# Useimmin selvää.OcrNer M SK1 NuGet-paketti (Teollinen osa 2)

<!-- category -- AI,OCR,NER,ONNX,CSharp,Tutorial,NuGet -->
<datetime class="hidden">2026-02-12T12:00</datetime>

[![NuGet](https://img.shields.io/nuget/v/Mostlylucid.OcrNer)](https://www.nuget.org/packages/Mostlylucid.OcrNer/) [![NuGet-palautukset](https://img.shields.io/nuget/dt/Mostlylucid.OcrNer)](https://www.nuget.org/packages/Mostlylucid.OcrNer/) [![GitHubin julkilausuma (CLI)](https://img.shields.io/github/v/release/scottgal/mostlylucidweb?filter=ocrner-*&label=CLI)](https://github.com/scottgal/mostlylucidweb/releases?q=ocrner)

Siihen [Osa 1](/blog/simple-ocr-ner-extraction) Näytin raakaputken:mallit laaditaan käsin,tokenointi kirjoitetaanM SK2 ONNX-tuloksen sijoittamiseenMSC3 ja BIO-merkintöjä dekodioidaan käsillä.

Nyt se on NuGet-paketti, ' ja . **Yksi yhteys setup, nollamallin laatimiseen** - kaikki automaattisesti -palauttaa ensimmäisessä käytössäM SK2

> **Huomautus:** Tämä paketti on yksinkertaistettu, keskittynyt väline tekstien ja elinten extrahointiin kuvista. *mikä tahansa* ( valokuvat, , asiakirjat,, screenshots,, käännökset,M SK4 animaatioGIFit ja jopa videot, [***ilmeinen*RAG**](https://www.lucidrag.com) where the production-grade version of this pipeline lives

[TOC]

---


## Lyhyt Glossaari (Jos olette uusi tähänM SK1

Ennen kuin aiomme ottaa kantaa siihen, mitä tärkeimmät termet tarkoittavat

- **OCR** (Optical Character Recognition
- **NER** John Smith työskentelee Microsoftissa Seattlessa.
- **ONNX:n käyttöaika** - keino käyttää koneen oppimiseen tarkoitettuja malleja `.onnx` faili, paikallisesti, käyttäen vain CPU:tänne .
- **BERT** - Googlen koulutettu kielimalli, jossa ymmärretään tekstiin liittyvä konteksti [CoNLL-2003](https://www.clips.uantwerpen.be/conll2003/ner/) henkilöiden tunnistamiseen tarkoitettu tietokokonaisuus
- **Firenze** - Microsoftin pieni näkemismalli, joka voi kuvailla *näkemys* kuvauksessa (captionsM SK1 objects, textMSC3 Erityinen Tesseractista siinä mielessä, että se ymmärtää koko näytelmän , ei vain hahmoja

---


## Miksi enemmän kuin pelkkä Tesseract?

Tesseract on vahva puhdasta asiakirjatekstiä varten,, mutta se laskee melua aiheuttaviin valoihin, alhainenM SK2 kontrastiskannerit , ja sekoitettu MSC4 näyttämö | + teksti |" kuvat |

Tämä paketti poistaa nämä puutteet

1. **[KuvaSharp](https://sixlabors.com/products/imagesharp/) ennakkokäsittely** - sininen ulottuvuusM SK1 kontrastipainotus , OCR:lle mukautettu Sharpening
2. **[OpenCV](https://opencv.org/) edistynyt ennakkokäsittely** -, deskew, ,, denoise, M SK2 ja vahingoittuneiden asiakirjojen binaarisointi
3. **[Firenze](https://huggingface.co/microsoft/Florence-2-base)** näkyvyys - paikallisen kuvan captioning ja OCR ONNXin välityksellä
4. **BERT NER OCR-tekstin yläpuolella** - muuntaa käännetty teksti kirjattuihin yksiköihin PERM SK2ORG/LOCMST4MISCMst5 voi toimia
5. **[Microsoft.Recognizers.Text](https://github.com/microsoft/Recognizers-Text)** --sääntö--päivämäärää koskeva tietojen extrahointi,-numerot,-URL-osoitteet,-puhelinet,- sähköpostit,- ja IP-osoitteita(-opt---in)
6. **Asianmukainen DI-integraatio** - `AddOcrNer()` ja te olette päässeet
7. **CLI-väline** - [Spectre.Konsole](https://spectreconsole.net/) command-liini-app, joka toimii vain omalla tavallaan

---


## Mikä on muuttunut osasta 1

```mermaid
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
```

Osa 1 oli koulutusta, osa - ymmärtää, mitä kukin osa tekee, osa

---


## Aloitetaan

### Asetus

```bash
dotnet add package Mostlylucid.OcrNer
```

### Rekisterointipalvelut

Euroopan unionin `AddOcrNer()` laajentumismenetelmä rekisteröi kaiken: OCRM SK1 NER , yhdistetty putkilinja, FirenzeMSC4 näkemys,, mallin lataaja,, ja kuvapreprocessori,M SK7 kaikki yksitonin muodossa

Tässä on todellinen rekisteröintikoodi ' `ServiceCollectionExtensions.cs`:

```csharp
// 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;
});
```

Se' se. Mitään mallia ei voida ladata , ei tiedostoja, , ei ONNX-yhteyksiä,. Kapteen alla `AddOcrNer()` rekisteröi nämä palvelut:

```csharp
// 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
```

### Ohjelmointi (appsettings.jsonM SK2

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

Tässä on todellinen `OcrNerConfig` luokitellaan nämä kartat :

```csharp
// 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
}
```

Kaikilla ohjelmilla on järkeviä standardeja. Voit poistaa koko osan ja kaikki toimiiM SK1 Kaksi opt-järjestelmää -ominaisuuksissa (`EnableAdvancedPreprocessing` ja `EnableRecognizers`) sääntöjen mukainen `false` joten paketti pysyy kevyenä niille käyttäjille, jotka eivät tarvitse niitä.

Euroopan unionin `Preprocessing` -vaihtoehto hallinnoi kuvaan parantamista ennen OCR:tä:

| Arvo | Mitä se tekee SSK2 Milloin sitä käytetään |
|-------|-------------|-------------|
| `None` | Ennaltakäsittelyä ei käytetä | Kuvat ovat jo optimoituja |
| `Minimal` | Ainoastaan harmaassa mittakaavassa | Puhtaiset skansit |
| `Default` | Grayscale + kontrasti | + | Sharpen || | Useimmat kuvat
| `Aggressive` | Vahva kontrasti + hidastetaan SSK2 laajennetaan | huonolaatuiset valokuvat S|

---


## Neljä palvelua

Paketissa rekisteröidään viisi palvelua, kukin käyttökelpoinen itsenäisesti . valitse se, joka sopii omaan käyttötarkoitukseenne M SK2 siellä' ei tarvitse lastata FirenzeäMSC4 jos tarvitsette vain tekstistä NER-viestin

```mermaid
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
```

### Asianmukaisen palvelun valinta käyttötarkoituksessanne

Keskeinen periaate on **tehokkuus**: valitse pienintä työkalua, joka tekee tehtävän.

| Palvelu SSK1 Mitä se tekee | Mallin koko S| Nopeus M| Käytettäessä
|---------|-------------|------------|-------|-------------|
| `INerService` | BERT NER tekstistä SSK1 ~430MB S| \~50ms | Teillä on jo tekstiä |(PDF-asiakirjat |, |tietokannat |SSK8 | käyttäjän input | ) | SSK10
| `IOcrService` | Tesseract OCR:n omaksuminen ohjelmien muodossa | SSK2MB | \~100ms S| Tarvitaan tekstiä asiakirjojen skannausta varten
| `IOcrNerPipeline` | OCR ja sen jälkeen NER yhdellä puhelulla | Molemmat mallit | | | 3 | ms || | Teillä on kuvia ja haluatte entiteetit yhdessä vaiheessa |
| `ITextRecognizerService` | SäännötM SK1perustainen ekstraktointi (päivämäärät,puhelimet, jne.
| `IVisionService` | FlorenceM SK1 captioning + OCR SSK3 ~450MB S| | ~1-3s | SSK7 Kuvan ymmärtäminen on välttämätöntä, ei vain tekstin lukeminen CSK9

---


## NER tekstistä (Ei tarvita kuvia

Jos teillä on jo teksti (PDFistä,tietokannatM SK2käyttäjän tulot ), voitte käyttää NER:tä suoraanMSC4 Tämä on nopein menettelytapa |- ilman OCR-koodia | , ilman kuvakäsittelyä |

Euroopan unionin `INerService` liides on yksinkertainen - yksi menetelmäM SK1

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

Täällä's miten käyttää sitä omassa palvelussanne:

```csharp
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
        }
    }
}
```

Tulosmallit ovat yksinkertaisia:

```csharp
// 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)
}
```

Ensimmäinen puhelu lataa HuggingFace-järjestelmästä BERT NER-mallin (~430MB) Toissijaiset puhelut käyttävät tallennettua mallia.

---


## OCR + NER-putki

,, OCR, , ja NER käsitellään yhdessä puhelussa. `IOcrNerPipeline` yhdistetään `IOcrService` ja `INerService`:

```csharp
// 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
    };
}
```

Käyttämällä sitä:

```csharp
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...
}
```

### What Happens Under the Hood

```mermaid
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
```

---


## Kuvan ennakkokäsittely

Osa 1 oli raaka Tesseract-puheluja . KäytännössäM SK2 sekä Tesserac että Florence-2 toimivat paremmin ennalta käsiteltyjen kuvien kanssa **perimmäisenä** mutta täysin valinnainen - voi poistaa sen `Preprocessing = "None"` configissa tai `--preprocess none` CLI.

Euroopan unionin `ImagePreprocessor` käytännöt **KuvaSharp** (pure C

```csharp
// 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();
}
```

Kolme varausta on rakennettu. `PreprocessingOptions` luokka määrittelee ne:

```csharp
// 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
};
```

| Ennakolta | Milloin käytettäisiin SSK2 Mitä se tekee |
|--------|------------|--------------|
| `Default` | Useimmat kuvat | Sininen mittakaava + S1.5x kontrasti M+ valonpesäys МSK5
| `Minimal` | Puhtaiset skannaukset
| `Aggressive` | Heikkolaatuiset valokuvat

### AvoimenCV:n kanssa edistetty ennakkokäsittely

Vakavasti heikennettyjen asiakirjojen osalta - vääristyneet skansit , meluisat valokuvat, hajotetut historialliset sivut |- ImageSharp-putki ei ole riittävä | `EnableAdvancedPreprocessing` siirretään täydelliseen OpenCV-kaasuputkeen, joka on siirretty [ImageSummarizer](https://github.com/scottgal/lucidrag).

OpenCV:n ennakkokäsittelyketjussa on neljä vaihetta, joista kutakin johtaa automaattinen laadunarviointi.

```mermaid
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
```

**Laatuarviointi** (`ImageQualityAssessor`) mittaa hämäryyttä, , katkeamisaskel,, melutaso,MSC3 kontrasti,M SK4 valon yhtenäisyys,, ja tekstipitoisuus,MST6 tulosten perusteella, , suosittaa, millaisia vaiheita soveltaa, jotta puhtaat kuvat vältetään tarpeettomasta käsittelystä,.

**Deskew** (`SkewCorrector`) korjaa käännetyt asiakirjat kolmen menetelmän avulla

**Denois** (`NoiseReducer`) tarjoaa Gaussian hämäryksen (nopeudetM SK2 kahdenväliset filterit (muurinmuurit-varmistaminenMSC5ei--alueelliset keinot M(yleisimmät laadunmuodotMST8 ja morfologiset toiminnotMSV9

**Binarisointi** (`InkExtractor`) muuntaa puhtaaksi mustaksi - ja-valkoiseksi käyttäen OtsuaM SK3 mukautuva kynnysarvoMSC4 Sauvolaa ( heikennettyihin historiallisiin asiakirjoihinMスク6 CLAHEa \+ Otsuta M( alhaiseen kontrastiinMST9 taimorfologisen taustan poistamiseenMSV10

Sovuttaa se konfiguroinnissa tai CLI:

```csharp
config.EnableAdvancedPreprocessing = true;
```

```bash
ocrner ocr damaged-scan.png -a
```

---


## Microsoft.Recognizers:RegelM SK2Based Entity Extraction

BERT NER-tutkimuksessa löydetään ihmisiä, organisaatioita, sijaintojaM SK2 ja erilaisia toimijoita . mutta joitakin rakenteellisia tietoja MSC4 päivämääriäMST5 puhelinnumerojaMst6 sähköpostiaM st7 URL:itäMt8 IP-osoitteita.

Asetetaan `EnableRecognizers` lisätään toinen ekstraktiivinen passi käyttämällä [Microsoft.Recognizers.Text](https://github.com/microsoft/Recognizers-Text). Tämä käy **sen jälkeen** NER ja liitteet:

| Typi | Esimerkit |
|------|----------|
| päivämääräTime | SSK2tammikuinen 15, \2024",\ \SSK5\huomenna tiistai \", \ "\ viimeviikko \ " \ SSK9\
|Lisämäärä | "42", \"kolme miljoonaaM SK4 |"15%" | |
|URL | SSK2httpsM SK3esimerkkiMSC4com", \"www
| Puheelin | "555-1234", \"+1 |(555) | 123-4567" |
| E-mail | SSK2johnMSC3microsoftM SK4com" |
| IP-osoite

Tunnustaja tukee useita kulttuureja (en-usM SK2 en -gbMST4 deMSC5deMSV6 frMSP7frMSM8 jneMSL9 joten se käsittelee paikallisiaMSR10kohtaisia päivämääriä ja numerosääntöjäMSSK11

```csharp
config.EnableRecognizers = true;
config.RecognizerCulture = "en-us";
```

```bash
ocrner ner "John Smith joined Microsoft on January 15, 2024. Call 555-1234." -r
```

Molemmat ekstraktiiviset menetelmät täydentävät toisiaan: BERT NER ymmärtää kontekstin ("AppleM SK2 yritys vs\. "apple~" hedelmäMSC6, kun taas tunnistajat kiinnittävät luotettavasti rakenteellisia malleja, joita BERT voi jättää huomiottaMST7 `OcrNerResult` malli sisältää nyt valinnaisen `Signals` omaisuus:

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

---


## Florence-2 Vision

Florence-2 on täysin erilainen lähestymistapa kuin Tesseract **näkömalli** , joka ymmärtää kokonaisen kuvan.

```csharp
// 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);
}
```

Käyttämällä sitä:

```csharp
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
}
```

### Milloin sitä käytetään

| Käytännöllinen tapaus | Tesseract`IOcrService`)`IVisionService`) |
|----------|--------------------------|-------------------------------|
| **Asiakirjaskannat** | Paras valinta - nopea
| **Kuvat merkiistä** | Hyvä | Parempi - ymmärtää tapahtuman taustaa M|
| **Kuvat** | Hyvä
| **Kuvan captionointi** | VoikoM SK1 ei voi tehdä tätä | Paras valinta |
| **Nopeus** | Nopeutettu (~100msM SK2
| **mallikoko** |

Kyse on **tehokkuus**: käyttää Tesseract-ohjelmaa asiakirjojen ja tekstien extrakointiin (itM SK2s 10x nopeampi M100x pienempi malli). käyttä FlorenceMSC6, kun itse asiassa tarvitaan kuva *ymmärrys*.

Florence-2 autoM SK1downloads its models (~450MBMSC3 first use to `{ModelDirectory}/florence2/`.

---


## NER-putken sisäinen toiminta

NER:n putkijohto noudattaa samaa kolmesta - - -vaiheesta koostuvaa prosessia, jota käsitellään yksityiskohtaisesti [Osa 1](/blog/simple-ocr-ner-extraction): **tokenisoida → päätellä → dekoda**. Osuus | 1 kulkee läpi jokaisen käsitteen |- WordPiece-tokenointi |

Tässä on se, mitä paketti tuo mukanaan käsin tapahtuvan lähestymistavan lisäksi.

### Offset-seuranta

Osa 1's tokenizer muuntaa tekstin token ID:iksi `BertNerTokenizer` myös jäljitteitä **kirjaimen offsetit** - niin että tiedätte tarkasti, missä lähdetekstissä kutakin asiaa löydettiin

```csharp
// 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)
```

Näin `NerEntity.StartOffset` ja `EndOffset` työ - ne kartoitetaan takaisin alkuperäisessä tekstissänne täsmälliseen kirjaimen asemaan

### Luottamus

Osa 1's decoder tuottaa kaikki entiteetit. Pakettifilteroi dekodin aikana - alhainen

```csharp
// 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: Miten se toimii

Kaikki mallit laaditaan automaattisesti ensimmäisessä käytössä. Ei tarvita hallinnollista käyttöönottoaM SK1

```mermaid
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
```

Euroopan unionin `ModelDownloader` downloads from HuggingFace (NER modelM SK1 and GitHub (tessdata). `.tmp` malli - jos ohjelmia laaditaan keskeytetyksi, ei jätetä korruptoituneita tietoja jäljelle

```csharp
// 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
```

Standardin Cache-paikka: `{AppBaseDir}/models/ocrner/`

```text
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)
```

---


## Rakennus

Everything is a singleton with lazy initialization. kalliit resurssit M SK1ONNX `InferenceSession`, `TesseractEngine`, FlorenssiM SK1 malli ) luodaan ensimmäisen käytön jälkeen ja käytetään uudelleen soveltamisen keston ajaksi

```mermaid
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: kaikki palvelut `SemaphoreSlim` inicialisointia varten. Monien samanaikaisesti ensimmäisen käytön yhteydessä käyttävien palvelujen käyttö käynnistää vain yhden laadinnan

```csharp
// 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-väline

Reso sisältää käännösmuodon-line-välineen, joka on rakennettu [Spectre.Konsole](https://spectreconsole.net/). Se, ', on suunniteltu menestyksen huippuksi.

### Nopea alku

```bash
# 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
```

**Älykäs eteneminen**: CLI autoM SK1 havaitsee tarkoituksenne `Program.cs`:

```csharp
// 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
}
```

Jos välitätte tekstistringin, se toimii NER:n mukaisesti.

### Kolme käskyä

| Päätöslauselma SSK1 Mitä se tekee |moottori S| Nopeus M|
|---------|-------------|--------|-------|
| `ner <text>` | Tekstistä otetaan entiteetit pois | BERT NER
| `ocr <path>` | OCR
| `caption <path>` | Kuvaus captioning + valinnainen OCR SSK2 FlorenceM SK3 (ONNX) | |

**Tesseract on standardi OCR-moottori** koska se's M SK1x nopeutetaan ja optimoidaan asiakirjan tekstiin . Firenze-2 on tarpeen silloin, kun tarvitsette kuvan ymmärtämistä (captionsMSC5 scene textMST6 signien valokuvatMSV7

### Todelliset tulokset

Tässä on todellista tulosta CLI:n käyttämisestä todellisiin esikuva-asiakirjoihin nähden.

**NER tekstistä:**

```bash
ocrner ner "Marie Curie won the Nobel Prize in Stockholm"
```

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

**NER:n tunnustajat** - BERT-yksiköiden yhdistäminen sääntöönM SK1johdonmukainen signaalisiirto:

```bash
ocrner ner "Shelby Lucier from SCS Agency in Cambridge, UK sent an invoice on 13/02/15. Call 07981423683." -r
```

```text
╭──────┬───────────────┬────────────┬──────────╮
│ 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-tutkimuksessa löydetään henkilöt, järjestöt ja paikat, , ja . Tunnustajat löytävät päivämäärän ja puhelinnumeron - rakenteelliset muodot, jotka hermoston verkosto ei voi luottaa saamaan aikaan

**OCR skannatusta asiakirjasta** (Amazonin osakkeenomistajien kirje, , skannattiin aukolla,-punch marks,):

```bash
ocrner ocr shareholder-letter.jpg -q
```

```text
╭──────┬───────────────┬────────────┬──────────╮
│ 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 vie läheltä -verbatim-tekstiä skannatusta kirjaimesta 89% luottamuksellisella jäljittämisellä , , ja NER tunnistaa asianmukaisesti Amazonin ,

### Tesseract vs Florence-2: Reaali vertailu

Sama skannattu osakkeenomistajien kirje, jota käsitellään molemmissa koneissa:

Tesseract (`ocrner ocr`)`ocrner caption --ocr`) |
|---|---|---|
| **Nopeus** |
| **OCR:n tarkkuus** | LähesM SK1verbatim, 89%luottamus
| **Avainteksti** | "Amazonissa on kuluneiden kahden vuoden aikana ollut tilaisuutta write many narrative.
| **NER-yhteisöt** | Jeff (PERM SK2 Amazon (ORG), AWS (ORG\), Amerika SSK7LOCMSC8 M| N~/A МSK11teksti on liian hajanainen luotettaviksi NER*)
| **Luettelo** | NM SK1A

Florence-2 on **näkemys** malli - se ymmärtää näkökohtia , esineitä M SK2 ja alueellisia suhteita . Se ei ole koskaan suunniteltu kilpailemaan Tesseractin kanssa asiakirjan tekstin lukemisessa *ymmärrys* (mikä se on? *kaivaus* ( mitä tässä asiakirjassa sanotaan

### & LLM-välineet

Euroopan unionin `--json` lipputulokset rakentavat JSONin stdout-järjestelmään, jossa kaikki merkinnät supistuvat. - suunniteltu katkaisettavaksi muihin työkaluihin.

```bash
ocrner ner "Shelby Lucier from SCS Agency in Cambridge, UK sent an invoice on 13/02/15. Call 07981423683." -r --json
```

```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" }]
  }
}
```

Tämä tekee CLI:stä käyttökelpoisen **väline** LLM:ille ja agenteille. LLM voi soittaa `ocrner ner "..." --json`, analysoi JSON:n vastausta , ja perustelee rakenteellisia yksiköitä. `jq`, välittäjän kehykseen toimittaminen, tai minkä tahansa kielen lukeminen

```bash
# 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
```

To save to a file instead, use `-o` omalla `.json` laajentaminen - samat rakenteelliset tiedot, kirjoitettu disktiinM SK2

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

### Tappikäsittely

Monien kuvien käsittely glob-muodon tai luetteloiden avulla:

```bash
# 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
```

### Kaikki CLI-vaihtoehdot

| Lippu | Sovelletaan SSK2 Kuvaus |
|------|------------|-------------|
| `--json` | `ner`, `ocr`, `caption` | Structured JSON to stdout `--quiet`, suppresses all logging
| `-c` | `ner`, `ocr` | Vähimmäisyritysten luottamuksen raja-arvo
| `--language` | `ocr` | Tesseract-kieli  (esimerkiksi `eng`, `fra`) |
| `--max-tokens` | `ner`, `ocr` | BERT-järjestelmien enimmäispituus
| `--model-dir` | `ner`, `ocr`, `caption` | mallin cache directory override
| `-p`, `--preprocess` | `ocr`, `caption` | Ennaltakäsittelyä koskeva ennakkomääräys `none`, `minimal`, `default`, `aggressive` |
| `-a`, `--advanced-preprocess` | `ocr`, `caption` | Käytetään OpenCV:n ennakkokäsittelyä.
| `-r`, `--recognizers` | `ner`, `ocr` | Sovelletaan sääntöäM SK1perustainen ekstraktointi (päivämäärät,numerotSSK4URL-osoitteetMST5puhelinetMKT6 sähköpostitMSKT7IP-osoitteitaMSCT8 SKT9
| `--culture` | `ner`, `ocr` | `en-us`, `de-de` (defaultM SK1 `en-us`) |
| `--brief` | `caption` | Generaa lyhyemmänM SK1 vähemmän yksityiskohtaisen katsauksen |
| `-q`, `--quiet` | `ner`, `ocr`, `caption` | Tyynenmodus
| `-o` | `ner`, `ocr`, `caption` | Saavutusliitteen etenemissuunnitelma (`.txt`, `.md`, `.json`) |
| `--ocr` | `caption` | Jatketaan myös OCR:tä caption-todistuksen aikana.
| `--ner` | `caption` | Poistaa NER:n OCR-tekstistä `--ocr`) |

---


## Toimivuus: Määrälliset mallit ja mikäM SK1 seuraava

Nykyinen NER-malli on täydellinen `protectai/bert-base-NER-onnx` (~430MB **määrällinen** Saman mallin (INT8) version olisi huomattavasti nopeampi ilman minkäänlaista virheellistä virhettä

ONNXin runtime-järjestelmässä tuetaan INT:n, 8:n ja ,:n kumulaatiota, joka yleensä vähentää mallikokoa ~4x:lla ja parantaa inferenssin nopeutta CPU:llä 2-3x:llä. `NerModelRepo` config-mahdollisuus tukee jo viittausta toiseen HuggingFace-repoon, joten kun kvantifioitu malli julkaistaan, muuttakaa vainM SK2

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

Järjestelmä on suunniteltu tähän - vaihtaa mallia , säilyttää sama API

---


## Suurimpi kuva: Missä tämä sopii

Tämä paketti on **yksivaiheinen kaasuputki**:, yksi OCR-moottori, ,, yksi NER-malli, ,, yksi valinnainen näkemismalli,., se on suunniteltu yksinkertaiseksi ja tehokkaaksi tavalliseen tapaukseen.

Monimutkaisempien skenaarioiden osalta - lukee teksti *mikä tahansa* (käsin kirjoitetut huomautukset, , valotaulujen valokuvat,, alhainen, M SK3 laadukkaat kamerakatsaukset,), monikäyttöiset,M SK5 koneen OCR-yhteisymmärrys,MSC6 hämärän vastauksen löytäminen,MST7 ja rakenteellinen ekstraktointi. [***ilmeinen*RAG**](https://www.lucidrag.com). SeM SK1 missä tämän työn tuotantovaiheen version variantti, -laadunmukainen,, monimuotoinen,- elää

### Mikä's Seuraava: Monimuotoiset LLM-järjestelmät

Florence-2 on tämän paketin nykyinen yläraja paikalliselle näkemykselle. **monimuotoinen LLM** - malli, joka pystyy näkemään kuvan *ja* perustelu luonnonkielellä. OCR:n erillisen lähettämisen sijasta + NER:n vaiheet, lähettäisitte kuvan suoraan ja pyytäisitte rakenteellista ekstraktiota

Tässä on arvio siitä, miltä API voisi näyttää.

```csharp
// 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"
```

Pienet paikalliset multimodaaliset mallit (kuten [Phi-3.5-vision](https://huggingface.co/microsoft/Phi-3.5-vision-instruct) tai [LLaVA](https://llava-vl.github.io/)) on tulossa riittävän hyväksi tähän, . kaupankäynti, -off on aina samaa, M SK3 suurempi malli, \ = älykkäämpi mutta hitaampi \.\ oikea valinta riippuu latenttibudjetistanne ja tarkkuusvaatimuksistanne.

```mermaid
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
```

Jokaisella tasolla lisätään kapasiteettia koko ja latenssin kustannuksella. [***ilmeinen*RAG**](https://www.lucidrag.com) on otsikko.

---


## Resurssit

**Tämä paketti**:

- **[Mostlylucid.OcrNer NuGetissä](https://www.nuget.org/packages/Mostlylucid.OcrNer)** - asentaa se
- **[Lähdekoodi](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.OcrNer)** - Tutka täytäntöönpanoa

**Osa 1**:

- **[Yksinkertainen OCR- ja NER-ominaisuuksien extrakointi](/blog/simple-ocr-ner-extraction)** - Tuttori, joka selittää jokaisen osan

**Riippuvuus**:

- **[Tesseract.NET](https://github.com/charlesw/tesseract)** Tesseract OCR:n wrapper
- **[BERT-base-NER ONNX](https://huggingface.co/protectai/bert-base-NER-onnx)** - NER-malli
- **[Firenze](https://www.nuget.org/packages/Florence2)** - Vision malli NuGet-paketti
- **[KuvaSharp](https://sixlabors.com/products/imagesharp/)** - CrossM SK1platform-image processing
- **[OpenCvSharp4](https://github.com/shimat/opencvsharp)** - OpenCV wrapper kehittyneelle ennakkokäsittelylle
- **[Microsoft.Recognizers.Text](https://github.com/microsoft/Recognizers-Text)** - Säännöt
- **[ONNX:n käyttöaika](https://onnxruntime.ai/)** - Yhdenlaajuinen -platform-mallin johtopäätös

**Related Articles**:

- **[Kolmansien -Tier OCR-putken putki](/blog/constrained-fuzzy-image-ocr-pipeline)** - Kun tarvitaan muutakin kuin yksinkertaista OCR:tä
- **[Vähennetty RAG](/blog/reduced-rag-concept)** - Missä ekstrahoidut entiteet sopivat kokonaiskuvaan
- **[*ilmeinen*RAG](https://www.lucidrag.com)** - Täysin monivaiheinen -vaiheen tuotantoputki