C#でのOCRのデバッグ方法
IronOCR を使用すると、ソースレベルで OCR の失敗を検出し、単語や文字レベルで認識品質を評価し、長時間実行されるジョブをリアルタイムで監視することができます。診断ファイルのロギング、型付き例外階層、結果ごとの信頼度スコアリング、OcrProgress イベントなどの組み込みツールが、本番環境のパイプラインにおけるこれらのワークフローをサポートします。
このガイドでは、診断ログの有効化、型付き例外の処理、信頼度スコアによる出力の検証、ジョブの進行状況のリアルタイム監視、バッチパイプラインにおけるエラーの分離など、それぞれの動作例を順を追って説明します。
クイックスタート: フルOCR診断ログを有効にする
最初の Read の呼び出しの前に、Installation クラスで LogFilePath と Loggingモード を設定してください。 Tesseractの初期化、言語パックの読み込み、および処理の詳細をログファイルに記録するには、たった2つのプロパティを設定するだけで済みます。
最小限のワークフロー(5ステップ)
- OCRのデバッグ用C#ライブラリをダウンロードしてください
LogFilePath書き込み可能なファイルパスに設定します。- 診断情報を完全に取得するには、
Loggingモードすべてに設定してください。 - OCR操作を実行し、問題を再現します
- 生成されたログファイルを検査して、エンジンの警告と処理の詳細を見ます
診断ログを有効にするにはどうすればよいですか?
Installation クラスは、3つのロギングコントロールを公開しています。 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は、@@--CODE-154--@@名前空間の下で型付き例外を定義します。 包括的なキャッチブロックではなく、これらのエラーを個別にキャッチすることで、それぞれのエラータイプを適切な修復パスにルーティングできます。
| 例外 | 共通の原因 | 修正方法 |
|---|---|---|
IronOcrInput例外 | 壊れたまたはサポートされていない画像/PDF | ファイルをOcrInputに読み込む前に検証 |
IronOcrProduct例外 | OCR実行中の内部エンジンエラー | ログを有効にし、ログ出力を確認し、最新のNuGetバージョンに更新 |
IronOcrDictionary例外 | 欠落または壊れた.traineddata言語ファイル | 言語パックのNuGetを再インストールするか、 LanguagePackDirectoryを設定してください。 |
IronOcrNative例外 | ネイティブC++の相互運用の失敗 | Visual C++ Redistributableをインストールして、AVXのサポートを確認 |
IronOcrLicensing例外 | 欠落または期限切れのライセンスキー | Readを呼び出す前にLicenseKeyを設定してください。 |
LanguagePack例外 | 想定されたパスに言語パックが見つかりません | LanguagePackDirectoryを確認するか、NuGet言語パッケージを再インストール |
IronOcrAssemblyVersionMismatch例外 | 部分的な更新後のアセンブリバージョンの不一致 | NuGetキャッシュをクリアし、パッケージを復元して、すべてのIronOCRパッケージが一致していることを確認 |
以下のtry-catchブロックを使用して、各例外タイプを個別に処理し、条件付きログ記録のために例外フィルタを適用します。
入力
IronOCR Solutions から Acme Corporation 宛ての 1 ページのベンダー請求書。LoadPdf 経由で OcrInput に読み込まれました。 これには4つの明細項目、税金、そして合計金額が含まれており、各例外処理担当者に現実的な演習を提供するのに十分なテキストの多様性がある。
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
出力
成功時の出力
請求書は正常に読み込まれ、エンジンは文字数と信頼度スコアを返します。
出力失敗
キャッチブロックは、最も具体的なものから最も一般的なものへと順に並べなさい。 when 句は、IronOcrNative例外 フィルター上で、AVX 関連のエラーを捕捉しつつ、無関係なネイティブエラーは捕捉しないようにします。 各ハンドラは例外メッセージをログに記録する。 包括的なブロックは、事後分析のためにスタックトレースもキャプチャします。
適切な例外を捕捉することで、何らかの問題が発生したことはわかりますが、エンジンが正常に動作した際のパフォーマンスについてはわかりません。 そのためには、信頼度スコアを使用してください。
OCR出力の信頼性スコアを検証するにはどうすればよいですか?
すべての OcrResult は Confidence プロパティを公開しており、この値は 0 から 1 の間で、認識されたすべての文字について平均化されたエンジンの統計的確度を表します。 結果階層のどのレベル(文書、ページ、段落、単語、文字)でもこれにアクセスできます。
低品質な結果が下流に伝播するのを防ぐため、閾値制御パターンを使用してください。
入力
品目明細、割引、合計金額、およびBARCODEが記載されたサーマルレシート。LoadImage経由で読み込まれます。 その狭い幅、等幅フォント、そして薄い印刷は、単語ごとの信頼度閾値を検証するための実用的なストレステストとなる。
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がデータ入力、請求書処理、コンプライアンスワークフローに供給されるパイプラインにおいて重要です。 単語ごとの詳細な分析により、ソース画像のどの領域が劣化を引き起こしたかを正確に特定できます。 その後、画質フィルターや向き補正を適用して再処理することができます。 信頼度レベルの詳細ガイドを見ると、信頼スコアリングをより深く見ることができます。
長期にわたる仕事においては、自信だけでは十分ではない。 また、エンジンがまだ進行中であるかどうかも把握する必要があります。そこで OcrProgress イベントが役立ちます。
OCRの進行状況をリアルタイムで監視するにはどうすればよいですか?
複数ページからなるドキュメントの場合、各ページの処理が完了するたびに IronTesseract 上の OcrProgress イベントが発生します。 OcrProgressEventArgs オブジェクトは、進行率、経過時間、総ページ数、および完了ページ数を公開します。 この例では、3ページにわたる四半期報告書を入力として使用します。これは、エグゼクティブサマリー、収益内訳、および業務指標を含む構造化されたビジネス文書です。
入力
LoadPdf 経由で読み込まれた、3ページにわたる2024年第1四半期の財務報告書。 1ページ目にはKPI指標を含むエグゼクティブサマリー、2ページ目には製品ライン別および地域別の収益表、3ページ目には運用処理量が掲載されています。各ページタイプごとに異なる処理時間が発生し、進捗コールバックで確認できます。
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 ファイルのフォルダには、請求書、発注書、サービス契約書、および意図的に破損させたファイルが 1 つ含まれています。以下の 2 つの代表的なサンプルは、このパイプラインが 1 回の実行で処理するドキュメントの多様性を示しています。
batch-scan-01.pdf: Bright Horizon Ltd. の請求書 (INV-2024-001) — OCR が正常に完了しました。
batch-scan-02.pdf: TechSupply Inc. の発注書 (PO-2024-042) — 同一実行における 2 番目のドキュメント タイプ。
: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 のログファイルには、内部診断をトリガーしたファイルに関するエンジンレベルの詳細が記録されます。
サービスやWebアプリケーションにおけるノンブロッキング実行のため、IronOCRは同じtry-catch構造を使用するReadAsyncをサポートしています。
パイプラインがエラーなく実行されたにもかかわらず、抽出されたテキストが間違っている場合、根本原因はほぼ間違いなくコードではなく画像品質にある。 それに対処する方法は以下のとおりです。
OCRの精度をデバッグするにはどうすればよいですか?
信頼度スコアが継続的に低い場合、問題はOCRエンジンではなく、元の画像にあります。IronOCRは、この問題を解決するための前処理ツールを提供しています。
テキストの鮮明度を向上させるために、シャープ化、ノイズ除去、膨張、収縮などの画像品質フィルターを適用します。 ・向き補正機能を使用して、スキャンした文書の傾きや回転を自動的に補正します。 処理前に低解像度画像のDPI設定を調整してください。 ・コンピュータビジョンを用いて、複雑なレイアウト内のテキスト領域を検出・分離する IronOCRユーティリティを使用すると、フィルターの組み合わせを視覚的にテストし、最適なC#構成をエクスポートできます。
デプロイメント固有の問題については、 IronOCR はAzure Functions 、 Docker および Linux 、一般的な環境設定に関する専用のトラブルシューティング ガイドを用意しています。
次はどこへ行くべきでしょうか?
IronOCRの実行時デバッグ方法が理解できたので、以下を試してみてください。
- OCR結果の構造とメタデータ(ページ、ブロック、段落、単語、座標など)をナビゲートする
- 結果階層のあらゆるレベルにおける信頼度スコアリングの理解
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結果の全体的な品質を向上させることができます。

