C# 中的单词和字符 OCR 数据(坐标、置信度、边界框)

This article was translated from English: Does it need improvement?
Translated
View the article in English

对文档进行 OCR 处理后,仅靠提取的文本通常是不够的。 若要定位页面上的特定值、排除低质量检测结果,或在多栏布局中重建自然的阅读顺序,您需要单词坐标、页码、区域索引和置信度评分。

WordsCharacters 集合公开了这些数据。 对于布局感知文档的 ReadDocumentAdvanced() 和用于相机输入的 ReadPhoto() 返回的颗粒度与标准的 OcrResult.Words 集合中的一致。

本指南将详细介绍五种常见模式:迭代处理WORD数据、重建阅读顺序、按置信度过滤、在字符级别进行处理,以及通过边界框裁剪源图像。

立即开始 30天试用,在您的开发流程中测试这些资源库。

NuGet 使用 NuGet 安装

PM >  Install-Package IronOcr

IronOCR 上查看 NuGet 快速安装。超过 1000 万次下载,它正以 C# 改变 PDF 开发。 您也可以下载 DLLWindows 安装程序

快速入门:从 OCR 结果中读取 WORD 和字符数据

调用 ReadDocumentAdvanced (或 ReadPhoto) 并迭代 result.Words,以在几行代码中获得每个识别的单词及其坐标、页码和置信度分数。

  1. 使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronOcr

    PM > Install-Package IronOcr
  2. 复制并运行这段代码。

    var result = new IronTesseract().ReadDocumentAdvanced(new OcrInput("scan.png"));
    foreach (var word in result.Words)
        Console.WriteLine($"{word.Text} @ ({word.X},{word.Y}) conf:{word.RegionConfidence:P0}");
  3. 部署到您的生产环境中进行测试

    通过免费试用立即在您的项目中开始使用IronOCR

    arrow pointer


如何根据坐标和置信度迭代WORD?

Words 集合返回跨每一页检测到的每个单词。 每个条目(即 AdvancedWordAdvancedCharacter,两者均继承自 AdvancedOcrElement)公开其文本、像素坐标、尺寸、所属页、标识哪个检测到的文本块包含它的区域索引,以及该区域的置信分数。

:path=/static-assets/ocr/content-code-examples/how-to/read-document-advanced-iterate-words.cs
using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("receipt.png");

var result = ocr.ReadDocumentAdvanced(input);

foreach (var word in result.Words)
{
    Console.WriteLine(
        $"Page {word.PageNumber} | " +
        $"Region {word.RegionIndex} | " +
        $"'{word.Text}' | " +
        $"Position: ({word.X}, {word.Y}) | " +
        $"Size: {word.Width}x{word.Height} | " +
        $"Confidence: {word.RegionConfidence:P1}"
    );
}

// ToString() override for diagnostic logging
Console.WriteLine(result.Words.First().ToString());
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("receipt.png")

    Dim result = ocr.ReadDocumentAdvanced(input)

    For Each word In result.Words
        Console.WriteLine(
            $"Page {word.PageNumber} | " &
            $"Region {word.RegionIndex} | " &
            $"'{word.Text}' | " &
            $"Position: ({word.X}, {word.Y}) | " &
            $"Size: {word.Width}x{word.Height} | " &
            $"Confidence: {word.RegionConfidence:P1}"
        )
    Next
End Using

' ToString() override for diagnostic logging
Console.WriteLine(result.Words.First().ToString())
$vbLabelText   $csharpLabel

提示PageNumber 是从1开始计数的:第一页是 1,而不是 0。 这与大多数采用零基索引的 .NET 集合不同。 RegionIndex 遵循标准的0计数惯例。]] )}]

要将坐标传递给绘图或裁剪API,请使用BoundingBox属性。 它将位置和大小打包成单个IronSoftware.Drawing.Rectangle

如何重建阅读顺序?

在多列布局中,Words 集合的迭代顺序与页面上的视觉阅读顺序不一致。 WORD按检测到的区域分组,因此列和表格单元格的返回顺序可能不按原序排列。

为重建自然的自上而下、从左至右的排列顺序,请先按 Y 坐标对集合进行排序,然后在每行内按 X 坐标排序。通过设置较小的 Y 坐标容差,可将位于同一基线上的 WORD 归为一组。

:path=/static-assets/ocr/content-code-examples/how-to/read-document-advanced-reading-order.cs
using IronOcr;
using System.Linq;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("multi-column-doc.png");

var result = ocr.ReadDocumentAdvanced(input);

int targetPage = 1;
int lineThreshold = 10; // pixel tolerance for grouping same-line words

// Sort by line (Y), then left-to-right (X)
var pageWords = result.Words
    .Where(w => w.PageNumber == targetPage)
    .OrderBy(w => w.Y / lineThreshold)
    .ThenBy(w => w.X)
    .ToList();

