如何在C#中除錯OCR

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

IronOCR能夠在來源中偵測OCR失敗,在字詞層級上評估識別質量,並實時監控長時任務。內建的工具如診斷文件記錄、型別化的異常層次結構、每個結果的信心評分以及OcrProgress事件支援這些生產流程。

本指南提供了每個工作範例:啟用診斷日誌記錄、處理型別異常、使用信心分數驗證輸出、實時監控作業進度,並在批量管道中隔離錯誤。

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

在第一次呼叫Read之前,於Installation類別上設置LogFilePathLoggingMode。 只需兩個屬性即可將Tesseract初始化、語言包載入和處理細節記錄到日誌文件中。

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

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

    IronOcr.Installation.LogFilePath = "ocr.log"; IronOcr.Installation.LoggingMode = IronOcr.Installation.LoggingModes.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

LoggingMode接受LoggingModes列舉中的旗幟值:

表1:LoggingModes選項
模式輸出目標用例
None禁用與外部監控的生產環境
DebugOutputWindowIDE除錯輸出窗口本地開發
FileLogFilePath伺服器端日誌集合
AllDebugOutputWindow + File全面捕獲診斷

CustomLogger屬性支援任何Microsoft.Extensions.Logging.ILogger實現,允許您將OCR診斷引導至Serilog、NLog或管道中的其他結構化日誌接收器。使用ClearLogFiles來刪除在運行過程中累積的日誌資料。

有了日誌記錄,下一步是了解IronOCR可以拋出的異常以及如何處理每個異常。

IronOCR拋出哪些異常?

IronOCR在IronOcr.Exceptions 命名空間下定義了型別化的異常。 具體捕獲這些,而不是一個全面的異常捕獲塊,可以讓您將每個失敗型別引導到正確的修復路徑。

表2:IronOCR異常參考
異常常見原因修復方法
IronOcrInputException損壞或不支持的圖像/PDF在載入OcrInput之前驗證文件
IronOcrProductExceptionOCR執行期間的內部引擎錯誤啟用日誌記錄,檢查日誌輸出,更新到最新的NuGet版本
IronOcrDictionaryException缺少或損壞的.traineddata 語言文件重新安裝語言包NuGet或設置LanguagePackDirectory
IronOcrNativeException本地C++互操作失敗安裝Visual C++ Redistributable;檢查AVX支持
IronOcrLicensingException缺少或過期的授權金鑰在呼叫Read之前設置LicenseKey
LanguagePackException找不到語言包於預期路徑驗證LanguagePackDirectory或重新安裝NuGet語言包
IronOcrAssemblyVersionMismatchException部分更新後不匹配的程式集版本清除NuGet快取,還原包,確保所有IronOCR包一致

使用以下try-catch塊來單獨處理每個異常型別,並應用異常過濾器來條件地記錄異常。

輸入

從IronOCR解決方案到Acme Corporation的一頁供應商發票,經由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文件時拋出的異常

從最具體到最泛泛的順序排列捕捉塊。 IronOcrNativeException上的when子句篩選與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進程?

對於多頁文件,IronTesseract上的OcrProgress事件會在每頁完成後觸發。 OcrProgressEventsArgs物件暴露進度百分比、經過時間、總頁數和完成頁數。 例子使用了該三頁季度報告作為輸入:結構化業務文件涵蓋執行摘要、收入細分和運營指標。

輸入

一份經由LoadPdf載入的三頁Q1 2024財務報告。 第一頁涵蓋KPI指標的執行摘要,第二頁按產品線和區域提供收入表,第三頁涵蓋運營處理量 — 每種頁面型別生成您可以觀察到的進度回調中的不同逐頁計時。

quarterly_report.pdf:三頁Q1 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

輸出

終端輸出顯示每頁的OcrProgress事件回調,包含完成百分比和三頁PDF的經過時間

將此事件整合到您的日誌記錄架構中以跟蹤OCR作業的持續時間並檢測停頓。 如果經過時間超過閾值而進度百分比未前進,管道可以標記該作業以進行調查。 這對批量PDF處理特別有用,因為單個錯誤頁面可以使整個作業停止。

