# Mostlucid.Ocrner @ -NuGet套件@(Part @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 下载](https://img.shields.io/nuget/dt/Mostlylucid.OcrNer)](https://www.nuget.org/packages/Mostlylucid.OcrNer/) [![GitHub 释放 (CLIMS K1](https://img.shields.io/github/v/release/scottgal/mostlylucidweb?filter=ocrner-*&label=CLI)](https://github.com/scottgal/mostlylucidweb/releases?q=ocrner)

内 [部分#1](/blog/simple-ocr-ner-extraction) 我展示了原始管道:手动下载模型, 写着一个象征性的~, 连接在ONNX发酵@, 并用手去解码 BIO标记

现在它是一个 NuGet 软件包@ . @ **一行设置@ , @ 零模式下载** “- ” 所有自动“-”“下载第一时间”“MS K2”

> **注::** 此宏包是一个简化的\ ,}焦点化工具, 用于从图像中提取文本和实体 MPK1。 如果您需要完整的多@ MS K2- 阶段管道以读取文字 *任何东西* (photos,}文件{, 屏幕截图}MS K3}字迹@, 动画吉弗,甚至视频}♪) [***清晰*RAG 区域包**](https://www.lucidrag.com) 该管道的“-”级版本在哪里生产?

[TOC]

---


## 快速词汇表 @ (@ if you' @ re new to this_ )\ {}

在我们潜水前, 关键词意味着什么? :?

- **OCR( 英国)** (Optical字符识别@) @ @-将文本图像转换成实际的文字字符。 您的代码可以使用\.}“ Think:g photo of a reccess turns into a text_.}
- **NN 中** 在西雅图的微软公司工作的 .+ @"#John Smith
- **NONX 运行时间** - @ 一种运行机器学习模型的方法 @ } 就像我们用来在您的机器上使用 BERT 模式, 而不需要 Python, @ TensorFlow@,}或 GPUMS K5}它以便携式方式运行该模型 `.onnx` 仅使用您的 CPU=.}文件@ , @ local+,}
- **布尔** 由Google提供且能理解文字背景的“.”语言模型。 [{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}不!](https://www.clips.uantwerpen.be/conll2003/ner/) 用于识别人们的数据集@,组织 @,地点}%,和各种实体_.
- **佛罗伦萨-2** 微软的小型视觉模型 可以描述它是什么 *可见* 在图像中 @(captions ,}对象@, text{).} 与宇宙魔方不同,因为它能理解整个场景_,}不只是字符 _.}

---


## 为什么比平原宇宙魔方更多? ?

