Meistens ist das NuGet-Paket ., OcrNer, -, Teil 2), (Deutsch (German))

Meistens ist das NuGet-Paket ., OcrNer, -, Teil 2),

Thursday, 12 February 2026

//

25 minute read

NuGet NuGet Downloads GitHub-Freisetzung

Im Teil Ich zeigte die rohe Pipeline, die von Hand heruntergeladene Modelle, das Schreiben eines Tokenizers, das Verkabeln von ONNX-Inferenzen und die Dekodierung von BIO-Tags per Hand, aber eine Menge Sanitär nach rechts.

Jetzt ist es ein NuGet-Paket. Eine Reihe von Setup-Downloads mit Nullmodellen Alles, was automatisch heruntergeladen wird, beim ersten Einsatz

Anmerkung: Dieses Paket ist ein vereinfachtes, konzentriertes Tool zum Extrahieren von Text und Entitäten aus Bildern. irgendetwas (Fotos,Dokumente, Screenshots ,Handschrift,Animierte Gifs und sogar Videos) mit fuzzy Matching,.OCR Konsens,. und strukturierte Extraktion klarRAG wo die Produktionsversion dieser Pipeline lebt


Schnelles Glossar, wenn Sie sich neu in diesem Format befinden

Bevor wir hier tauchen, was die Schlüsselbegriffe bedeuten

  • OCR Optical Character Recognition (Optical Charaktere Erkennung)).-. Konvertieren Sie ein Bild von Text in tatsächliche Textzeichen, mit dem Ihr Code arbeiten kann.
  • NER Benannte Entity-Erkennung: ) Benannter Entity Recognition: - Bezeichneter Scantext, um Namen von Dingen zu finden und zu klassifizieren.. Benanntes Unternehmen: John Smith arbeitet bei Microsoft in Seattle.
  • ONNX Laufzeit Wie das BERT-Modell, das wir auf Ihrer Maschine verwenden, ohne Python, ,, Tensor, Flow, , oder GPU, läuft es als tragbares Modell. .onnx Datei, die nur Ihre CPU verwendet
  • BEERT Die NER-Variante wurde fein abgestimmt auf die CoNLL--2003- Datensatz, um Menschen zu erkennen,-Organisationen,-Standorte,-und verschiedene Entities
  • Florenz ,-2 Ein kleines Vision-Modell von Microsoft, das beschreiben kann, was es sieht in einem Bild, das sich von Tesseract unterscheidet, indem es die ganze Szene versteht, nicht nur Zeichen

Warum mehr als Plain Tesseract?

Tesseract ist stark für saubere Dokument-Texte, aber es fällt nach unten auf laute Fotos, ,. low.-...Kontrast-Scans, ,. und gemischte ".scene, +. text. ". images,.. Es stoppt auch bei Rohtexten, dass Sie noch extra Code benötigen, um diesen Text in strukturierte Entitäten zu verwandeln, die Sie tatsächlich verwenden können.