進度監控顯示執行狀態,但文件級的失敗如果不加以隔離仍可能使整個批次停止。

我如何處理批次OCR管道中的錯誤?

在生產環境中,單個文件錯誤不應該中止整個批量。 對每個文件隔離錯誤,記錄上下文中的失敗,並在最後生成總結報告。 該範例處理包含發票、訂購單、服務合約和一個故意損壞的文件以觸發錯誤路徑的掃描文件夾。 下面顯示了一個具有代表性的範例:

輸入

一個傳遞給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的一個錯誤和總結行

外部捕獲塊處理包括共享儲存上的網路超時、許可權問題或大型TIFF上的記憶體不足情況在內的不可預見錯誤。 每次失敗都記錄了文件路徑和錯誤消息以供總結使用,而我們在迴圈中持續處理其餘文件。 在batch_debug.log的日誌文件捕獲任何引發內部診斷的文件的引擎級別詳情。

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

如果管道運行沒有錯誤但提取的文字仍然錯誤,根本原因幾乎總是圖像質量而不是程式碼。 這就是如何解決這個問題的方法。

我如何除錯OCR準確性?

如果信心分數持續偏低,問題在於源圖像而不是OCR引擎。IronOCR提供預處理工具來解決這個問題:

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

我接下來應該去哪裡?

現在您了解如何在運行時除錯IronOCR,繼續探索:

對於生產使用,請記得獲取授權以移除浮水印並存取全部功能。

常見問題

在C#中除錯OCR常見問題是什麼?

常見問題包括OCR結果不正確、信心水準低和意外例外。IronOCR提供了如記錄和信心水準評估的工具以協助識別和解決這些問題。

IronOCR如何協助在C#中進行錯誤處理?

IronOCR提供了型別化例外和詳細的錯誤消息,有助於在C#應用程式中有效地進行OCR操作過程中的錯誤理解和處理。

IronOCR為除錯提供了哪些記錄功能?

IronOCR內建的記錄功能有助於跟蹤OCR過程,並通過記錄有關OCR操作的詳細資訊來識別潛在問題。

信心水準評估如何改進OCR結果?

IronOCR中的信心水準評估有助於確定識別文字的準確性,允許開發人員專注於低信心水準的區域並改進OCR結果。

我可以使用IronOCR跟蹤OCR任務的進度嗎?

可以,IronOCR提供進度追蹤功能,讓開發人員能夠監控OCR任務的狀態和持續時間,便於更好的資源管理和性能優化。

推薦哪些try-catch模式來處理OCR錯誤?

IronOCR建議使用生產級的try-catch模式來優雅地處理例外,確保OCR應用程式保持強韌和可維護。

IronOCR的內建工具如何增強OCR除錯功能?

IronOCR的工具,如記錄、型別化例外和信心水準評估,提供了全面的支持,幫助識別和解決問題,從而增強除錯過程。

為什麼錯誤記錄在OCR應用程式中很重要?

錯誤記錄很重要,因為它提供了有關在OCR處理過程中發生了什麼問題的洞察力,允許開發人員快速診斷和修復他們應用程式中的問題。

型別化例外在除錯IronOCR中扮演什麼角色?

IronOCR中的型別化例外提供特定的錯誤資訊,使開發人員更容易了解問題的性質,應用適當的解決方案進行除錯。

開發人員如何從IronOCR的除錯功能中受益?

開發人員可以利用IronOCR的除錯功能來高效地排除問題,提高應用程式的穩定性,並改善OCR結果的整體質量。

Curtis Chau
技術作家

Curtis Chau擁有Carleton大學的電腦科學學士學位,專精於前端開發,擁有Node.js、TypeScript、JavaScript和React的專業知識。Curtis熱衷於建立直觀且美觀的使用者介面,喜愛使用現代框架並建立結構良好、視覺吸引力的手冊。

除了開發,Curtis對物聯網(IoT)有濃厚的興趣,探索創新的方法來整合硬體和軟體。在空閒時間,他喜歡玩遊戲和建立Discord機器人,結合他對技術的熱愛與創造力。

準備開始了嗎?
Nuget 下載 6,136,090 | 版本: 2026.7 剛剛發布
Still Scrolling Icon

還在滾動?

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