如何在 C# 中除錯 OCR
IronOCR 讓您能夠在源頭偵測 OCR 失敗情況、在單字與字元層級評估辨識品質,並即時監控長時間執行的任務。內建工具(例如診斷檔案記錄、類型化例外層級、每項結果的信心分數,以及 OcrProgress 事件)皆能支援生產管線中的這些工作流程。
本指南將逐步示範各項實作範例:啟用診斷記錄、處理類型化例外、透過信心分數驗證輸出、即時監控工作進度,以及在批次處理管線中隔離錯誤。
快速入門:啟用完整的 OCR 診斷記錄
請在首次呼叫 Read 之前,於 Installation 類別上設定 LogFilePath 和 Logging模式。 只需設定兩項屬性,即可將 Tesseract 的初始化、語言套件載入及處理細節記錄至日誌檔案中。
簡化工作流程(5 個步驟)
- 下載用於 OCR 除錯的 C# 函式庫
- 將
LogFilePath設定為可寫入的檔案路徑 - 將
Logging模式設為全部以進行完整的診斷記錄 - 執行您的 OCR 操作並重現該問題
- 檢查生成的日誌檔案,以查看引擎警告及處理詳情
如何啟用診斷記錄?
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
Logging模式 接受來自 Logging模式s 枚舉的旗標值:
| 模式 | 目標輸出 | 使用案例 |
|---|---|---|
無 | 已停用 | 生產環境搭配外部監控 |
除錯 | IDE 除錯輸出視窗 | 在地化開發 |
檔案 | LogFilePath | 伺服器端日誌收集 |
全部 | 除錯 + 檔案 | 完整診斷擷取 |
CustomLogger 屬性支援任何 Microsoft.Extensions.Logging.ILogger 實作,讓您能將 OCR 診斷資訊導向 Serilog、NLog 或您管道中的其他結構化記錄接收端。使用 ClearLogFiles 來清除執行間累積的記錄資料。
在啟用記錄功能後,下一步是了解 IronOCR 可能拋出的例外狀況,以及如何處理每種情況。
IronOCR 會拋出哪些例外?
IronOCR 在 IronOcr.Exceptions 命名空間下定義了類型化例外。 透過針對性地處理這些錯誤,而非使用籠統的 catch 區塊,您便能將每種錯誤類型導向正確的修復路徑。
| 例外 | Common Cause | 修正 |
|---|---|---|
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
輸出
成功輸出
發票載入順暢,引擎會同時回傳字元數與信心分數。
失敗的輸出
請將 catch 區塊依從最具體到最通用的順序排列。 when 子句在 IronOcrNative例外 篩選器上,用於篩選與 AVX 相關的錯誤,同時不會擷取無關的原生錯誤。 每個處理程序都會記錄例外訊息; 該 catch-all 區塊亦會擷取堆疊追蹤資訊,以供事後分析之用。
捕捉正確的例外狀況能告訴您出了問題,但無法反映引擎在成功運作時的表現如何。 為此,請使用信心分數。
如何利用信心分數驗證 OCR 輸出結果?
每個 OcrResult 都會公開一個 Confidence 屬性,其值介於 0 到 1 之間,代表引擎針對所有識別出的字元所計算出的平均統計確定度。 您可以在結果層級的每個層級(文件、頁面、段落、單字和字元)存取此內容。
請採用閾值門控模式,以防止低品質的結果向下傳遞。
輸入
一張熱感收據,包含明細項目、折扣、總額及BARCODE,透過 LoadImage 載入。 其狹窄的寬度、等寬字體以及淡色的PRINT字體,使其成為測試單字信心閾值的實用壓力測試。
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
輸出
此模式對於 OCR 銜接至資料輸入、發票處理或合規工作流程的處理鏈至關重要。 按WORD細查功能可精確識別源圖像中哪些區域導致了畫質劣化; 您隨後可套用影像品質濾鏡或進行方向校正,並重新處理。 若要深入了解信心分數,請參閱信心等級操作指南。
對於長期運行的任務,僅憑信心是不夠的。 您還需要了解引擎是否仍在運作,而這正是 OcrProgress 事件派生的原因。
如何即時監控 OCR 的進度?
對於多頁文件,每當一頁處理完畢後,OcrProgress 上的 IronTesseract 事件便會觸發。 OcrProgressEventArgs 物件會公開進度百分比、已耗時、總頁數及已完成頁數。 此範例以這份三頁的季度報告作為輸入:一份結構化的商業文件,內容涵蓋執行摘要、營收明細及營運指標。
輸入
透過 LoadPdf 載入的 2024 年第一季三頁財務報告。 第一頁涵蓋包含 KPI 指標的執行摘要,第二頁包含按產品線和地區劃分的營收表格,第三頁則涵蓋營運處理量 — 每種頁面類型都會產生獨特的每頁處理時間,您可在進度回調中觀察到這些數據。
quarterly_report.pdf: Three-page Q1 2024 financial report (executive summary, revenue breakdown, operational metrics) used to demonstrate real-time `OcrProgress` callbacks per page.
: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
輸出
將此事件整合至您的記錄基礎架構中,以追蹤 OCR 工作執行時間並偵測停滯狀況。 若經過的時間超過閾值,而進度百分比卻未增加,管道可將該工作標記為待查。 這對於批次 PDF 處理特別有用,因為單一格式錯誤的頁面就可能導致整個工作停滯。
進度監控會顯示執行狀態,但若未能隔離檔案層級的錯誤,仍可能導致整個批次作業提前終止。
如何處理批次 OCR 處理流程中的錯誤?
在生產環境中,單一檔案的失敗不應導致整個批次中斷。 請針對每個檔案分別標示錯誤,並附帶上下文記錄失敗情況,最後生成一份摘要報告。 此範例處理一個包含掃描文件的資料夾,內含發票、採購訂單、服務合約,以及一個刻意損毀的檔案,用以觸發錯誤處理流程。 以下為代表性範例:
輸入
傳遞給 Directory.GetFiles 的 PDF 文件夾——包含一張發票、一份採購訂單、一份服務合約,以及一個刻意損毀的檔案。以下兩個代表性範例展示了該處理流程在單次執行中處理的文件多樣性。
batch-scan-01.pdf:Bright Horizon Ltd. 的發票(INV-2024-001)—— OCR 識別成功。
batch-scan-02.PDF:TechSupply Inc. 的採購訂單(PO-2024-042)—— 同一批次中的第二種文件類型。
: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
輸出
外層的 catch 區塊負責處理各種不可預見的錯誤,包括共用儲存空間的網路超時、權限問題,或是處理大型 TIFF 檔案時的記憶體不足狀況。 每次處理失敗時,系統會將檔案路徑與錯誤訊息記錄至摘要中,同時迴圈會繼續處理剩餘的檔案。 位於 batch_debug.log 的日誌檔案,會記錄任何觸發內部診斷的檔案之引擎層級詳細資訊。
為了在服務或網頁應用程式中實現非阻塞執行,IronOCR 支援 ReadAsync,其採用相同的 try-catch 結構。
若處理流程執行時未出現錯誤,但擷取的文字仍不正確,根本原因幾乎總是源於影像品質,而非程式碼。 以下是處理方式。
如何調試 OCR 準確度?
若信心分數持續偏低,問題出在原始圖像而非 OCR 引擎。IronOCR 提供預處理工具來解決此問題:
- 套用影像品質濾鏡(例如銳化、去噪、膨脹與蝕蝕)以提升文字清晰度
- 使用方向校正功能,自動校正並旋轉掃描文件
- 處理前請先調整低解析度圖片的 DPI 設定
- 運用電腦視覺技術,在複雜版面中偵測並區隔文字區域
- IronOCR Utility 讓您可直觀地測試濾鏡組合,並匯出最佳的 C# 設定
針對部署相關問題,IronOCR 提供針對 Azure Functions、Docker 與 Linux 以及一般環境設定的專用疑難排解指南。
接下來該去哪裡?
既然您已了解如何在執行階段除錯 IronOCR,請進一步探索:
- 解析 OCR 結果的結構與元資料,包括頁面、區塊、段落、單字及座標
- 理解結果層級結構中各層級的信心分數
- 結合 async 與多執行緒技術,搭配
ReadAsync打造高吞吐量處理管線 - 瀏覽完整的 API 參考以查看完整的屬性清單
若用於正式生產環境,請記得取得授權以移除浮水印並使用完整功能。
常見問題
在 C# 中除錯 OCR 時常見哪些問題?
常見問題包括 OCR 結果不正確、信心分數過低以及發生意外的例外狀況。IronOCR 提供日誌記錄和信心評分等工具,協助識別並解決這些問題。
IronOCR 如何協助處理 C# 中的錯誤?
IronOCR 提供類型化的例外狀況與詳細的錯誤訊息,有助於在 C# 應用程式執行 OCR 操作時,有效理解並處理錯誤。
IronOCR 提供了哪些用於除錯的記錄功能?
IronOCR 內建日誌記錄功能,可透過記錄 OCR 操作的詳細資訊,協助追蹤 OCR 流程並識別潛在問題。
信心評分如何改善 OCR 結果?
IronOCR 的信心分數功能有助於判斷辨識文字的準確性,讓開發人員能專注於信心分數較低的區域,並改善 OCR 結果。
我能否使用 IronOCR 追蹤 OCR 任務的進度?
是的,IronOCR 提供進度追蹤功能,讓開發人員能夠監控 OCR 任務的狀態與執行時間,從而協助進行更完善的資源管理與效能優化。
針對 OCR 錯誤處理,建議採用哪些 try-catch 模式?
IronOCR 建議採用已通過生產環境驗證的 try-catch 模式來優雅地處理例外狀況,確保 OCR 應用程式具備穩健性與可維護性。
IronOCR 的內建工具如何提升 OCR 除錯效能?
IronOCR 的工具,例如記錄、類型化例外狀況及信心評分,為問題的識別與解決提供全面支援,從而提升除錯流程的效率。
在 OCR 應用程式中,錯誤記錄為何如此重要?
錯誤記錄至關重要,因為它能提供 OCR 處理過程中發生何種問題的洞察,讓開發人員能夠快速診斷並修復應用程式中的問題。
在 IronOCR 的除錯過程中,類型化例外扮演什麼角色?
IronOCR 中的類型化例外狀況會提供具體的錯誤資訊,讓開發人員在除錯時更容易理解問題的本質,並採取適當的解決方案。
開發人員如何從 IronOCR 的除錯功能中受益?
開發人員可利用 IronOCR 的除錯功能,有效率地排除問題、提升應用程式穩定性,並改善 OCR 結果的整體品質。