Dieses Paket schließt diese Lücken

  1. ImageSharp Vorverarbeitung Graustufen-Verstärkung des Kontrasts für OCR
  2. OpenCV fortgeschrittene Vorverarbeitung , und Binarisierung für beschädigte / skewed Dokumente
  3. Florenz ,-2 Bildverarbeitungs- und OCR-Bildunterschriften über die ONNX-Datei ®('no cloud API ® )«
  4. BERT NER auf OCR-Text Umwandeln Sie extrahierten Text in typisierte Entities.
  5. Microsoft-Erkenner.Text --Regel--basierte Extraktion von Daten,-Nummern,-URLs,-Telefone,-E-Mails,- und IPs
  6. Richtige DI-Integration - AddOcrNer() und du bist fertig
  7. CLI-Werkzeug -" A Spectre-.-Konsole Befehl: - line App, die nur aus dem Kasten heraus funktioniert

Was änderte sich von einem Teil?

flowchart LR
    subgraph Part1["Part 1: Manual"]
        M1[Download models]
        M2[Write tokenizer]
        M3[Wire ONNX]
        M4[BIO decode]
    end

    subgraph Part2["Part 2: NuGet Package"]
        N1["AddOcrNer()"]
        N2[Auto-download]
        N3[ImageSharp + OpenCV]
        N4[Florence-2]
        N5[Recognizers]
        N6[CLI Tool]
    end

    Part1 -->|"packaged into"| Part2

    style N1 stroke:#090,stroke-width:3px
    style N2 stroke:#090,stroke-width:3px
    style N3 stroke:#f60,stroke-width:3px
    style N4 stroke:#f60,stroke-width:3px
    style N5 stroke:#f60,stroke-width:3px
    style N6 stroke:#f60,stroke-width:3px

Teil, der das Verständnis des jeweiligen Stückes vermittelt. Teil, den es praktisch nutzt, ohne an die Internalen zu denken.


Erste Schritte

Installieren

dotnet add package Mostlylucid.OcrNer

Registerdienste

Das AddOcrNer() Erweiterung Methode registriert alles , : , OCR , , NER , die kombinierte Pipeline , , , Florence , und das Modell downloader , , , das Bild preprocessor , alle als Singletons ,, , alles faul ,- , initialisiert ,

Hier ist der tatsächliche Registrierungscode von ServiceCollectionExtensions.cs:

// Option 1: From appsettings.json (reads the "OcrNer" section)
builder.Services.AddOcrNer(builder.Configuration);

// Option 2: Inline configuration
builder.Services.AddOcrNer(config =>
{
    config.EnableOcr = true;
    config.TesseractLanguage = "eng";
    config.MinConfidence = 0.5f;
});

Dass es ' ist Kein Modell Downloads keine Datei Pfade keine ONNX Verkabelung unter der Haube AddOcrNer() registriert diese Dienstleistungen

// From ServiceCollectionExtensions.cs - what gets registered
services.AddSingleton<ModelDownloader>();           // Auto-downloads models on first use
services.AddSingleton<ImagePreprocessor>();         // ImageSharp-based image enhancement
services.AddSingleton<OpenCvPreprocessor>();        // OpenCV advanced preprocessing
services.AddSingleton<INerService, NerService>();   // BERT NER from text
services.AddSingleton<IOcrService, OcrService>();   // Tesseract OCR from images
services.AddSingleton<IOcrNerPipeline, OcrNerPipeline>();         // Combined OCR + NER
services.AddSingleton<ITextRecognizerService, TextRecognizerService>(); // Microsoft.Recognizers
services.AddSingleton<IVisionService, VisionService>();           // Florence-2 vision

Konfigurationseinstellungen (MSK)

{
  "OcrNer": {
    "EnableOcr": true,
    "TesseractLanguage": "eng",
    "MinConfidence": 0.5,
    "MaxSequenceLength": 512,
    "ModelDirectory": "models/ocrner",
    "Preprocessing": "Default",
    "EnableAdvancedPreprocessing": false,
    "EnableRecognizers": false,
    "RecognizerCulture": "en-us"
  }
}

Hier ist die tatsächliche OcrNerConfig Klasse diese Karte zu

// From OcrNerConfig.cs
public class OcrNerConfig
{
    public string ModelDirectory { get; set; } =
        Path.Combine(AppContext.BaseDirectory, "models", "ocrner");
    public bool EnableOcr { get; set; } = true;
    public string TesseractLanguage { get; set; } = "eng";
    public int MaxSequenceLength { get; set; } = 512;
    public float MinConfidence { get; set; } = 0.5f;
    public string NerModelRepo { get; set; } = "protectai/bert-base-NER-onnx";
    public PreprocessingLevel Preprocessing { get; set; } = PreprocessingLevel.Default;
    public bool EnableAdvancedPreprocessing { get; set; } = false;  // OpenCV pipeline
    public bool EnableRecognizers { get; set; } = false;            // Microsoft.Recognizers
    public string RecognizerCulture { get; set; } = "en-us";       // Recognizer language
}

Alle Einstellungen haben sinnvolle Voreinstellungen...... Sie können den gesamten Abschnitt weglassen und alles funktioniert..........EnableAdvancedPreprocessing und EnableRecognizersVoreinstellung zu false so bleibt das Paket leicht für Benutzer, die sie nicht brauchen

Das Preprocessing Option steuert Bildvergrößerung vor OCRP0MSK

Was es tut, was es macht, wenn es benutzt wird |-------|-------------|-------------| | None Nicht vorverarbeitende Bilder sind bereits optimiert | Minimal Nur Graustufen-Scans mit sauberen Scans | Default Die meisten Bilder sind zu empfehlen. | Aggressive Strenger Kontrast: Strenge Kontrast: Schärfung: Hochglanz: Fotos schlechter Qualität:


Die vier Dienste

Das Paket registriert fünf Dienste, die jeweils unabhängig nutzbar sind, wählen Sie den aus, der zu Ihrem Anwendungsfall passt.'s keine Notwendigkeit Florence zu laden, wenn alles was Sie brauchen ist NER from text.

flowchart TD
    subgraph Services
        NER["INerService<br>Text → Entities"]
        OCR["IOcrService<br>Image → Text"]
        REC["ITextRecognizerService<br>Text → Signals"]
        PIPE["IOcrNerPipeline<br>Image → Entities + Signals"]
        VIS["IVisionService<br>Image → Caption"]
    end

    OCR --> PIPE
    NER --> PIPE
    REC -.-> PIPE

    style PIPE stroke:#090,stroke-width:3px
    style VIS stroke:#f60,stroke-width:3px
    style REC stroke:#f60,stroke-width:2px,stroke-dasharray: 5 5

Wählen Sie den richtigen Service für Ihren Anwendungsfall

Das wichtigste Prinzip ist: EffizienzWählen Sie das leichteste Werkzeug, das die Arbeit tut .. . . . . Don . ' . t laden ein .450 .MB Vision-Modell, wenn ein OCR-Engine .

-Service - Was es tut -Modellgröße -Geschwindigkeit -Verwenden, wenn ...- -Verwendung
INerService BERT NER aus dem Text Aus dem Text ~430Aus dem Artikel Aus dem Bericht ~50Aus dem Beitrag Du hast bereits Text MSC6Aus den Datenbanken ,Aus dem Eintrag )Aus dem Abschnitt Aus dem Anhang MSK2Aus
IOcrService -Tesseract OCR aus Bildern -Teessract-OCR aus dem Bild ~4-MB Ms K3-Teract-Dossiers Sie benötigen Text aus Dokumentenscans ,-Screenshots
IOcrNerPipeline Sie haben Bilder und wollen Entitäten in einem Schritt.
ITextRecognizerService -Regel--basierte Extraktionsdaten (-Termine ,-Telefone, usw. .)-Regel -Keine -Daten ~1-Daten Sie wollen strukturierte Daten neben NER-Entitäten
IVisionService Sie müssen Bild verstehen, nicht nur Text lesen, sondern auch Text lesen.