清除文档文本Q,的方程式非常强烈, 但是它会掉落到噪音中的相片@ , 低-contrast surnings,和混合的 @ MS K4scene {+ text _" image}\. 它也停留在原始文字@ MPK8 您仍然需要额外的代码才能将该文本转换为结构化实体。 您可以实际使用\.

此软件包关闭空白@ : @ {}

1. **[图像共享](https://sixlabors.com/products/imagesharp/) 预处理前** MOSK0灰色 ,对比度 振动=, 为OCR调制的磨亮
2. **[OpenCV](https://opencv.org/) 高级预处理** (opt-in})
3. **[佛罗伦萨-2](https://huggingface.co/microsoft/Florence-2-base)** 通过 ONNX @(no cloud API) 本地图像字幕和OCR,
4. **在 OCR 文本之上的 BERT NER** - 将抽取的文字转换成已打字的实体 @(PER/ORG}ORGK3LOCMS K4MISC)您可以按
5. **[微软 . @ recogniizers @ MS K1@Text](https://github.com/microsoft/Recognizers-Text)** @ - @ rules@ -_ basic recipation of dates @ MPK2_ number\ MS K3} URLS,} 电话: ,{ 电子邮件 @ I,} IPs @(Oppt} MSKO8})}
6. **适当的开发数据基础设施一体化** - `AddOcrNer()` {\fn方正黑体简体\fs18\b1\bord
7. **CLI 工具** # -A# [频谱@ . @ console](https://spectreconsole.net/) 命令“M-”的线性应用程序,只要在框中工作即可

---


## 部分的改变是什么 @ 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
```

部分“1”是教育性的 “-”理解每件作品的功用是什么?

---


## 开始

### 安安装

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

### 登记册服务

缩略 `AddOcrNer()` 混合管道 ,Florence}-2View,模型下载器MS K6和图像预处理器. 全部作为单元@,所有懒惰{-初始=.

这里的' 实际注册代码来自 `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;
});
```

{\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}没有样板下载 {\fnarial black\fs12\bord1\1\shad0\4cH000000}沒有檔案路徑@,}沒有 ONNX 線線.在兜帽下 `AddOcrNer()` 这些服务注册@: @%

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

### 設定 & M( @ appetings @ ._json@)

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

这里='}这是真实的 `OcrNerConfig` 类中这些映射为 @:}%

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

所有设置都有明智的默认值 @ . 您可以略去整个部分, 一切正常工作@ MS K1 两个选择@ I-in 特性 @ MPK3}`EnableAdvancedPreprocessing` 和 `EnableRecognizers`) 默认 `false` 因此,软件包对于使用该软件的用户来说保持轻量级。

缩略 `Preprocessing` 在 OCR: {} 前的选项控件控制图像增强

“|值”“|它做什么? ”“|何时使用呢?”
|-------|-------------|-------------|
| `None` | 没有预处理@|图像已经优化了 @|
| `Minimal` | 灰度只有 @| 清洁扫描@|
| `Default` @|_灰度@+}对比点 #+_磨亮#|}大多数影像都是 ({推荐})}|}
| `Aggressive` @|# 强烈对比度 #+# 锐化 #+# 升级@|#

---


## 四服务

软件包注册了五个服务@, @ 每一个独立可用的\ .} 选择适合您使用的“ -Q” 案例的选项。 如果只需要文本中的 NER=., 那么无需装入 Florence@ MS K4 。

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

### 选择正确服务于您的使用案例

关键原则是 **效率效率**@ :_ 选择最轻的操作工具@ .} 唐'} 当一个 MS K4MB 的 OCR 引擎将完成 * . * 时, 请使用最轻的工具来装载 a\ MSC3\ MB 视觉模型 。

|服务 @| 它的模范大小@|}速度#|}当它使用时
|---------|-------------|------------|-------|-------------|
| `INerService` @|_BERT NER 来自文本 {|}~430MB <|} ~50ms _|}你已经有了文本 ~(PDF>,}数据库@,\ 用户输入{MS K9 200)}#|}
| `IOcrService` |Tesseract OCR,来自图像 @|@~4MB\| MS K4ms _|}您需要文档扫描的文字=,屏幕截图_|{
| `IOcrNerPipeline` @| OCR 然后一个呼叫NER\ {|} 两种型号 | ~150ms | 您在一步内有图像和想要实体 *#|}
| `ITextRecognizerService` “|”规则“-”基础提取 (dates @, phones@,}等等“MS K5 @#| None”|{~1|你想要结构化数据与净实体(Z|)一起
| `IVisionService` @| @Florence@-2}您需要理解影像@,#不只是文字阅读 #|#

---


## NER 来自文本 @ ( 没有需要的图像\ )

如果您已经从 PDFs,}数据库 < , user involution>\ MS K3 _ 您可以直接使用 NER <%. > 这是最快的路径 @- no OCR, 没有图像处理@, n只要在 ,\ 实体中文本\ MPK9 text

缩略 `INerService` 简单 {-} 是一个方法\ :} 。

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

这里的' 如何在您自己的服务中使用@:

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

结果模型是直截了当的:

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

首个呼叫下载 BERT NER 模式@(~430MB)}来自 Hugging Face @.}后继呼叫使用缓存模型{-}启动是即时=.}

---


## OCR Z+NER输油管

对于图像来说 ,管处理预处理 MS K1 OCR,和NER 一个调用\. `IOcrNerPipeline` 组合 `IOcrService` 和 `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
    };
}
```

使用它#:

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

### 兜帽下发生的事

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

---


## 图像预处理

部分“1”有原始的宇宙魔方呼叫@.在实践中 “, 泰方和佛罗伦萨-2对预处理图像更好工作,预处理是前处理。 **默认** 您可以禁用它 `Preprocessing = "None"` 以配置或 `--preprocess none` 在CLI.

缩略 `ImagePreprocessor` 用途 **图像共享** 没有本地属地 ):

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

三个预设在“.”中构建 `PreprocessingOptions` 类定义它们@:

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

“|”预设@|}何时使用 @| 做什么?
|--------|------------|--------------|
| `Default` @| 多数图像@| 灰度 @MS K2 @#1.5x对比度 @+ 灯光锐利 *|
| `Minimal` @ |_ 清洁扫描@ MS K1} 只有灰度 @ MPK2
| `Aggressive` 低质照片 @|_Q#1.8_X对比 *+}强力锐利 +_大规模的|{

### OpenCV 高级预处理

对于严重退化的文档 {-} 扭曲扫描@,} 吵闹的照片,} 已消逝的历史页 * @-} 图像沙尔普管道是'}* tQQ.}启用 `EnableAdvancedPreprocessing` 切换到全 OpenCV 从 [图像合成器](https://github.com/scottgal/lucidrag).

OpenCV预处理器链 四个阶段 , 由自动质量评估驱动

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

**质量评估** (`ImageQualityAssessor`)QQ 测量模糊度@, @skew 角度 @,}噪音水平 @MS K3}对比,}亮度统一性 @,}和文字密度\.}根據結果_,}它建議使用哪些階段 {-}(所以乾淨的圖片不必要地處理MS K9}

**书头** (`SkewCorrector`)校正旋转的文档 使用三种方法来校准循环的文档

**Denoisa 硬度** (`NoiseReducer`提供高山模糊的 @(_fast}),双边过滤器@(#adge _-{preservation{\),}非-}本地的意思是 @MS K7}最高品质$,}和形态操作=.}

**Binbiziziz 提醒** (`InkExtractor` 轉換為乾淨黑的 MS K1 和 -white 使用 Otsu, 適應下限 , Saudola {(} 以腐壞的历史文件 *), * CLAHE MS K7 Otsu @( 低对比度), 或形态背景移除\.

在配置或 CLI :\ 上启用它

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

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

---


## 微软.Recogniizers:规则{-基于实体采掘

BERT NER 发现人们“,”组织 “,”地点 @,和各种实体@. 但一些结构化数据“-}日期_,’ 电话号码{, emails, URLs*, IP 地址<->比神经网络更容易被确定性规则所控制\".?"

启用 `EnableRecognizers` 添加第二个抽取出入证 [微软 . @ recogniizers @ MS K1@Text](https://github.com/microsoft/Recognizers-Text). 本次运行 **之后** NER和提取 :

@| type #| 示例#|
|------|----------|
1月1日 15, {2024",}
",~"15%"~ MS K6~
@|Q URL @MS K1 " @https/://#example @MS4 @com_",} @" @www:.Github @MS8 @comQ" @ @ @MSC10 @
| 电话 MS K1 @"555-1234",} "+1+(555)+123-4567"#|#
|收发电子邮件: @| @@" @john_@ @微软 @MS K4 @comQ"}#|
@|_IP 地址@|_Q#"192.168.1.1"} @MSC3_

承认者支持多种文化 @(en-usMS K2en@-gb,de}(-DE),frMSsk7ffr,et{.),所以它处理本地语=-特定日期格式和编号公约_.#

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

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

两种采掘方法互为补充 :BERT NER理解上下文 @("Apple"公司诉. "apple}"果水果{),,而识别者则可靠地捕捉到BERTE可能错过的结构性模式_. `OcrNerResult` 模式现在包括一个可选的 `Signals` 属性@: @%

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

---


## 佛罗伦萨·-2

宇宙魔方是一个专门的 OCR 引擎, 它按字符读取文字字符@,\ @Florence_-2}是 **愿景模型** 能够理解整张图像@- @ 对象 @ ,} 场景 @ MPK2 @ people @ I,} 和文字@ MS K4

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

使用它#:

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

### 何时使用

|使用大小写|TesseractMS K2`IOcrService`? ) MS K1 佛罗伦萨 -2 NSK3`IVisionService`) |
|----------|--------------------------|-------------------------------|
| **文档扫描** {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}准确的| {\fnarial black\fs12\bord1\1\shad0\4aH00\fscy120\fscx90\fscy110}
| **标志照片** @|#体面的@|#更好 #-}理解场景背景 *|*
| **截图** |好,| 好,|
| **图像字幕** 最佳选择: |
| **速度速度** @|}快速 (~100 @ms@)# @ @ MS K3_ 慢速 *(~1-3 @s) @ @ @ |#
| **模型大小** -=YTET -伊甸园字幕组=- 翻译:

重点是 **效率效率**:在文档和文本提取中使用魔方 {(} iit'MS K3x 在您需要图像时使用佛罗伦萨=-2} *理解*.

Florence -2 自动- 下载其首用模型@(~450MBMS K3 `{ModelDirectory}/florence2/`.

---


## NER 管道如何在内部运作

NER 输油管道遵循同样的三- [部分#1](/blog/simple-ocr-ner-extraction): **正在解码@ → @ infer *→}**.Q 部分 @1QQ 一步步走過每個概念@-Z WordPiece messicalization_,QOONX 高频推斷},QBIO標籤解碼 *,Q軟體信任度 *{-Q}從頭開始,並且有一個完全可建構的示例*.

@'_Q_BARBAR_在手动处理方法之外,

### 偏移跟踪

@ 1'}%s messerizer 将文本转换为代号 ID@ MS K1 { `BertNerTokenizer` 也跟踪轨道 **字符抵消** -}(所以您知道源文本中每个实体的确切位置)

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

就是这样 `NerEntity.StartOffset` 和 `EndOffset` 工作“-” 他们映射回到您原始文本中的准确字符位置@.

### 信任-+Filtered实体采掘业

Part 1'}%s decoder 生产所有实体@.}在解码期间的包过滤器 *\ MS K2} < low\ - 信任噪音从未达到您的代码=:}

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

---


## 自动- @ 向下load@ :}它是如何运作的

所有模型在第一次使用时自动下载@. @ 不需要手动设置 @ . @

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

缩略 `ModelDownloader` 从 Hugging Face 下载以下数据: @(NER model@)}和 GitHub @MS K2Tesdata).}它使用原子 `.tmp` 模式“%-”中,如果下载被中断,#,没有留下腐败文件@:

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

默认缓存位置@: @% `{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)
```

---


## 建筑结构架构

所有东西都是单吨的懒惰初始化 . 昂贵的资源 *(ONNX `InferenceSession`, `TesseractEngine`@,_Florence_-2}模型_}在第一次使用时创建一次 并在应用期内再利用

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

使用的所有服务 `SemaphoreSlim` 初始化时@ . @ 多个线条同时在第一次使用时拨打服务, 只触发一个下载@ I/}load:}

```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 工具

repo 包含一个命令@ - @ line 工具, 用 [频谱@ . @ console](https://spectreconsole.net/)@.@ it' @%s 设计成成功的地方 @MS K2}#" @ @\ -}只要通过您的输入,它就有效了

### 快速启动

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

**智能路由**:CLI 自动- 检测您的意图@.來自 `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
}
```

如果您通过文本字符串 @ ,, 它会运行 NER\ . 如果您通过了图像文件@ MS K2 glob,或目录,}它会运行 OCR @ MPK5 Ner.不需要命令 @ OMK7

### 三个命令

|Q命令 @|Q 它所做的一切#|}引擎 @MS K3Q速度@|Q
|---------|-------------|--------|-------|
| `ner <text>` @|_ 摘自文本中的实体@|_ BERT NER#(ONX}){
| `ocr <path>` @| OCR +NER 从图像\ |Tesseract\ NSK3BERT{|~100-300AMsMS K6#
| `caption <path>` @|_图像字幕@+}(可选的 OCR ) @|#Florence_-2}(}ONNX=)}{|} @MS K7Qs *|*

**宇宙魔方是默认的 OCR 引擎** @'}@5-10#x 快速且优化的文档文本是用于您需要图像理解 @MS K4\captions_,}场景文字 @,}图片=).}

### 实际产出

这里'}根据真实的样本文档 运行 CLI 的实际输出=.}

**来自文本的 NER@ : @%**

```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    │
╰──────┴─────────────┴────────────┴──────────╯
```

**与识别者的净净入学率** - 将BERT实体与规则的-基信号提取}:

