如何在 C# 中除錯 OCR辨識與文字辨識問題

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

IronOCR可讓您從來源偵測 OCR辨識錯誤,評估單字和字元層級的辨識質量,並即時監控長時間運行的作業。內建工具(例如診斷文件日誌記錄、類型化異常層次結構、每個結果的置信度評分以及 OcrProgress 事件)支援生產流程中的這些工作流程。

本指南將逐一介紹以下工作範例:啟用診斷日誌記錄、處理類型異常、使用置信度分數驗證輸出、即時監控作業進度以及隔離批次管道中的錯誤。

快速入門:啟用完整 OCR 診斷日誌記錄

在第一次呼叫 Read 之前,在 Installation 類別上設定 LogFilePathLogging模式。 只需兩個屬性即可將 Tesseract 初始化、語言包載入和處理詳細資訊擷取到日誌檔案中。

  1. 使用NuGet套件管理器安裝https://www.nuget.org/packages/IronOcr

    PM > Install-Package IronOcr
  2. 複製並運行這段程式碼。

    IronOcr.Installation.LogFilePath = "ocr.log"; IronOcr.Installation.Logging模式 = IronOcr.Installation.Logging模式s.All;
  3. 部署到您的生產環境進行測試

    今天就在您的專案中開始使用免費試用IronOCR

    arrow pointer


如何啟用診斷日誌記錄?

Installation類別公開了三個日誌記錄控制項。 在呼叫任何 Read 方法之前設定這些參數。

:path=/static-assets/ocr/content-code-examples/how-to/debugging-enable-logging.cs
using IronOcr;

// Write logs to a specific file
Installation.LogFilePath = "logs/ocr_diagnostics.log";

// Enable all logging channels: file + debug output
Installation.LoggingMode = Installation.LoggingModes.All;

// Or pipe logs into your existing ILogger pipeline
Installation.CustomLogger = myLoggerInstance;
Imports IronOcr

' Write logs to a specific file
Installation.LogFilePath = "logs/ocr_diagnostics.log"

' Enable all logging channels: file + debug output
Installation.LoggingMode = Installation.LoggingModes.All

' Or pipe logs into your existing ILogger pipeline
Installation.CustomLogger = myLoggerInstance
$vbLabelText   $csharpLabel

Logging模式 接受來自Logging模式s枚舉的標誌值:

表 1:日誌模式選項
模式目標輸出用例
已停用生產環境搭配外部監控
除錯IDE 除錯輸出視窗在地化開發
檔案LogFilePath伺服器端日誌收集
全部除錯 + 檔案完整診斷擷取

CustomLogger 屬性支援任何 Microsoft.Extensions.Logging.ILogger 實現,讓您可以將 OCR 診斷資訊定向到 Serilog、NLog 或管道中的其他結構化日誌接收器。使用ClearLogFiles可清除運行之間累積的日誌資料。

日誌記錄就緒後,下一步是了解IronOCR可能拋出哪些異常情況以及如何處理每種異常。

IronOCR會拋出哪些異常?

IronOCR在IronOcr.例外s命名空間下定義了類型化異常。 與其進行一刀切式攔截,不如專門針對這些故障類型進行攔截,這樣可以將每種故障類型路由到正確的修復路徑。

表 2: IronOCR異常參考
例外共同事業修正
IronOcrInput例外損壞或不支援的圖片/PDF在載入 OcrInput 之前驗證檔案
IronOcrProduct例外OCR 執行期間發生內部引擎錯誤啟用記錄功能、檢查記錄輸出、更新至最新 NuGet 版本
IronOcrDictionary例外缺少或損毀的 .traineddata 語言檔案重新安裝語言包NuGet或設定LanguagePackDirectory
IronOcrNative例外原生 C++ 互通失敗安裝 Visual C++ 再發行套件;檢查 AVX 支援
IronOcrLicensing例外缺少或已過期的授權金鑰在呼叫Read之前設定LicenseKey
LanguagePack例外未在預期路徑中找到語言套件請檢查 LanguagePackDirectory 或重新安裝 NuGet 語言套件
IronOcrAssemblyVersionMismatch例外部分更新後組件版本不匹配清除 NuGet 快取、還原套件,並確保所有 IronOCR 套件版本一致

使用下列 try-catch 區塊分別處理每種異常類型,套用異常過濾器進行條件日誌記錄。

輸入