NER aus Text Keine Bilder erforderlich

Wenn Sie bereits Text haben, können Sie NER direkt verwenden. Das ist der schnellste Weg......... keine OCR.,. keine Bildverarbeitung.... nur Text in...

Das INerService Schnittstelle ist einfach eine Methode.

// From INerService.cs
public interface INerService
{
    Task<NerResult> ExtractEntitiesAsync(string text, CancellationToken ct = default);
}

Hier-'s, wie man es in Ihrem eigenen Service verwendet

public class MyService
{
    private readonly INerService _nerService;

    public MyService(INerService nerService)
    {
        _nerService = nerService;
    }

    public async Task ProcessDocumentAsync(string text)
    {
        var result = await _nerService.ExtractEntitiesAsync(text);

        foreach (var entity in result.Entities)
        {
            // entity.Label: "PER", "ORG", "LOC", or "MISC"
            // entity.Text: "John Smith"
            // entity.Confidence: 0.9996
            // entity.StartOffset / EndOffset: character positions in the source
        }
    }
}

Die Ergebnismodelle sind einfach

// From NerResult.cs / NerEntity.cs
public class NerResult
{
    public string SourceText { get; init; } = string.Empty;
    public List<NerEntity> Entities { get; init; } = [];
}

public class NerEntity
{
    public string Text { get; init; } = string.Empty;     // "John Smith"
    public string Label { get; init; } = string.Empty;    // "PER", "ORG", "LOC", "MISC"
    public float Confidence { get; init; }                 // 0.0 to 1.0
    public int StartOffset { get; init; }                  // Where in the source text
    public int EndOffset { get; init; }                    // End position (exclusive)
}

Der erste Aufruf lädt das BERT NER-Modell herunter. - (~430.MB. - ). von HuggingFace. -.. Nachfolgende Anrufe verwenden das zwischengespeicherte Modell.


NER-Pipeline von OCR

Für Bilder die Pipeline behandelt Preprocessing-,. OCR., und NER in einem Anruf die IOcrNerPipeline kombiniert IOcrService und INerService:

// From OcrNerPipeline.cs - the actual pipeline code
public async Task<OcrNerResult> ProcessImageAsync(string imagePath, CancellationToken ct = default)
{
    // Step 1: OCR (includes preprocessing automatically)
    var ocrResult = await _ocrService.ExtractTextAsync(imagePath, ct);

    if (string.IsNullOrWhiteSpace(ocrResult.Text))
        return new OcrNerResult
        {
            OcrResult = ocrResult,
            NerResult = new NerResult { SourceText = string.Empty }
        };

    // Step 2: NER on extracted text
    var nerResult = await _nerService.ExtractEntitiesAsync(ocrResult.Text, ct);

    return new OcrNerResult
    {
        OcrResult = ocrResult,
        NerResult = nerResult
    };
}

Verwendung von :

var pipeline = serviceProvider.GetRequiredService<IOcrNerPipeline>();

var result = await pipeline.ProcessImageAsync("invoice.png");

// What OCR found
var text = result.OcrResult.Text;           // The full extracted text
var confidence = result.OcrResult.Confidence; // 0.0 to 1.0

// What NER found in that text
foreach (var entity in result.NerResult.Entities)
{
    // [PER] John Smith, [ORG] Microsoft, [LOC] Seattle...
}

Was unter der Haube geschieht

flowchart LR
    IMG[Image bytes]
    PRE["ImageSharp<br>or OpenCV"]
    TESS["Tesseract<br>OCR"]
    TOK["WordPiece<br>Tokenize"]
    BERT["BERT NER<br>ONNX"]
    REC["Recognizers<br>(optional)"]
    OUT[Result]

    IMG --> PRE
    PRE --> TESS
    TESS --> TOK
    TOK --> BERT
    BERT --> REC
    REC --> OUT

    style PRE stroke:#f60,stroke-width:3px
    style BERT stroke:#f60,stroke-width:3px
    style REC stroke:#f60,stroke-width:2px,stroke-dasharray: 5 5

Bildvorbehandlung

In der Praxis arbeiten sowohl Tesseract als auch Florence-2 mit vorverarbeiteten Bildern besser. Voreingestellt aber komplett optional können Sie es mit deaktivieren Preprocessing = "None" in der Konfiguration oder --preprocess none auf dem CLI-.

Das ImagePreprocessor Verwendungen ImageSharp Keine natürlichen Abhängigkeiten

// From ImagePreprocessor.cs - the actual preprocessing steps
public byte[] Preprocess(byte[] imageBytes, PreprocessingOptions? options = null)
{
    options ??= PreprocessingOptions.Default;
    using var image = Image.Load<Rgba32>(imageBytes);

    image.Mutate(ctx =>
    {
        // Step 1: Upscale small images (Tesseract wants 300+ DPI equivalent)
        if (options.EnableUpscale && (image.Width < options.MinWidth || image.Height < options.MinHeight))
        {
            var scale = Math.Max(
                (float)options.MinWidth / image.Width,
                (float)options.MinHeight / image.Height);
            scale = Math.Min(scale, options.MaxUpscaleFactor);
            ctx.Resize((int)(image.Width * scale), (int)(image.Height * scale),
                KnownResamplers.Lanczos3);
        }

        // Step 2: Grayscale (single channel = faster, more accurate)
        if (options.EnableGrayscale)
            ctx.Grayscale();

        // Step 3: Contrast boost (text stands out from background)
        if (options.EnableContrast && options.ContrastAmount != 1.0f)
            ctx.Contrast(options.ContrastAmount);

        // Step 4: Sharpen (crisp character edges)
        if (options.EnableSharpen)
            ctx.GaussianSharpen(options.SharpenSigma);
    });

    using var ms = new MemoryStream();
    image.SaveAsPng(ms);  // PNG = lossless, no additional artifacts
    return ms.ToArray();
}