foreach (var word in pageWords)
{
    Console.Write($"{word.Text} ");
}
Console.WriteLine();
Imports IronOcr
Imports System.Linq

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("multi-column-doc.png")

    Dim result = ocr.ReadDocumentAdvanced(input)

    Dim targetPage As Integer = 1
    Dim lineThreshold As Integer = 10 ' pixel tolerance for grouping same-line words

    ' Sort by line (Y), then left-to-right (X)
    Dim pageWords = result.Words _
        .Where(Function(w) w.PageNumber = targetPage) _
        .OrderBy(Function(w) w.Y / lineThreshold) _
        .ThenBy(Function(w) w.X) _
        .ToList()

    For Each word In pageWords
        Console.Write($"{word.Text} ")
    Next
    Console.WriteLine()
End Using
$vbLabelText   $csharpLabel

调整 lineThreshold 以匹配您的文档:10-15像素适用于标准12pt文本在300 DPI下。 对于较大的标题或手写输入内容,可适当放宽翻译标准。 此模式在多栏页面和表格单元格内部特别有用,引擎会将每列或每个单元格识别为独立区域。

如何过滤低置信度的词汇?

要在他们到达您的数据库、搜索索引或下游提取之前排除低质量检测,请按 RegionConfidence 筛选集合。 评分范围为 0.0 至 1.0,数值越高表示对检测文本的识别信心越强。

:path=/static-assets/ocr/content-code-examples/how-to/read-document-advanced-confidence-filter.cs
using IronOcr;
using System.Linq;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("noisy-scan.png");

var result = ocr.ReadDocumentAdvanced(input);

double threshold = 0.75;

var highConfidenceWords = result.Words
    .Where(w => w.RegionConfidence >= threshold)
    .ToList();

var lowConfidenceWords = result.Words
    .Where(w => w.RegionConfidence < threshold)
    .ToList();

Console.WriteLine($"Accepted: {highConfidenceWords.Count} words");
Console.WriteLine($"Rejected: {lowConfidenceWords.Count} words");

// Log rejected words for manual review
foreach (var word in lowConfidenceWords)
{
    Console.WriteLine(
        $"  LOW CONF: '{word.Text}' at ({word.X},{word.Y}) — {word.RegionConfidence:P1}"
    );
}
Imports IronOcr
Imports System.Linq

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("noisy-scan.png")

    Dim result = ocr.ReadDocumentAdvanced(input)

    Dim threshold As Double = 0.75

    Dim highConfidenceWords = result.Words _
        .Where(Function(w) w.RegionConfidence >= threshold) _
        .ToList()

    Dim lowConfidenceWords = result.Words _
        .Where(Function(w) w.RegionConfidence < threshold) _
        .ToList()

    Console.WriteLine($"Accepted: {highConfidenceWords.Count} words")
    Console.WriteLine($"Rejected: {lowConfidenceWords.Count} words")

    ' Log rejected words for manual review
    For Each word In lowConfidenceWords
        Console.WriteLine($"  LOW CONF: '{word.Text}' at ({word.X},{word.Y}) — {word.RegionConfidence:P1}")
    Next
End Using
$vbLabelText   $csharpLabel

对于质量参差不齐的扫描件(部分区域清晰,其他部分模糊),这可防止低置信度的输出结果进入下游系统。 为了提高源图像的置信度评分,图像预处理滤波器(去倾斜、去噪、二值化)会在应用阈值之前提升图像质量。

如何在字符级别进行迭代?

对于OCR验证叠加、字符级与真值的区别分析,或在表单字段上的精确空间分析,请使用 Characters 集合。 它镜像Words,但解析到单个字符。

:path=/static-assets/ocr/content-code-examples/how-to/read-document-advanced-characters.cs
using IronOcr;

var ocr = new IronTesseract();
using var input = new OcrInput();
input.LoadImage("form-field.png");

var result = ocr.ReadDocumentAdvanced(input);

foreach (var ch in result.Characters)
{
    Console.WriteLine(
        $"'{ch.Text}' | " +
        $"Box: ({ch.X}, {ch.Y}, {ch.Width}, {ch.Height}) | " +
        $"Page {ch.PageNumber}"
    );
}

// ToString() override provides diagnostic-friendly output
Console.WriteLine(result.Characters.First().ToString());
Imports IronOcr

Dim ocr As New IronTesseract()
Using input As New OcrInput()
    input.LoadImage("form-field.png")

    Dim result = ocr.ReadDocumentAdvanced(input)

    For Each ch In result.Characters
        Console.WriteLine($"'{ch.Text}' | Box: ({ch.X}, {ch.Y}, {ch.Width}, {ch.Height}) | Page {ch.PageNumber}")
    Next

    ' ToString() override provides diagnostic-friendly output
    Console.WriteLine(result.Characters.First().ToString())
End Using
$vbLabelText   $csharpLabel

[[i:(WordsCharacters 都是被懒加载并缓存的。 首次访问将触发计算; 后续访问将返回缓存结果,因此第二次迭代无需任何成本。