IronOCR Solutions 向 Acme Corporation 開立的單頁供應商發票,透過 LoadPdf 載入至 OcrInput 中。 它包括四項內容、稅金和總計——足夠豐富的文本種類,可以給每個異常處理程序一個現實的練習。

invoice_scan.pdf:供應商發票(#INV-2024-7829),用於依序示範每個類型化的異常處理程序。

:path=/static-assets/ocr/content-code-examples/how-to/debugging-exception-handling.cs
using IronOcr;
using IronOcr.Exceptions;

var ocr = new IronTesseract();

try
{
    using var input = new OcrInput();
    input.LoadPdf("invoice_scan.pdf");

    OcrResult result = ocr.Read(input);
    Console.WriteLine($"Text: {result.Text}");
    Console.WriteLine($"Confidence: {result.Confidence:P1}");
}
catch (IronOcrInputException ex)
{
    // File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}");
}
catch (IronOcrDictionaryException ex)
{
    // Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}");
}
catch (IronOcrNativeException ex) when (ex.Message.Contains("AVX"))
{
    // CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}");
}
catch (IronOcrLicensingException)
{
    Console.Error.WriteLine("License key is missing or invalid.");
}
catch (IronOcrProductException ex)
{
    // Catch-all for other IronOCR engine errors
    Console.Error.WriteLine($"OCR engine error: {ex.Message}");
    Console.Error.WriteLine($"Stack trace: {ex.StackTrace}");
}
Imports IronOcr
Imports IronOcr.Exceptions

Dim ocr As New IronTesseract()

Try
    Using input As New OcrInput()
        input.LoadPdf("invoice_scan.pdf")

        Dim result As OcrResult = ocr.Read(input)
        Console.WriteLine($"Text: {result.Text}")
        Console.WriteLine($"Confidence: {result.Confidence:P1}")
    End Using
Catch ex As IronOcrInputException
    ' File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}")
Catch ex As IronOcrDictionaryException
    ' Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}")
Catch ex As IronOcrNativeException When ex.Message.Contains("AVX")
    ' CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}")
Catch ex As IronOcrLicensingException
    Console.Error.WriteLine("License key is missing or invalid.")
Catch ex As IronOcrProductException
    ' Catch-all for other IronOCR engine errors
    Console.Error.WriteLine($"OCR engine error: {ex.Message}")
    Console.Error.WriteLine($"Stack trace: {ex.StackTrace}")
End Try
$vbLabelText   $csharpLabel

輸出

成功輸出

發票載入正常,引擎傳回字元數和置信度評分。

終端輸出顯示成功讀取 invoice_scan.pdf 的 OCR 字元集,包括字元數和置信度。

輸出失敗

終端輸出顯示載入缺少的 PDF 檔案時拋出異常

按從最具體到最一般的順序排列捕獲塊。 when 子句在 IronOcrNative例外 過濾器中用於檢測與 AVX 相關的故障,而不會捕獲不相關的本機錯誤。 每個處理程序都會記錄異常訊息; 兜底塊也會捕捉堆疊追蹤訊息,以便進行事後分析。

捕捉正確的異常可以告訴你哪裡出了問題,但並不能告訴你引擎在成功運行時表現如何。 為此,可以使用置信度評分。

如何使用置信度分數驗證 OCR 輸出?

每個OcrResult都公開一個 Confidence 屬性,該屬性的值介於 0 和 1 之間,表示引擎對所有已識別字元的統計確定性平均值。 您可以在結果層次結構的每個層級存取此功能:文件頁面段落單字字元

使用閾值門控模式防止低品質結果向下游傳播。

輸入

透過 LoadImage 載入的熱感收據,包含明細項目、折扣、總計和條碼。 它的窄寬度、等寬字體和淡淡的印刷字體使其成為對每個單字置信度閾值進行實際壓力測試的理想工具。

這是FoodMart超市的熱感收據樣本,顯示了詳細的購買項目、總計和獎勵積分,用作OCR輸入。

receipt.png:用於示範閾值閘控置信度驗證和逐字準確度深入分析的熱敏收據掃描。

:path=/static-assets/ocr/content-code-examples/how-to/debugging-confidence-scoring.cs
using IronOcr;

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

OcrResult result = ocr.Read(input);
double confidence = result.Confidence;

Console.WriteLine($"Overall confidence: {confidence:P1}");

// Threshold-gated decision
if (confidence >= 0.90)
{
    Console.WriteLine("ACCEPT — high confidence, processing result.");
    ProcessResult(result.Text);
}
else if (confidence >= 0.70)
{
    Console.WriteLine("FLAG — moderate confidence, queuing for review.");
    QueueForReview(result.Text, confidence);
}
else
{
    Console.WriteLine("REJECT — low confidence, logging for investigation.");
    LogRejection("receipt.png", confidence);
}

// Drill into per-page and per-word confidence for diagnostics
foreach (var page in result.Pages)
{
    Console.WriteLine($"  Page {page.PageNumber}: {page.Confidence:P1}");

    var lowConfidenceWords = page.Words
        .Where(w => w.Confidence < 0.70)
        .ToList();

    foreach (var word in lowConfidenceWords)
    {
        Console.WriteLine($"    Low-confidence word: \"{word.Text}\" ({word.Confidence:P1})");
    }
}
Imports IronOcr

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

    Dim result As OcrResult = ocr.Read(input)
    Dim confidence As Double = result.Confidence

    Console.WriteLine($"Overall confidence: {confidence:P1}")

    ' Threshold-gated decision
    If confidence >= 0.9 Then
        Console.WriteLine("ACCEPT — high confidence, processing result.")
        ProcessResult(result.Text)
    ElseIf confidence >= 0.7 Then
        Console.WriteLine("FLAG — moderate confidence, queuing for review.")
        QueueForReview(result.Text, confidence)
    Else
        Console.WriteLine("REJECT — low confidence, logging for investigation.")
        LogRejection("receipt.png", confidence)
    End If

    ' Drill into per-page and per-word confidence for diagnostics
    For Each page In result.Pages
        Console.WriteLine($"  Page {page.PageNumber}: {page.Confidence:P1}")

        Dim lowConfidenceWords = page.Words _
            .Where(Function(w) w.Confidence < 0.7) _
            .ToList()

        For Each word In lowConfidenceWords
            Console.WriteLine($"    Low-confidence word: ""{word.Text}"" ({word.Confidence:P1})")
        Next
    Next
End Using
$vbLabelText   $csharpLabel

輸出

終端輸出顯示收據影像的置信度評分、接受/標記/拒絕決策,以及逐字低置信度細分資訊。

此模式對於 OCR 銜接至資料輸入、發票處理或合規工作流程的處理鏈至關重要。 逐字分析可以準確地確定來源影像的哪些區域導致了影像品質下降; 然後您可以套用影像品質濾鏡方向校正並重新處理。 若要深入了解信心分數,請參閱信心等級操作指南

對於需要長期從事的工作來說,光有自信是不夠的。 你還需要知道引擎是否仍在運行,而這正是 OcrProgress 事件的作用所在。

如何即時監控OCR辨識進度?

對於多頁文檔,OcrProgress 事件在 IronTesseract 上會在每個頁面完成後觸發。 OcrProgressEventArgs 物件公開進度百分比、已使用時間、總頁數和已完成頁數。 此範例使用這份三頁的季度報告作為輸入:一份結構化的商業文檔,包括執行摘要、收入明細和營運指標。

輸入

透過 LoadPdf 載入的 2024 年第一季三頁財務報告。 第一頁涵蓋了執行摘要和 KPI 指標,第二頁包含按產品線和地區劃分的收入表,第三頁涵蓋了營運處理量——每種頁麵類型都會產生不同的每頁時間,您可以在進度回調中觀察到。

quarterly_report.pdf:2024 年第一季三頁財務報告(執行摘要、收入明細、營運指標),用於示範每頁的即時`OcrProgress`回呼。

:path=/static-assets/ocr/content-code-examples/how-to/debugging-progress-monitoring.cs
using IronOcr;

var ocr = new IronTesseract();

ocr.OcrProgress += (sender, e) =>
{
    Console.WriteLine(
        $"[OCR] {e.ProgressPercent}% complete | " +
        $"Page {e.PagesComplete}/{e.TotalPages} | " +
        $"Elapsed: {e.Duration.TotalSeconds:F1}s"
    );
};

using var input = new OcrInput();
input.LoadPdf("quarterly_report.pdf");

OcrResult result = ocr.Read(input);
Console.WriteLine($"Finished in {result.Pages.Count()} pages, confidence: {result.Confidence:P1}");
Imports IronOcr

Dim ocr = New IronTesseract()

AddHandler ocr.OcrProgress, Sub(sender, e)
    Console.WriteLine(
        $"[OCR] {e.ProgressPercent}% complete | " &
        $"Page {e.PagesComplete}/{e.TotalPages} | " &
        $"Elapsed: {e.Duration.TotalSeconds:F1}s"
    )
End Sub

Using input As New OcrInput()
    input.LoadPdf("quarterly_report.pdf")

    Dim result As OcrResult = ocr.Read(input)
    Console.WriteLine($"Finished in {result.Pages.Count()} pages, confidence: {result.Confidence:P1}")
End Using
$vbLabelText   $csharpLabel

輸出

終端輸出顯示了三頁 PDF 檔案中每頁的 OcrProgress 事件回調次數、完成百分比和耗時。

將此事件連接到您的日誌記錄基礎架構,以追蹤 OCR 作業持續時間並偵測停滯情況。 如果經過的時間超過閾值而進度百分比沒有增加,則管道可以標記該作業以進行調查。 這對於批次處理 PDF 特別有用,因為單一頁面的格式錯誤就可能導致整個工作停滯。

進度監控顯示執行狀態,但如果沒有隔離,檔案級故障仍然可能導致整個批次提前停止。

如何處理批量 OCR 流程中的錯誤?

在生產環境中,單一檔案故障不應該導致整批停止運作。 按文件隔離錯誤,記錄故障及其上下文,並在最後產生總結報告。 此範例處理一個包含發票、採購訂單和服務合約的掃描文件資料夾,Plus故意損壞的文件以觸發錯誤路徑。 下面展示的是一個代表性的例子:

輸入

傳遞給 Directory.GetFiles 的 PDF 資料夾包含:一張發票、一份採購訂單、一份服務合約以及一個故意損壞的文件。以下兩個範例展示了該流程在單次運行中處理的文件類型。

:path=/static-assets/ocr/content-code-examples/how-to/debugging-batch-pipeline.cs
using IronOcr;
using IronOcr.Exceptions;

var ocr = new IronTesseract();
Installation.LogFilePath = "batch_debug.log";
Installation.LoggingMode = Installation.LoggingModes.File;

string[] files = Directory.GetFiles("scans/", "*.pdf");
int succeeded = 0, failed = 0;
double totalConfidence = 0;
var failures = new List<(string File, string Error)>();

foreach (string file in files)
{
    try
    {
        using var input = new OcrInput();
        input.LoadPdf(file);

        OcrResult result = ocr.Read(input);
        totalConfidence += result.Confidence;
        succeeded++;

        Console.WriteLine($"OK: {Path.GetFileName(file)} — {result.Confidence:P1}");
    }
    catch (IronOcrInputException ex)
    {
        failed++;
        failures.Add((file, $"Input error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (IronOcrProductException ex)
    {
        failed++;
        failures.Add((file, $"Engine error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (Exception ex)
    {
        failed++;
        failures.Add((file, $"Unexpected: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.GetType().Name}: {ex.Message}");
    }
}

// Summary report
Console.WriteLine($"\n--- Batch Summary ---");
Console.WriteLine($"Total: {files.Length} | Passed: {succeeded} | Failed: {failed}");
if (succeeded > 0)
    Console.WriteLine($"Average confidence: {totalConfidence / succeeded:P1}");

foreach (var (f, err) in failures)
    Console.WriteLine($"  {Path.GetFileName(f)}: {err}");
Imports IronOcr
Imports IronOcr.Exceptions
Imports System.IO

Dim ocr As New IronTesseract()
Installation.LogFilePath = "batch_debug.log"
Installation.LoggingMode = Installation.LoggingModes.File

Dim files As String() = Directory.GetFiles("scans/", "*.pdf")
Dim succeeded As Integer = 0
Dim failed As Integer = 0
Dim totalConfidence As Double = 0
Dim failures As New List(Of (File As String, Error As String))()

For Each file As String In files
    Try
        Using input As New OcrInput()
            input.LoadPdf(file)

            Dim result As OcrResult = ocr.Read(input)
            totalConfidence += result.Confidence
            succeeded += 1

            Console.WriteLine($"OK: {Path.GetFileName(file)} — {result.Confidence:P1}")
        End Using
    Catch ex As IronOcrInputException
        failed += 1
        failures.Add((file, $"Input error: {ex.Message}"))
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}")
    Catch ex As IronOcrProductException
        failed += 1
        failures.Add((file, $"Engine error: {ex.Message}"))
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}")
    Catch ex As Exception
        failed += 1
        failures.Add((file, $"Unexpected: {ex.Message}"))
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.GetType().Name}: {ex.Message}")
    End Try
Next

' Summary report
Console.WriteLine(vbCrLf & "--- Batch Summary ---")
Console.WriteLine($"Total: {files.Length} | Passed: {succeeded} | Failed: {failed}")
If succeeded > 0 Then
    Console.WriteLine($"Average confidence: {totalConfidence / succeeded:P1}")
End If

For Each failure In failures
    Console.WriteLine($"  {Path.GetFileName(failure.File)}: {failure.Error}")
Next
$vbLabelText   $csharpLabel

輸出

終端輸出顯示批次管道的結果,包括每個檔案的字元數、置信度分數、一個來自損壞 PDF 的錯誤以及摘要行。

外部 catch 區塊處理意外錯誤,包括共享儲存上的網路逾時、權限問題或大型 TIFF 檔案記憶體不足的情況。 每次失敗都會將檔案路徑和錯誤訊息記錄在摘要中,同時迴圈會繼續處理剩餘的檔案。 位於 batch_debug.log 的日誌檔案記錄了觸發內部診斷的任何檔案的引擎級詳細資訊。

對於服務或 Web 應用程式中的非阻塞執行, IronOCR支援ReadAsync ,它使用相同的 try-catch 結構。

如果管道運行沒有錯誤,但提取的文字仍然錯誤,那麼根本原因幾乎總是圖像品質而不是程式碼。 以下是解決之道。

如何調試OCR辨識準確率?

如果置信度分數持續偏低,則問題出在來源影像上,而不是 OCR 引擎。 IronOCR 提供了IronOCR工具來解決這個問題:

針對部署特定問題, IronOCR維護了Azure FunctionsDocker 和 Linux的專門故障排除指南以及一般環境設定指南。

接下來我該去哪裡?

既然您已經了解如何在運行時調試IronOCR ,請探索以下內容:

對於生產使用,請記得取得授權以移除水印並存取完整功能。

常見問題解答

What are the common issues when debugging OCR in C#?

Common issues include incorrect OCR results, low confidence scores, and unexpected exceptions. IronOCR provides tools like logging and confidence scoring to help identify and resolve these issues.

How does IronOCR assist with error handling in C#?

IronOCR offers typed exceptions and detailed error messages, which aid in understanding and handling errors effectively during OCR operation in C# applications.

What logging features does IronOCR provide for debugging?

IronOCR includes built-in logging capabilities that help track OCR processes and identify potential issues by logging detailed information about the OCR operations.

How can confidence scoring improve OCR results?

Confidence scoring in IronOCR helps determine the accuracy of the recognized text, allowing developers to focus on low-confidence areas and improve the OCR results.

Can I track the progress of OCR tasks using IronOCR?

Yes, IronOCR provides progress tracking features that enable developers to monitor the status and duration of OCR tasks, facilitating better resource management and performance optimization.

What try-catch patterns are recommended for OCR error handling?

IronOCR suggests using production-ready try-catch patterns to handle exceptions gracefully, ensuring that OCR applications remain robust and maintainable.

How can IronOCR's built-in tools enhance OCR debugging?

IronOCR's tools, such as logging, typed exceptions, and confidence scoring, provide comprehensive support for identifying and resolving issues, thus enhancing the debugging process.

Why is error logging important in OCR applications?

Error logging is crucial as it provides insight into what went wrong during OCR processing, allowing developers to quickly diagnose and fix issues in their applications.

What role do typed exceptions play in debugging IronOCR?

Typed exceptions in IronOCR provide specific error information, making it easier for developers to understand the nature of the problem and apply appropriate solutions during debugging.

How can developers benefit from IronOCR's debugging features?

Developers can leverage IronOCR's debugging features to efficiently troubleshoot issues, enhance application stability, and improve the overall quality of the OCR results.

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。

準備好開始了嗎?
Nuget 下載 5,570,591 | 版本: 2026.4 剛剛發布
Still Scrolling Icon

還在捲動嗎?

想要快速證明? PM > Install-Package IronOcr
執行範例 觀看您的圖片變成可搜尋的文字。