Drei Presets sind in ·.- PreprocessingOptions Klasse definiert sie.

// From ImagePreprocessor.cs
public static PreprocessingOptions Default => new();  // Grayscale + 1.5x contrast + sharpen

public static PreprocessingOptions Minimal => new()   // Grayscale only
{
    EnableContrast = false,
    EnableSharpen = false,
    EnableUpscale = false
};

public static PreprocessingOptions Aggressive => new() // For poor quality images
{
    ContrastAmount = 1.8f,
    SharpenSigma = 1.5f,
    MinWidth = 1024,
    MinHeight = 768,
    MaxUpscaleFactor = 4.0f
};
Voreinstellung von , wann Sie verwenden, was es tut
Default Die meisten Bilder Graustufen-Kontrast +-Schärfung
Minimal Saubere Scans nur für Graustufen
Aggressive SCHLÜSSELMASSK0 Schlecht-Qualität Fotos SchLÜsselMSSK1 , Kontrast 1.8 , starke Schärfe + , größere upscale

Erweiterte Vorverarbeitung mit OpenCV

Für schwer degradierte Dokumente, die gespenstische Scans, lärmende Fotos, verblasste historische Seiten, die ImageSharp Pipeline ist genug, um ' zu aktivieren EnableAdvancedPreprocessing um auf eine vollständige OpenCV-Pipeline zu wechseln, die von ImageSummarizer.

Der OpenCV Preprocessor verkettet vier Stufen, die jeweils von einer automatischen Qualitätsbewertung angetrieben werden.

flowchart LR
    IMG[Image]
    QA["Quality<br>Assess"]
    SK["Deskew"]
    DN["Denoise"]
    BIN["Binarize"]
    OUT[Clean image]

    IMG --> QA
    QA --> SK
    SK --> DN
    DN --> BIN
    BIN --> OUT

    style QA stroke:#f60,stroke-width:2px

Qualitätsbewertung (ImageQualityAssessor)-Messt Unschärfen ,-Skew-Winkel,-Rauschpegel,-Kontrast,-Brightness Gleichförmigkeit ,- und Textdichte.-Basierend auf den Ergebnissen,-Es empfiehlt, welche Stufen zu verwenden --So saubere Bilder unnötige Verarbeitung überspringen