```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 发现人民-, 组织-MS K1 和地点-. 识别者捕捉到日期和电话号码-@- 结构模式,即神经网络在提取/.时不可靠-

**从扫描文档中的OCR** @(@an Amazon 亚马逊股东信件_,}扫描时用洞~-#punch mark_):}

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

@-@verbatim 上扫描信件中的字串摘要, 请正确辨别亚马逊#,_Jeff @(_Bezos),}AWS_,}和北美=.}

### 宇宙魔方对佛罗伦萨=-2:}真实比较

由两个引擎处理的相同扫描式股东信件

@| @ @ | @ 宇宙魔方 @ I( @`ocrner ocr`? ) MS K1 佛罗伦萨 -2 NSK3`ocrner caption --ocr`) |
|---|---|---|
| **速度速度** @| @ ~200#s @ mSSK2} @ I~14_s@|} @
| **OCR 精确度** @| @Near@- @verbatim_,} @ 89%#信任 #|$High KBledQ,幻音#|#*
| **关键字文字** 过去在亚马逊(Amazon)的25年中,
| **NER 实体** @| @Jeff@(PER}#Amazon # 亚马逊#(ORG#),}AWS @MS K5OORG}),America @(LOC□)|NNSKK10A (Text太模糊了,无法提供可靠的 NERZK12#MSC13#
| **标题** @| @N/#A |_ZMS K3}(有几篇文字的论文) MSSK4}{|}

佛罗伦萨-2是 **愿景** 它理解场景@,物件 @, 和空间关系\.}它从未设计过在阅读文档文本时与宇宙魔方竞争=.当您需要图像的时候使用它 *理解* @ ( @ whatsthis@ MS K1 @% 在此相片中, @ MPK2} 不是文本 *抽采* “(”这个文件怎么说?“?).”

### 自动化的 JSON 输出@ & @ LLM 工具

缩略 `--json` 结构化的 JSON 输出以停止所有被抑制的 {- 设置为 pipting 进入其它工具\,LLM 函数调用{MS K2} 或自动脚本@:}

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

这样CLI 就可以作为 **工具工具** LLM和代理商 . `ocrner ner "..." --json`“,”分析JSON回应“,”和对结构实体的理性 ‘-’,无需定制代码$.插管 `jq`, feed to a 代理框架 @,或阅读任何语言@:

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

要保存到文件@ , @ use `-o` 与 a 有 `.json` Q- 相同结构化数据@, 写到磁盘 @:

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

### 批次处理

使用球形模式或目录@:处理多个图像

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

### 所有 CLI 选项

|旗| 适用于 @|描述@|
|------|------------|-------------|
| `--json` | `ner`, `ocr`, `caption` | 结构化 JSON 以支撑 #(#implies `--quiet`“, 抑制所有伐木”“) |”
| `-c` | `ner`, `ocr` 最低实体信任阈值
| `--language` | `ocr` |Tesseract语言 @(例如 `eng`, `fra`) |
| `--max-tokens` | `ner`, `ocr` 最大BERT序列长度 @|
| `--model-dir` | `ner`, `ocr`, `caption` |模擬快取目录覆寫@|
| `-p`, `--preprocess` | `ocr`, `caption` |预处理预设@: `none`, `minimal`, `default`, `aggressive` |
| `-a`, `--advanced-preprocess` | `ocr`, `caption` |使用 OpenCV 预处理@(deskew,denoise},binarize) @#|
| `-r`, `--recognizers` | `ner`, `ocr` @|_启用规则@-_BARBasic discription #(\dates#,}号码 @,}URLs%,}(电话){,}电子邮件=,}IPs})}|}
| `--culture` | `ner`, `ocr` -=YTET -伊甸园字幕组=- 翻译: `en-us`, `de-de` @(_default :# `en-us`) |
| `--brief` | `caption` “|” 生成一个更短的“,” 小于细节的小标题 @|
| `-q`, `--quiet` | `ner`, `ocr`, `caption` | 静音模式 @( 降压控制台输出@) MS K3
| `-o` | `ner`, `ocr`, `caption` | 输出文件路径 @(`.txt`, `.md`, `.json`) |
| `--ocr` | `caption` @|}在字幕指令期间 也运行OCR *\ |}
| `--ner` | `caption` | 摘自 OCR 文本的 NER {(} immplies `--ocr`) |

---


## 性能 : 量化模型和下一步

目前的 NER 模式是全@ - @ 精度 `protectai/bert-base-NER-onnx` @-_ZA 受限制的机器或高容量处理时a a/ **量化** 同一型号的(INT8)版本将大大加快速度,精度损失最小@.

ONNX 运行时支持 INT8QQQontication 从框中分离出来@,}通常会通过 ~4x 降低模型大小,并通过 CPU=2-3x 在 CHU_.}提高推断速度 `NerModelRepo` 配置选项已支持指定一个不同的 Hugging Face repo,}这样当量化模型被发布时您 ' d just change @:}

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

此架构是设计用于此“ -” 转换模型“ I,” 的, 并保留相同的 API.“ 。

---


## "大图片"=:}这适合的地方

此软件包是一个 **单管 -阶段输油管**“: ”一个 OCR 引擎“,” 一个 NER 模型“MS K2 ” 一个可选的视觉模型“. ” “It'” 设计为简单而高效地处理普通案件“.”

读取来自 *任何东西* (}(手写便笺), 白板的相片 , 低(下) - 质量摄像头捕捉 *),* [***清晰*RAG 区域包**](https://www.lucidrag.com)此作品的制作版本“-QGRA”, moto @-阶段

### $' @%s next@:}多模式LMS

FlorenceMSMK0是此软件包中当前本地视野的上限@.下一个逻辑步骤是一个 **多式联运(LLM)** - 能够看到图像的模型Name *和* 您直接发送图像并要求结构提取@ . @ @

这里的' 大致上是API长得像什么

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

当地小型多式联运模式 [Phi-3.5-View](https://huggingface.co/microsoft/Phi-3.5-vision-instruct) 或 [ALLAVA](https://llava-vl.github.io/)I)}#MSSK1# #- #:#更大的型號#MPK4#更聪明,但慢點□.#} 正确的選擇取決於你的暫存预算和精確要求〞.#

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

包件目前涵盖的等级为“1-3.”-“Tier AS4”-是Admodal LLMs位于该地, [***清晰*RAG 区域包**](https://www.lucidrag.com) 标题@. @%

---


## 资源资源资源 资源和资源资源资源

**此软件包**:

- **[在 Nuget 上的 Mostlucid\ . @ Ocrner](https://www.nuget.org/packages/Mostlylucid.OcrNer)** 安装它
- **[源代码](https://github.com/scottgal/mostlylucidweb/tree/main/Mostlylucid.OcrNer)** - 浏览执行

**部分#1**:

- **[简单OCR和NER地物采掘](/blog/simple-ocr-ner-extraction)** “- 解释每件作品的教程”

**依赖性**:

- **[宇宙魔方=.NET](https://github.com/charlesw/tesseract)** 用于宇宙魔方 OCR 的 C#包装器
- **[BERT-Base-NEN ONNX(星际迷航)](https://huggingface.co/protectai/bert-base-NER-onnx)** *-NER模型
- **[佛罗伦萨-2](https://www.nuget.org/packages/Florence2)** - 愿景模型 NuGet 软件包
- **[图像共享](https://sixlabors.com/products/imagesharp/)** @ - @ cross @ I-_ 平台图像处理
- **[OpenCvSharp4](https://github.com/shimat/opencvsharp)** 用于高级预处理的- OpenCV 包装器
- **[微软 . @ recogniizers @ MS K1@Text](https://github.com/microsoft/Recognizers-Text)** - 规则-基于实体提取
- **[NONX 运行时间](https://onnxruntime.ai/)** -Cross-平台模型推断

**相关条款**:

- **[3-Tier OCR管道](/blog/constrained-fuzzy-image-ocr-pipeline)** 当您需要超过简单的 OCR时 -
- **[减少的RAG](/blog/reduced-rag-concept)** “- 采掘实体适合大局的地方”
- **[*清晰*RAG 区域包](https://www.lucidrag.com)** “- 完整的多管--阶段生产管道”