Back to "Найяскравіший.OcrNer M SK1 Пакет NuGet ( Частка МSK3"

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

Найяскравіший.OcrNer M SK1 Пакет NuGet ( Частка МSK3

Thursday, 12 February 2026

NuGet Скачивки NuGet Випуск на GitHub (CLI)

В Частина 1 Я показав сирову трубу. МСК0. Ручно завантажуючи моделі. МSK1. Пишаючи токенізер. ММК2. Використовуючи набір ONNX. МКС3. І розшифровуючи BIO-теги вручну. ММСК4. Освітній. МПСК5. Але багато водопроводів, щоб зробити все правильно. МУСК6.

Тепер це - пакет NuGet Один ряд установок, нуль загрузок моделей - все автоматизовано -завантаження на перший разM SK2

Nota: Цей пакет є спрощеним, фокусованим інструментом для видобутку тексту та об 'єктів з зображень будь-що (фотографіїM SK1 документи МSK2 скриншоти , ручний малюнокМSK4 анімованіGIFи і навіть відео) з неяскравим співпадіннямMSC6 консенсус OCRMST7 та структурований видобутокМST8 перевірте прозораРАГ де проходить виробництво-швидкісної версії цього трубопроводуM SK1


Короткий словник (Якщо виM SK1Новый до цього)

Перед тим, як зануритися в це слово:

  • ОCR (Опtical Character RecognitionM SK1 - Перетворення зображення тексту в реальні текстові символи, з яким може працювати ваш код. Подумайте
  • NER (Назвизнання іменних об 'єктівM SK1 - сканування тексту, щоб знайти та класифікувати імена речей. " Джон Сміт працює в Microsoft у СіетліMSC5 стаєMSSK6 ДжонСміт МSK7 ЛюдинаMSL8 Microsoft МSK9 ОрганізаціяMСК10 Сіетл ♫ = Местонахождение ♫ МСК12 ♫
  • Пропускний час на NX - спосіб запускати моделі машинного навчання так само як модель BERT, яку ми використовуємо для NER .onnx файл, локально
  • БЕРТ - це попереднє МSK1 тренований модель мови від Google, яка розуміє контекст у тексті . Варіант NER був добре влаштований CoNLL-2003 набір даних для розпізнавання людей, організаційM SK1 локаційМSK2 та різних груп.
  • Флоренція-2 - маленька модель візуалізації від Microsoft, яка може описати бачить в зображенні (капції , об 'єкти, текстM SK3 По-іншому, ніж Тесеракт, він розуміє всю сценуMSC4 не лише символиMST5

Чому більше ніж простий тексеракт

Tesseract ефективний для чистого тексту dokumentu, але він потрапив на шумні фотографіїМSK1 низькийM SK2 контрастні скани, і змішені MSC4 сцена МСК5 текстМ СК6 зображенняMСК7 Він також зупиняється на сирому тексті МСК8 ви все ще потребуєте додаткового коду, щоб перетворити цей текст на структуровані об 'єкти, які ви дійсно можете використовуватиMSК9

Цей пакет вирішує ці прогалини.

  1. Зображення передрозробка - сірий діапазонM SK1 покращення контрасту, пристроєння для OCR
  2. OpenCV розвинене попереднє оброблення - дескю МSK1 денозі МSK2 і бінарізацію для пошкоджених / схвильованих документів M опт МСК5 в МSK6
  3. Флоренція-2 візуалізація - локальне субтитриювання зображення і OCR через ONNX (без хмарного API МSK2
  4. BERT NER зверху тексту OCR - перетворити виňaтений текст в задруковані об 'єкти PERM SK2ORG/LOCMSC4MISCMST5 ви можете діяти на
  5. Microsoft.Recognizers.Text МСК0 правилоМSK1податковий вилученняМСК2 цифриМ СК3 URLsM СК4 телефониМ סК5 електронні листиМ S К6 і IP MСК7 оптM S К8 в М СК9
  6. Правильна інтеграція DI - AddOcrNer() і ви закінчили
  7. Програмне забезпечення CLI - А Спектр.Консоль command- - додаток для лінії, який просто працює з коробки

Що змінилося з частини 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 була освітньою - розуміння того, що робить кожна частина МSK2 Część МSK3 є практичною \ - використання її без роздумів про внутрішні речі \ МSK5


Початок

Установити

dotnet add package Mostlylucid.OcrNer

Услуги реєстрування

І AddOcrNer() метод розширення записує все : OCR, NERM SK2 об 'єднаний трубний кабель МSK3 Флоренція МСК4 зоріобачення М СК5 модельний завантажувач M СК6 і пристрій для обробки зображення М S К 7 Все як одинокі тони M S К 8 всі лінивіші М ็ С К 9 зачаровані M ็ S К 10

Тут - МСК0 - це справжній регистрационний код 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;
});

МSK0 - це він. МSK1 - Ніхто не завантажує моделі, МSK2 - немає файлових маршрутів, , - немає ONNX підключення, МСК4 - під капюшоном, MСК5 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

Konfiguration (appsettings.jsonM SK2

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

У всіх настроях є розумні початкові параметри. Ви можете закинути весь розділ і все працюєM SK1 Дві оптики - в функціях (EnableAdvancedPreprocessing і EnableRecognizers) по замовчуванню до false таким чином пакет залишається легким для користувачів, які не потребують його.

І Preprocessing опція контролює покращення зображення перед OCR:

Wartość МSK1 Що це робить МSK2 Коли використовувати
None Жодного попереднього обробки МSK1 Зображення вже оптимізовані МSK2
Minimal Тільки Grayscale Чисті скани МSK2
Default Грейова шкала МSK1 контраст МSK2 острів Більшість образів M( запропоновані
Aggressive Сильний контраст МSK1 острівніше МSK2 збільшення Slikи поганої якості MSК4

Чотири служби

Пакет записує п 'ять сервісів, кожен корисний окремоM SK1 Виберіть той, який підходить для вашого призначення MSC2 там' немає потреби завантажувати ФлоренціюMST4 якщо все, що вам потрібно - це NER з текстуМST5

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

Вибирати правильну службу для вашого випадку використання

Головним принципом є ефективність: вибрати найлегший інструмент, який виконує цю функцію . Не завантаження МSK2 модель візуалізації МSK3 МБ, коли OCR-мобіль M SK4 Мб буде виконувати свою функцію

Obsługа МSK1 Що він робить МSK2 розмір моделі Швидкість мSK4 Використовуйте, коли
INerService BERT NER з тексту МSK1 ~430 MB
IOcrService Tesseract OCR з зображеннях МSK2MB МSK3 ♫ ♫ ~100ms ♫ МSK5 Вам потрібен текст із сканування документів ♫, скриншоти ♫
IOcrNerPipeline ОCR, потім NER в одному дзвінку МSK1 Обидві моделі МSK2 ~150ms M У вас є зображення і хочете об 'єкти в один крок МСК5
ITextRecognizerService ПравилоМSK1виведення на основі МСК2стані datumиMСК3 телефониМ СК4 і т.д.
IVisionService ФлоренціяM SK1 субтитри МSK2 ОКР МSK3 ~450 МБ 5 6 7 Вам потрібно розуміти зображення МSK8 не просто читати текст

NER з тексту (Непотрібні зображення

Якщо у вас вже є текст ( з PDFs , бази даних МSK2 вхід користувача M SK3 ви можете використовувати NER напрямуМSK4 це найшвидший шлях МСК5 без OCR МСК6 без обробки зображень

І INerService інтерфейс простий - один метод

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

Тут' як його використовувати в своїй власній сферіM SK1

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 (~430MBM SK1 з HuggingFace. Наступні дзвінки використовують зашифровану модель


ОCR + NER Pipeline

Для зображеннях, труба об 'єднує підготування, OCRM SK2 і NER в одному wywołaнніMSC3 IOcrNerPipeline об 'єднує IOcrService і INerService:

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

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

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

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

Використовуючи його:

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 мала необроблені дзвінки Tesseract . В praktyce, як Tesserac, так і FlorenceM SK3 працюють краще з передрозробленими зображеннямиMSC4 Передрозробка по замовчуванню але цілком опціонально - ви можете вимкнути його з Preprocessing = "None" в конфігурації або --preprocess none на CLI.

І ImagePreprocessor використання Зображення (pure C

// 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
};
Упередбачуваний МSK1 Коли використовувати МSK2 Що це робить
Default Більшість образів МSK1 Грейова шкала МSK2 1.5 x контраст M+ остришайте світло МСК5
Minimal Чисті скани тільки в чорних діапазонах МSK2
Aggressive Неякісні фотографії МSK1 МSK2x контраст + жорсткий зустріч MSК4 більший масштаб МСК5

Дальне попереднє оброблення з OpenCV

Для серйозно зруйнованих документів - skewed scans , noisy photosM SK2 faded historical pages МSK3 ImageSharp pipeline is not enough EnableAdvancedPreprocessing переключитися на повну трубу OpenCV, портowaną з ImageSummarizer.

Працпроцесор 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) вимірює невизначеність , кут відхилення МSK2 рівень шуму MSC3 контраст M SK4 однорідність яскравостіМSK5 і щільність текстуM SK6 На основі результатів, він запропонує, які етапи застосування МСК8 так, щоб чисті зображення пропустили непотрібне обробленняMСК9

Дескеу (SkewCorrector) коректує обертені документи за допомогою трьох методів : виявлення товстої лінії

Денуаї (NoiseReducer) пропонує гаусову розбіжність МSK1швидкий МSK2 двосторонний фильтр ( стовпень

Бінариз (InkExtractor) перетворюється на чисту чорну матрицю МSK1 та МSK2 білу, використовуючи OtsuM SK3 пристосований порог , Сауволу \ ( для зруйнованих історичних документів

Ввімкніть його в конфігурації або на CLI:

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

Microsoft.Recognizers: RuleM SK2Based Entity Extraction

БЕРТ NER знаходить людей МСК0 організації МSK1 локації , і різні об 'єкти М SK3 Але деякі структуровані дані МСК4 дати М СК5 телефонні номери М סК6 електронні листи М S К 7 URLs М ็ С К 8 IP адреси M С К 9 краще ловиться детерміністичними правилами, ніж нейронною мережею М Ш К 10

Створити EnableRecognizers додавати другу видобутку за допомогою Microsoft.Recognizers.Text. Це працює після NER та ekstraktи:

МСК0 Тип | Приклади | |------|----------| МSK0 DataTime | МSK2Januar 15, ♫ ♫ МSK4 ♫ МSK0 Число МSK1 "42", "три мільйони | URL МSK1 МSK2 httpsM SK3example.comMSC5 | | "wwwMスク7githubMST8com"\ | МSK10
| Телефон | E-mail | | IP адрес МSK1 МSK2 |

Цей розпізнавач підходить для різних культур: (ru-usM SK2 ru -gbMST4 deMSC5deMS, frMSV7frM SV8 і т.д.Msv9 таким чином він обробляє локальні формати data та числові конвенції

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

Дві методи видобутку доповнюють одна одну. : BERT NER розуміє контекст: (" яблуко МSK2 компанія проти МSK3 "\ яблука \ "\ фрукт \ МSK6 , тоді як розпізнавачі надійно ловлять структуровані візерунки, які BERT може пропустити. 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 Vision

Флоренція-2 - це зовсім інший підхід від ТеsseractM SK1, де Tesseract - це спеціалізований OCR-аналізатор, який читає текст символ за символом. модель зору що розуміє ціле зображення. - об 'єкти , сцени МSK2 люди, , і текст

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

Коли використовувати який

Застосований випадок Тесеракт МSK2IOcrServiceМSK0 Флоренція МSK2 (IVisionService)
Сканування документів МSK0 Найкращий варіант - швидкий МSK2 точний Гаразд, але надмірна кількість
Фотографії знаків Досить МSK1 Краще МSK2 розуміє контекст сцени
Скрині кадри МSK0 Хороша Хороший МSK2
Написування зображення МожешM SK1 не робити цього Найкращий варіант МSK3
Швидка Гвидкий (~100msM SK2 МSK3 Повільніший МSK4s) ≥
Розмір моделі МSK0 ~4МБ МSK2 ~450Мб МСК4

Справа в тому, ефективність: використовувати Tesseract для видобутку документів та текстів (itM SK2s МSK3x швидше з МSK4x меншою модельюMSC5 використовувати Флоренцію-2, коли вам дійсно потрібно зображення розуміння.

Флоренція-2 автоM SK1 завантажує свої моделі MSC2MB) на перший раз, щоб {ModelDirectory}/florence2/.


Як всередині працює трубопровод NER

Трубопровод NER проходить за тими ж трьома кроками, що й в Частина 1: означати → зробити висновок МSK1 розшифрувати. Частка МSK1 проходить через кожну концепцію МSK2 Токенізація WordPiece , Тензорна діагностика ONNX \ , Декодування BIO теги \ МSK5 запевненість Softmax | - з нуля з повним прикладом, який можна побудувати

Тут' це те, що пакет додає за межами ручного підходу

Офсетове стеження

Частина 1's токенізер перетворює текст на токенні IDs 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.StartOffset і EndOffset робота - вони повертаються до точного місця символів у вашому оригінальному тексті

Упевненість-Видобуток розсіяних об 'єктів

Частина 1' декодер генерує всі об 'єктиM SK1 пакети відфільтровуються під час декодування - низький МSK3 шум запевненості ніколи не досягає коду

// 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: Як це працює

Всі моделі завантажуються автоматично після першого використання. Не потрібна ручна інсталяціяM SK1

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 завантаження з HuggingFace (NER modelM SK1 і GitHub (tessdata). Він використовує атомну .tmp шаблон - якщо завантаження перервано , жодних пошкоджених файлів не залишилося позадуM SK2

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

Архітектура

Усе - це одинтон з ліницькою іініціалізацією. дорогі ресурси M SK1ONNX InferenceSession, TesseractEngine, Флоренція -2 модель МSK2 створені один раз при першій використанні і перероблені на весь термін використання

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 для інициалізації. Багато потоків, які запускають службу одночасно при першій користуванні, спричиняють лише один завантаження /завантаження МSK2

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

Репо включає в себе Command-line інструмент, збудований з Спектр.Консоль. Це МSK1 спроектовано як МSK2 вершина успіху " \ \ - просто передайте ваші дані і це працює \

Швидкий старт

# 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. Якщо передувати файл з зображенням , globM SK3 або каталогі МSK4 він запускає OCR MSC5 NER

Три команди

Команда МSK1 Що він робить МSK2 Мотор Швидкість
ner <text> Вирізаємо елементи з тексту BERT NER МSK2ONNXM SK3 МSK4 ~50ms МSK6
ocr <path> ОКР МSK1 NER з зображеннях МSK2 Тесеракт + BERT မ်SK4 мSK5м M
caption <path> Напис зображення МSK1 опціональний OCR МSK2 ФлоренціяM SK3 (ONNX)

Теsseract - це початковий OCR-аналізатор тому що це 's МSK1x швидше і оптимізоване для тексту документу МSK2 Флоренція -2 є для, коли вам потрібно розуміти зображення МСК4 заголовки М СК5 текст сцени M СК6 фото знаків MСК7

Реальний Output

Ось реальний результат тестування 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    │
╰──────┴─────────────┴────────────┴──────────╯

NER з розпізнавачими - об 'єднання BERT-утворів з правилом -на основі видобутку сигналу M SK2

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

БЕРТ знаходить людей, організаціїМSK1 і місцяM SK2 Перепізнавачі фіксують дату та номер телефону - структуровані шаблони, які нейронна мережа не могла б довіряти при виділенні

ОCR з сканованого документа (на листі акціонерів Амазонки , відсканований отвіром

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%

Тесеракт виділяє близько -вербітальний текст з сканованого листа на 89% довіра МSK2, а NER правильно ідентифікує Амазонку

Теsseract проти Флоренції-2: Реальний порівняння

Те ж проскановане листо акціонерів, оброблене обоми двигунами:

МSK0 Тесеракт МSK2ocrner ocrМSK0 Флоренція МSK2 (ocrner caption --ocr)
Швидка МSK0 ~200ms МSK2 ~14s
Точность OCR МSK0 Близько-обговорюваністьMSC2 M SK3 впевненість МSK4 сильно зруйновані, галюциновані фрази
Шляховий текст МSK0 "За останні два роки в Амазонці МSK3 Я ' мав можливість МСК5 ♫ МСк6 MСк7 За останні вісім років у Амазонії М Ск9 Я\ М СК10 мав змогу написати багато розповідей М סК11 електронні листи М ск12 М sк13
Органи НЕР МSK0 Джефф (ПЕр МSK2 Амазонка (ORGM SK4 АWS MSК5ORG), Америка МСК7ЛОКМСК8 МК9 NМК10А РМСК11текст надто заплутаний, щоб бути надійним NERМК12 \МК13
Заголовок МСК0 NМSK1А МSK2 "Paпір з деякими текстами

Флоренція-2 - зоровий модель - вона розуміє сцени , об 'єкти МSK2 і просторові відносини МSK3 Вона ніколи не була розроблена для того, щоб конкурувати з Tesseract в читанні тексту документу | МSK4 | Використовуйте її, коли вам потрібно зображення розуміння ( щоM SK1 на цій фотографії ?), не текст видобуток ( Що в цьому документі сказано

Виход JSON для автоматизації інструментів & LLM

І --json вихідні сигнали, структуровані JSON до stdout з подавленням всіх записів - розроблені для підключення до інших інструментів , LLM функція вызову , або скриптів автоматизації МSK3

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 та агентів. LLM може викликати ocrner ner "..." --json, розшифровує відповідь JSON , і пояснює структуру об 'єктів jq, fed to an agent framework , or read from any language

# 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

Щоб заpisać до файлу замість, використовувати -o з .json rozszerzenie - ті самі структуровані дані , написані на дискіM SK2

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

Флаг МSK1 Застосовується до МSK2 Описание
--json ner, ocr, caption Структурований JSON для stdout --quiet, пригнічує всі журнальні дані
-c ner, ocr Minimalний початковий рівень впевненості компанії
--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
-r, --recognizers ner, ocr Ввімкніть правилоМSK1подібне вилучення МСК2стані datumиМ СК3 цифриM СК4 यूआरएलи МСК5 телефони М СК6 електронні листи М סК7 IP-адреса М S К8 М ็ С К9
--culture ner, ocr Культура розпізнавання en-us, de-de (по замовчуваннюM SK1 en-us)
--brief caption Створити коротший , менш детальний заголовок МSK2
-q, --quiet ner, ocr, caption Тихий режим МSK1знижений вихід з консолі МSK2
-o ner, ocr, caption вихідний шлях файлу (.txt, .md, .json)
--ocr caption Далі запустите OCR під час команди з заголовком
--ner caption Вирізає NER з тексту OCR ( упрощує --ocr)

Продукція: Квантовані моделі і щоM SK1 Наступне

На даний момент модель NER має повну protectai/bert-base-NER-onnx (~430MBM SK1 Для багатьох випадків використання - особливо на ресурсі МSK3 при обмежених машинах або при обробці великих об 'ємів кількісно (INTM SK1 версія тієї ж моделі була б значно швидша з мінімальним втратою точності

Runtime ONNX підтримує INT8 квантування з-за коробки ,, що зазвичай зменшує розмір моделі на M SK2x і покращує швидкість виведення на \2-3x на процесорі. Це на карті NerModelRepo опція конфігурації вже підтримує вказування на іншу HuggingFace репо, тому, коли ви опублікуєте кількісну модель, ви'd просто змінитеM SK2

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

Архітектура розроблена для цього. - замінити модель.


Найвизначніша картина: Де це підходить

Цей пакет - одноступенча труба: один OCR двигун , один NER-модель МSK2 один опціональний візуальний модель

Для більш складних сценаріїв - читайте текст з будь-що ( рукописні нотатки , фотографії білих таблиць МSK2 низький M SK3 високоякісні камерні знімки ), з мультиплікатором МSK5 консенсус OCR двигуна прозораРАГ. Те, що ' це місце, де проживає виробництво МSK2 сорта МСК3 багаторазовий М СК4 фазова версія цієї роботи MСК5

Що's НаступнеM SK1 Мультимоdal LLM

Флоренція-2 є теперішньою межою для локального бачення в цьому пакетіM SK1 Наступним логічним кроком є мультимодальний LLM - модель, яка може бачити зображення і про причину цього в природному мові. Замість відокремленого OCR MSC1 NER крокиM SK2 ви' надсилаєте зображення безпосередньо і запитуєте про структурне виділення

Ось як би 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"

Малі локальні мультиmodaльні моделі (подібні Phi-3.5-vision або ЛЛАВА) стають достатньо добрими для цього . Торгівля МSK2off завжди одна й та сама МSK3 більша модель Хіба = розумніша, але повільніша \ . Правильний вибір залежить від вашого бюджету на затримку і вимог до точності

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

Кожна шкала додає можливостей за рахунок вартості розміру та затримки. У даний момент пакет охоплює тривиміри M SK1 шкало МSK2 це місце, де мультиmodaльні LLM приходять в МSK3 і де прозораРАГ це заголовок.


Ресурс

Цей пакет:

Частина 1:

Відлежність:

Подібні статті:

logo

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