Schreibtisch (SkewCorrectorBereinigt gedrehte Dokumente mit drei Methoden Befestigen der Hough-Line-Erkennung Beeindrucken der (DefaultBereinigen des Mindestbereichs-Rechtecks, oder Projektionsprofilanalyse.

Lärmbelästigung (NoiseReducer)- bietet Gaußische Unschärfe an (-schnell),-bilaterale Filter (-Edge--konservierend ),-non---lokale Mittel (-höchste Qualität und morphologische Operationen

Binarisieren (InkExtractorUmwandelt zur Reinigung von Schwarz, - und -, Weiß mit Otsu, MSC3, adaptiver Schwellung, MSSK4, Sauvola, für degradierte historische Dokumente, ),, CLAHE, +, Otso, MKS8, für niedrige Kontraste, MSV9 oder morphologische Hintergrundentfernung

Aktivieren Sie es in config oder auf dem CLI-Stick

config.EnableAdvancedPreprocessing = true;
ocrner ocr damaged-scan.png -a

Microsoft®.-Erkenner® :-Regeln---basierte Entity Extraction

BERT NER findet Menschen,-Organisationen,-Standorte,-und verschiedene Entitäten.-Aber einige strukturierte Daten --Dates,-Telefonnummern,-E-Mails,-URLs,-IP-Adressen - ist besser durch deterministische Regeln gefangen als durch ein neuronales Netzwerk.-

Aktivieren EnableRecognizers einen zweiten Extraktionspass mit Microsoft-Erkenner.TextDies läuft nach NER und Auszüge

Beispiele für die Verwendung von „MSK" |------|----------| DatumZeit ,| , " Januar , 15, , 2024", , am nächsten Dienstag , und ", , letzte Woche ," , 3 Millionen ",, 3 Millionen |, 4 Millionen Weitere Informationen finden Sie unter: http://www...github.sk8.com/". Telefon: |, Telefon: "555-1234",, Fax:"+1, E-Mail-Adresse: "johne, @microsoft, .ycom, MSC6 IP-Adresse

Der Erkenner unterstützt mehrere Kulturen (-de---e-,-en-M--gb,- de---de.,-fr-,-etcs-.), so dass es mit lokalen Formaten und Zahlenkonventionen umgeht

config.EnableRecognizers = true;
config.RecognizerCulture = "en-us";
ocrner ner "John Smith joined Microsoft on January 15, 2024. Call 555-1234." -r

Die beiden Extraktionsmethoden ergänzen einander.: NER versteht den Kontext.MSC1 ®Apple-" ? die Firma vs.. ? ? " ? apple-" ? das Obst?), ? während die Erkenner zuverlässig strukturierte Muster fangen, die BERT vermissen könnte. OcrNerResult modell enthält jetzt eine optionale Signals Eigentum

public class OcrNerResult
{
    public OcrResult OcrResult { get; init; } = new();
    public NerResult NerResult { get; init; } = new();
    public RecognizedSignals? Signals { get; init; }  // Only when EnableRecognizers = true
}

Die Vision von Florenz

Florenz – -2 ist ein völlig anderer Ansatz von Tesseract – . – Wo Tesserakt eine spezialisierte OCR-Engine ist, die Textzeichen nach Zeichen liest., – MSC3 ist ein Sehmodell die das ganze Bild versteht

// From IVisionService.cs
public interface IVisionService
{
    Task<VisionCaptionResult> CaptionAsync(string imagePath, bool detailed = true,
        CancellationToken ct = default);
    Task<VisionOcrResult> ExtractTextAsync(string imagePath,
        CancellationToken ct = default);
    Task<bool> IsAvailableAsync(CancellationToken ct = default);
}

Verwendung von :

var vision = serviceProvider.GetRequiredService<IVisionService>();

// Generate a caption describing the image
var caption = await vision.CaptionAsync("photo.jpg", detailed: true);
if (caption.Success)
{
    // caption.Caption: "A man in a blue suit standing at a podium"
    // caption.DurationMs: how long it took
}

// Extract visible text using Florence-2's built-in OCR
var ocrResult = await vision.ExtractTextAsync("screenshot.png");
if (ocrResult.Success)
{
    // ocrResult.Text: the visible text Florence-2 detected
}

Wann welche verwendet werden soll

Verwendungsfall , Tesseract (IOcrService,) , , , Florenz , -2 , ( ,IVisionService)
Dokumentenscans Beste Wahl schnelles, präzises, sicheres, aber overkill
Fotos von Schildern Anständige, bessere und besser verstandene Szene-Kontext
Screenshots Guter, guter, guter
Bildunterschrift Dies ist die beste Wahl.
Geschwindigkeit Schnelles, schnelleres und langsameres )
Größe des Modells -MB- -Mb-~450-MB

Der Punkt ist: EffizienzVerwenden Sie Tesseract für Dokumente und Textextraktion.(.it'.s schneller mit einem kleineren Modell, 100.x. Verwenden Sie Florence...-2., wenn Sie wirklich Bild benötigen Verständnis.

Florence--2-Auto - --Downloads seiner Modelle bei der ersten Verwendung zu {ModelDirectory}/florence2/.


Wie die NER-Pipeline intern funktioniert

Die NER-Pipeline folgt demselben dreistufigen Prozess, der im Detail in Teil: **decodieren Sie das Zeichen →**Teil 1, der jedes Konzept durchläuft. WordPiece Tokenization.,, ONNX Tensor-Inferenz.MS K4, BIO Tag Decodierung.,, Softmax-Konfidenz von Grund auf mit einem kompletten bebaubaren Beispiel

Hier ist das, was das Paket jenseits des manuellen Ansatzes hinzufügt.

Offset-Tracking

Teil des Tokenizers wandelt Text in Token-IDs um BertNerTokenizer auch Gleise Zeichenoffsets So wissen Sie genau, wo im Quelltext jede Entität gefunden wurde.

// From BertNerTokenizer.cs
// "John Smith works at Microsoft" becomes:
// [CLS] John Smith works at Micro ##soft [SEP] [PAD] ...
//
// Each token tracks its source position:
// "John"     → chars 0-4
// "Smith"    → chars 5-10
// "Micro"    → chars 20-29  (WordPiece splits "Microsoft")
// "##soft"   → chars 20-29  (same source range)

Dies ist, wie NerEntity.StartOffset und EndOffset Arbeiten Sie - , sie Karte zurück zu exakten Charakterpositionen in Ihrem ursprünglichen Text

Vertrauen – --Filtered Entity Extraction

Das Paketfilter während der Decoder-Dekodierung......... ..-... das Vertrauensrauschen erreicht nie Ihren Code.

// From NerService.cs
private void FlushEntity(
    List<NerEntity> entities, string text,
    string type, int start, int end, float confidence)
{
    if (confidence < _config.MinConfidence) return;  // Filter low-confidence

    var entityText = text[start..end].Trim();
    if (string.IsNullOrWhiteSpace(entityText)) return;

    entities.Add(new NerEntity
    {
        Text = entityText,
        Label = type,
        Confidence = confidence,
        StartOffset = start,
        EndOffset = end
    });
}

Auto.-.Download, wie es funktioniert

Alle Modelle downloaden automatisch bei der ersten Verwendung... keine manuelle Einrichtung erforderlich...

flowchart TD
    CALL["First API call"]
    CHECK{"Files exist<br>in cache?"}
    YES[Use cached model]
    NO["Download to .tmp file"]
    MOVE["Atomic rename<br>.tmp → final"]

    CALL --> CHECK
    CHECK -->|Yes| YES
    CHECK -->|No| NO
    NO --> MOVE
    MOVE --> YES

    style NO stroke:#f60,stroke-width:3px
    style MOVE stroke:#090,stroke-width:3px

Das ModelDownloader Downloads aus dem HuggingFace Modell ) und GitHub Daten ( tessdata .tmp pattern Wenn ein Download unterbrochen wird, werden keine beschädigten Dateien zurückgelassen

// From ModelDownloader.cs - atomic download pattern
await using var fileStream = new FileStream(tempPath, FileMode.Create,
    FileAccess.Write, FileShare.None, 81920, true);
// ... stream download to .tmp file ...
await fileStream.FlushAsync(ct);
fileStream.Close();

File.Move(tempPath, localPath, overwrite: true);  // Atomic rename

Voreingestellter Cache-Standort {AppBaseDir}/models/ocrner/

models/ocrner/
  ner/
    model.onnx      (~430MB - BERT NER)
    vocab.txt       (~230KB - WordPiece vocabulary)
    config.json     (~1KB - label mapping)
  tessdata/
    eng.traineddata (~4MB - English OCR data)
  florence2/
    ...             (~450MB - Vision model files)

Architektur

Alles ist ein Singleton mit fauler Initialisierung... teure Ressourcen... InferenceSession, TesseractEngineDas Modell ) wird einmal nach dem ersten Gebrauch erstellt und für die Lebensdauer der Anwendung wiederverwendet.

flowchart TD
    DI["AddOcrNer()"]

    DI --> MD["ModelDownloader<br>(singleton)"]
    DI --> PP["ImagePreprocessor<br>(singleton)"]
    DI --> CV["OpenCvPreprocessor<br>(singleton)"]
    DI --> NER["NerService<br>(singleton)"]
    DI --> OCR["OcrService<br>(singleton)"]
    DI --> PIPE["OcrNerPipeline<br>(singleton)"]
    DI --> REC["TextRecognizerService<br>(singleton)"]
    DI --> VIS["VisionService<br>(singleton)"]

    MD --> NER
    MD --> OCR
    PP --> OCR
    CV --> OCR
    NER --> PIPE
    OCR --> PIPE
    REC --> PIPE

    style DI stroke:#090,stroke-width:3px

Thread safety - Sicherheit für alle Dienste SemaphoreSlim für die Initialisierung: Mehrere Threads, die den Dienst gleichzeitig beim ersten Einsatz aufrufen, lösen nur einen Download aus

// From NerService.cs - lazy init pattern used by all services
private async Task EnsureInitializedAsync(CancellationToken ct)
{
    if (_initialized) return;           // Fast path: already loaded

    await _initLock.WaitAsync(ct);      // Only one thread enters
    try
    {
        if (_initialized) return;       // Double-check after lock

        var paths = await _downloader.EnsureNerModelAsync(ct);
        _tokenizer = new BertNerTokenizer(paths.VocabPath, _config.MaxSequenceLength);
        _session = new InferenceSession(paths.ModelPath, sessionOptions);
        _initialized = true;
    }
    finally { _initLock.Release(); }
}

CLI-Werkzeug

Das repo enthält ein Kommando-Tool mit Spectre-.-KonsoleEs ist als ein Erfolgserlebnis konzipiert, und es funktioniert, wenn Sie Ihre Eingabe übergeben.

Schnellstart

# NER from text (auto-detected)
ocrner "John Smith works at Microsoft in Seattle"

# OCR from an image (auto-detected)
ocrner invoice.png

# Explicit commands
ocrner ner "Marie Curie won the Nobel Prize in Stockholm"
ocrner ocr scan.png
ocrner caption photo.jpg

Intelligentes RoutingDas CLI Auto ,- , erkennt Ihre Absicht , . Aus Program.cs:

// From Program.cs - smart routing logic
if (IsImageFile(args2[0]) || IsGlobPattern(args2[0]) || Directory.Exists(args2[0]))
{
    args2 = ["ocr", .. args2];   // Image file → ocr command
}
else
{
    args2 = ["ner", .. args2];   // Text string → ner command
}

Wenn Sie einen Text-String übergeben, läuft es NER.., wenn Sie eine Bilddatei übergeben, ,, glob?,, oder Verzeichnis; ,, es führt OCR aus.

Drei Befehle

Befehl , was es tut , Motor Geschwindigkeit ,
ner <text> Entitäten aus Text extrahieren
ocr <path> -OCR-NER aus Bildern MS K2-Tesseract-BERT- -~100-300- -
caption <path> Bildunterschrift für optionale OCR-Aufnahmen von +, Florence-2, (,ONNX, MSC5, MCSK6, ~1-3 und

Tesseract ist die Standard-OCR-Engine weil es 's schneller und optimiert für Dokumenttext ist , wenn Sie Bild Verständnis benötigen ,( Captions , , , Szene Text , , , Fotos von Schildern ,

Reale Produktion

Hier ist die tatsächliche Ausgabe vom Ausführen des CLI gegen reale Beispieldokumente.

NER aus dem Text

ocrner ner "Marie Curie won the Nobel Prize in Stockholm"
╭──────┬─────────────┬────────────┬──────────╮
│ Type │ Entity      │ Confidence │ Position │
├──────┼─────────────┼────────────┼──────────┤
│ PER  │ Marie Curie │ 100%       │ 0-11     │
│ MISC │ Nobel Prize │ 100%       │ 20-31    │
│ LOC  │ Stockholm   │ 100%       │ 35-44    │
╰──────┴─────────────┴────────────┴──────────╯

NER mit Erkennern Kombination von BERT-Entitäten und regelbasierter Signalextraktion auf der Basis von :

ocrner ner "Shelby Lucier from SCS Agency in Cambridge, UK sent an invoice on 13/02/15. Call 07981423683." -r
╭──────┬───────────────┬────────────┬──────────╮
│ Type │ Entity        │ Confidence │ Position │
├──────┼───────────────┼────────────┼──────────┤
│ PER  │ Shelby Lucier │ 100%       │ 0-13     │
│ ORG  │ SCS Agency    │ 100%       │ 19-29    │
│ LOC  │ Cambridge     │ 100%       │ 33-42    │
│ LOC  │ UK            │ 100%       │ 44-46    │
╰──────┴───────────────┴────────────┴──────────╯

── Recognized Signals ─────────────────────────
  Type       Text          Details
  DateTime   13/02/15      datetimeV2.date
  Phone      07981423683

BERT findet die Leute, die Organisationen und Standorte von ,. Die Erkennungspersonen fangen das Datum und die Telefonnummer von -. Strukturierte Muster, dass ein neuronales Netzwerk unzuverlässig wäre beim Extrahieren von..

OCR aus einem gescannten Dokument Ein Amazon-Aktionärsbrief, der mit Loch gescannt wurde

ocrner ocr shareholder-letter.jpg -q
╭──────┬───────────────┬────────────┬──────────╮
│ Type │ Entity        │ Confidence │ Position │
├──────┼───────────────┼────────────┼──────────┤
│ ORG  │ Amazon        │ 87%        │ 285-291  │
│ PER  │ Jeff          │ 99%        │ 293-297  │
│ ORG  │ AWS           │ 95%        │ 984-987  │
│ LOC  │ America       │ 98%        │ 2315-2322│
╰──────┴───────────────┴────────────┴──────────╯
OCR Confidence: 89%

Tesseract-Extrakte in der Nähe von -,verbatim Text aus dem gescannten Buchstaben bei 89%, confidence., und NER richtig identifiziert Amazon, , Jeff Bezos, MKS5, AWS, MSC6 und Nordamerika

Tesseract vs Florence--2:-Ein echter Vergleich

Dieselbe gescannte Aktionärsbuchstabe, die von beiden Triebwerken bearbeitet wird

-Tesseract-Tesseraktocrner ocr,) , , , Florenz , -2 , ( ,ocrner caption --ocr)
Geschwindigkeit -~200- -M-~14-M
OCR-genauigkeit , in der Nähe von -, halluzinierte Phrasen
Schlüsseltext Im Laufe der letzten Jahre bei Amazon hatte ,, I', die Möglichkeit, viele Erzählungen zu schreiben.,, E-Mail-Adresse: ...", ,
NER-Einrichtungen -Jeff Jeff (-PER-),-Amazon (-ORG),-AWS Ms K5-ORG),-Amerika Ms k7-LOC-)MSC9-N./-A zu verfärbt für zuverlässige NER-MS-K12-MSSK13
Bildunterschrift Ein Papier mit einigen Texten

