Back to "Mostlucid.Ocrner @ -NuGet套件@(Part @2)"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

AI CSharp NER NuGet OCR ONNX Tutorial

Mostlucid.Ocrner @ -NuGet套件@(Part @2)

Thursday, 12 February 2026

Nuget 元数 NuGet 下载 GitHub 释放 (CLIMS K1

部分#1 我展示了原始管道:手动下载模型, 写着一个象征性的~, 连接在ONNX发酵@, 并用手去解码 BIO标记

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

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


快速词汇表 @ (@ 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}不! 用于识别人们的数据集@,组织 @,地点}%,和各种实体_.
  • 佛罗伦萨-2 微软的小型视觉模型 可以描述它是什么 可见 在图像中 @(captions ,}对象@, text{).} 与宇宙魔方不同,因为它能理解整个场景_,}不只是字符 _.}

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

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

此软件包关闭空白@ : @

  1. 图像共享 预处理前 MOSK0灰色 ,对比度 振动=, 为OCR调制的磨亮
  2. OpenCV 高级预处理 (opt-in})
  3. 佛罗伦萨-2 通过 ONNX @(no cloud API) 本地图像字幕和OCR,
  4. 在 OCR 文本之上的 BERT NER - 将抽取的文字转换成已打字的实体 @(PER/ORG}ORGK3LOCMS K4MISC)您可以按
  5. 微软 . @ recogniizers @ MS K1@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 命令“M-”的线性应用程序,只要在框中工作即可

部分的改变是什么 @ 1 @ @

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”是教育性的 “-”理解每件作品的功用是什么?


开始

安安装

dotnet add package Mostlylucid.OcrNer

登记册服务

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

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

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

// 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@)

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

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

// 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}EnableAdvancedPreprocessingEnableRecognizers) 默认 false 因此,软件包对于使用该软件的用户来说保持轻量级。

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

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

四服务

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

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 简单 {-} 是一个方法\ :} 。

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

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

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

结果模型是直截了当的:

// 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 组合 IOcrServiceINerService:

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

使用它#:

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

兜帽下发生的事

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 用途 图像共享 没有本地属地 ):

// 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 类定义它们@:

// 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 从 图像合成器.

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

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 :\ 上启用它

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

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

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

启用 EnableRecognizers 添加第二个抽取出入证 微软 . @ recogniizers @ MS K1@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{.),所以它处理本地语=-特定日期格式和编号公约_.#

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

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

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

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

使用它#:

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 K2IOcrService? ) MS K1 佛罗伦萨 -2 NSK3IVisionService)
文档扫描 {\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: 正在解码@ → @ infer *→}.Q 部分 @1QQ 一步步走過每個概念@-Z WordPiece messicalization_,QOONX 高频推斷},QBIO標籤解碼 *,Q軟體信任度 {-Q}從頭開始,並且有一個完全可建構的示例.

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

偏移跟踪

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

// 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.StartOffsetEndOffset 工作“-” 他们映射回到您原始文本中的准确字符位置@.

信任-+Filtered实体采掘业

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

// 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@ :}它是如何运作的

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

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 模式“%-”中,如果下载被中断,#,没有留下腐败文件@:

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

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}模型_}在第一次使用时创建一次 并在应用期内再利用

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

// 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@.@ it' @%s 设计成成功的地方 @MS K2}#" @ @\ -}只要通过您的输入,它就有效了

快速启动

# 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:

// 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@ : @%

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

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

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

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

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%

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

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

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

@ @ @ @ 宇宙魔方 @ I( @ocrner ocr? ) MS K1 佛罗伦萨 -2 NSK3ocrner caption --ocr)
速度速度 @ @ 200#s @ mSSK2} @ I14_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 函数调用 或自动脚本@:}

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

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

# 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- 相同结构化数据@, 写到磁盘 @:

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

批次处理

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

# 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 @:}

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

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


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

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

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

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

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

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

// 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-ViewALLAVAI)}#MSSK1# #- #:#更大的型號#MPK4#更聪明,但慢點□.#} 正确的選擇取決於你的暫存预算和精確要求〞.#

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 区域包 标题@. @%


资源资源资源 资源和资源资源资源

此软件包:

部分#1:

依赖性:

相关条款:

logo

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