Florence--2- ist ein Sehvermögen Modell - , es versteht Szenen , , Objekte , und räumliche Beziehungen . , Es wurde nie entwickelt, um mit Tesseract beim Lesen von Dokument Text konkurrieren , verwenden Sie es, wenn Sie Bild benötigen Verständnis Nicht Text in diesem Foto Extraktion Was sagt dieses Dokument?

JSON-Ausgang für Automatisierung LLM Tools

Das --json Flag-Ausgänge strukturiert JSON, um stdout mit allen Protokollierung unterdrückt . . - . entwickelt für Rohrleitungen in andere Tools ., . LLM-Funktion Aufrufen ?, . oder Automatisierungsskripte .

ocrner ner "Shelby Lucier from SCS Agency in Cambridge, UK sent an invoice on 13/02/15. Call 07981423683." -r --json
{
  "command": "ner",
  "success": true,
  "sourceText": "Shelby Lucier from SCS Agency in Cambridge, UK...",
  "entityCount": 4,
  "entities": [
    { "type": "PER", "text": "Shelby Lucier", "confidence": 0.9996, "startOffset": 0, "endOffset": 13 },
    { "type": "ORG", "text": "SCS Agency", "confidence": 0.999, "startOffset": 19, "endOffset": 29 },
    { "type": "LOC", "text": "Cambridge", "confidence": 0.9975, "startOffset": 33, "endOffset": 42 },
    { "type": "LOC", "text": "UK", "confidence": 0.9991, "startOffset": 44, "endOffset": 46 }
  ],
  "signals": {
    "dateTimes": [{ "text": "13/02/15", "typeName": "datetimeV2.date" }],
    "phoneNumbers": [{ "text": "07981423683" }]
  }
}

Dies macht den CLI nutzbar als Werkzeug für LLMs und Agenten ocrner ner "..." --jsonDie JSON-Response und die Vernunft über die strukturierten Entities werden geparst. jqEinspeisung an ein Agenten-Framework oder Auslesen aus einer beliebigen Sprache

# Pipe to jq for quick filtering
ocrner ocr invoice.png --json | jq '.results[0].entities[] | select(.type == "PER")'

# Use from Python, Node, or any language that can shell out
echo "John Smith at Microsoft" | ocrner ner --json

Um stattdessen in eine Datei zu speichern -o mit einem .json extension Auf Diskette geschrieben auf Disketten geschrieben

ocrner ocr "scans/*.png" -o results.json

Stapelverarbeitung

Mehrere Bilder mit Glob-Mustern oder Verzeichnissen verarbeiten

# All PNGs in a directory
ocrner ocr "scans/*.png" -o results.json

# All images in a folder
ocrner ocr ./documents/

# Batch captioning with Florence-2
ocrner caption "photos/*.jpg" --ocr -o captions.md

Alle CLI-Einstellungen

-Flagge Bezieht sich auf -Beschreibung
--json ner, ocr, caption Structured JSON zu stdout --quietAlle Protokollierungen werden unterdrückt.
-c ner, ocr Mindestanforderungen für das Vertrauen der Unternehmen
--language ocr ZUSAMMENFASSUNG eng, fra)
--max-tokens ner, ocr Maximale BERT-Sequenzlänge
--model-dir ner, ocr, caption Modell-Cache-Verzeichnis überschreiben
-p, --preprocess ocr, caption Vorbehandlung voreingestellt none, minimal, default, aggressive
-a, --advanced-preprocess ocr, caption Verwendung von OpenCV-Vorverarbeitungsmitteln für die Vorbehandlung von ([Deskew],[Denoise] ,[binarize]MS K4
-r, --recognizers ner, ocr -Aktivieren von Regel---basierten Extraktions-MSC2-Daten,-Nummern,-URLs,-Telefone,-E-Mails,-IPsMSC8- -
--culture ner, ocr -Erkennerkultur ,-E-.-G-.-E en-us, de-de (-default-:- en-us)
--brief caption Erzeugen Sie eine kürzere, weniger detaillierte Bildunterschrift
-q, --quiet ner, ocr, caption Ruhemodus - reduzierte Konsolenausgabe
-o ner, ocr, caption Ausgabedatei-Pfad.txt, .md, .json)
--ocr caption Auch OCR während des Caption-Befehls ausführen.
--ner caption Extrahieren Sie NER aus OCR-Texten --ocr)

Leistung Quantisierte Modelle und Was Quantifizierte Modelle

Das aktuelle NER-Modell ist die Full-Prezision protectai/bert-base-NER-onnx Für viele Anwendungsfälle vor allem auf resource- oder bei der Verarbeitung von hohen Volumina quantifiziert Die Version des gleichen Modells wäre mit minimalem Genauigkeitsverlust deutlich schneller.

ONNX Runtime unterstützt die Int.8-Quantisierung aus dem Kasten heraus, was typischerweise die Modellgröße um ~4-x reduziert und die Ableitungsgeschwindigkeit durch 2-3-x auf CPU verbessert. NerModelRepo config option unterstützt bereits den Hinweis auf eine andere HuggingFace repo.,, also wenn ein quantisiertes Modell veröffentlicht wird, ändern Sie sich einfach

{
  "OcrNer": {
    "NerModelRepo": "protectai/bert-base-NER-onnx-quantized"
  }
}

Die Architektur ist für diesen Austausch des Modells , konzipiert.


Das größere Bild, wo das passt

Dieses Paket ist ein single---PhasenpipelineEine OCR-Engine – ein NER-Modell – ein optionales Visionsmodell – ein .-Modell – es wurde entwickelt, um einfach und effizient für den Common Case zu sein.

Für komplexere Szenarien lesen Sie Text aus irgendetwas Handgeschriebene Notizen - Fotos von Whiteboards - , low-- qualitative Kamera fängt mit multi-- engine OCR consens -, funky matching – , , und strukturierte Extraktion - - , überprüfen Sie die vollständige Pipeline bei klarRAGMehrphasenversion dieser Arbeit lebt, wo die Produktion...

Was sind die nächsten Multimodal LLMs?

Florence--2' ist die aktuelle Decke für lokale Vision in diesem Paket. Der nächste logische Schritt ist ein Multimodales LLM Ein Modell, das ein Bild sehen kann und Grund für es in der natürlichen Sprache, statt separates OCR, +, NER-Schritte, MSV2, Sie, MSC3, senden das Bild direkt und fragen nach strukturierter Extraktion. .,

Hier ist ungefähr das, was diese API aussehen könnte.

// Hypothetical future IMultimodalService
public interface IMultimodalService
{
    Task<StructuredExtractionResult> ExtractAsync(
        string imagePath,
        string prompt = "Extract all people, organizations, and locations from this image. Return as JSON.",
        CancellationToken ct = default);
}

// Usage
var multimodal = serviceProvider.GetRequiredService<IMultimodalService>();
var result = await multimodal.ExtractAsync("business-card.jpg");

// result.Entities: [{ "John Smith", PER }, { "Acme Corp", ORG }, { "New York", LOC }]
// result.RawText: "John Smith, VP Engineering, Acme Corp, New York, NY 10001"
// result.Summary: "Business card for John Smith at Acme Corp in New York"

Kleine lokale multimodale Modelle Phi--3.5--Vision oder LVADie richtige Wahl hängt von Ihrem Latenzbudget und den Genauigkeitsanforderungen ab.

flowchart LR
    subgraph Staged["Staged Approach: Pick Your Level"]
        T1["Tesseract OCR<br>4MB | ~100ms<br>Text extraction"]
        T2["BERT NER<br>430MB | ~50ms<br>Entity extraction"]
        T3["Florence-2<br>450MB | ~1-3s<br>Image understanding"]
        T4["Multimodal LLM<br>2-8GB | ~5-30s<br>Full reasoning"]
    end

    T1 --> T2
    T2 --> T3
    T3 -.->|"future"| T4

    style T1 stroke:#090,stroke-width:2px
    style T2 stroke:#090,stroke-width:2px
    style T3 stroke:#f60,stroke-width:2px
    style T4 stroke:#999,stroke-width:2px,stroke-dasharray: 5 5

Jede Ebene fügt die Fähigkeit zu den Kosten der Größe und Latenz hinzu.Das Paket umfasst derzeit Ebenen......1-3.. Tier....4. ist, wo multimodale LLMs in ..-. klarRAG die Überschrift „." ist


Aufkommen

Dieses Paket:

Teil:

Abhängigkeiten:

Verwandte Artikel:

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.