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の初期化、言語パックの読み込み、および処理の詳細をログファイルに記録するには、たった2つのプロパティを設定するだけで済みます。

  1. IronOCR をNuGetパッケージマネージャでインストール

    PM > Install-Package IronOcr
  2. このコード スニペットをコピーして実行します。

    IronOcr.Installation.LogFilePath = "ocr.log"; IronOcr.Installation.Loggingモード = IronOcr.Installation.Loggingモードs.All;
  3. 実際の環境でテストするためにデプロイする

    今日プロジェクトで IronOCR を使い始めましょう無料トライアル

    arrow pointer


診断ログを有効にするにはどうすればよいですか?

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;
$vbLabelText   $csharpLabel

LoggingモードLoggingモードs列挙型からフラグ値を受け入れます。

表1:ログモードのオプション
モード出力ターゲット使用事例
None無効本番環境での外部モニタリング
DebugIDEのデバッグ出力ウィンドウローカル開発
FileLogFilePathサーバーサイドのロギング収集
Allデバッグ + ファイル完全な診断キャプチャ

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++ 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}");
}
$vbLabelText   $csharpLabel

出力

成功時の出力

請求書は正常に読み込まれ、エンジンは文字数と信頼度スコアを返します。

invoice_scan.pdf の OCR 読み取りが成功したことを示すターミナル出力(文字数と信頼度スコアを含む)。

出力失敗

ターミナル出力には、存在しないPDFファイルの読み込み時に発生した例外が表示されています。

キャッチブロックは、最も具体的なものから最も一般的なものへと順に並べなさい。 when 句は、IronOcrNative例外 に対して、無関係なネイティブ エラーを捕捉することなく、 AVX 関連の障害をフィルタリングします。 各ハンドラは例外メッセージをログに記録する。 包括的なブロックは、事後分析のためにスタックトレースもキャプチャします。

適切な例外を捕捉することで、何らかの問題が発生したことはわかりますが、エンジンが正常に動作した際のパフォーマンスについてはわかりません。 そのためには、信頼度スコアを使用してください。

OCR出力の信頼性スコアを検証するにはどうすればよいですか?

すべてのOcrResultConfidence プロパティを公開します。これは、認識されたすべての文字にわたって平均化されたエンジンの統計的確実性を表す 0 から 1 の間の値です。 結果階層のどのレベル(文書ページ段落単語文字)でもこれにアクセスできます。

低品質な結果が下流に伝播するのを防ぐため、閾値制御パターンを使用してください。

入力

明細項目、割引、合計、バーコードが記載された感熱レシート。LoadImage を介して読み込まれます。 その狭い幅、等幅フォント、そして薄い印刷は、単語ごとの信頼度閾値を検証するための実用的なストレステストとなる。

OCR入力として使用される、FoodMartの感熱レシートのサンプル(購入品目、合計金額、ポイントが記載されている)。

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})");
    }
}
$vbLabelText   $csharpLabel

出力

端末出力には、レシート画像の信頼度スコア、承認/フラグ/拒否の判定、および単語ごとの低信頼度ドリルダウンが表示されます。

このパターンは、OCRがデータ入力、請求書処理、コンプライアンスワークフローに供給されるパイプラインにおいて重要です。 単語ごとの詳細な分析により、ソース画像のどの領域が劣化を引き起こしたかを正確に特定できます。 その後、画質フィルター向き補正を適用して再処理することができます。 信頼度レベルの詳細ガイドを見ると、信頼スコアリングをより深く見ることができます。

長期にわたる仕事においては、自信だけでは十分ではない。 また、エンジンがまだ進行しているかどうかを知る必要があり、そこでOcrProgressイベントが登場します。

OCRの進行状況をリアルタイムで監視するにはどうすればよいですか?

複数ページの文書の場合、各ページが完了すると、IronTesseractOcrProgress イベントが発生します。 OcrProgressEventArgs オブジェクトは、進行率、経過時間、総ページ数、完了ページ数を公開します。 この例では、3ページにわたる四半期報告書を入力として使用します。これは、エグゼクティブサマリー、収益内訳、および業務指標を含む構造化されたビジネス文書です。

入力

LoadPdf を介して読み込まれた 2024 年第 1 四半期の 3 ページの財務報告書。 1ページ目にはKPI指標を含むエグゼクティブサマリー、2ページ目には製品ライン別および地域別の収益表、3ページ目には運用処理量が掲載されています。各ページタイプごとに異なる処理時間が発生し、進捗コールバックで確認できます。

quarterly_report.pdf: 2024年第1四半期の3ページにわたる財務報告書(エグゼクティブサマリー、収益内訳、運用指標)で、ページごとのリアルタイムの`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}");
$vbLabelText   $csharpLabel

出力

ターミナル出力には、3ページのPDFについて、ページごとのOcrProgressイベントコールバック、完了率、経過時間が表示されます。

このイベントをログ記録インフラストラクチャに組み込むことで、OCRジョブの実行時間を追跡し、停止を検出できます。 経過時間が一定の閾値を超えても進捗率が進まない場合、パイプラインは調査対象としてジョブにフラグを立てることができます。 これは特にバッチPDF処理に役立ち、単一の異常なページが全体のジョブを停滞させてしまう可能性があります。

進捗状況の監視によって実行状態は把握できますが、ファイルレベルの障害が発生した場合、それを特定しないとバッチ処理全体が途中で停止してしまう可能性があります。

バッチOCRパイプラインにおけるエラー処理方法を教えてください

本番環境では、単一ファイルのエラーによってバッチ処理全体が停止するような事態は避けるべきです。 ファイルごとにエラーを特定し、エラーをコンテキストとともにログに記録し、最後に要約レポートを作成します。 この例では、請求書、発注書、サービス契約書を含むスキャン文書のフォルダと、Plus。 代表的なサンプルを以下に示します。

入力

Directory.GetFiles に渡されたPDFファイルのフォルダには、請求書、発注書、サービス契約書、そして意図的に破損させたファイルが1つ含まれています。以下の2つの代表的なサンプルは、パイプラインが1回の実行で処理する文書の多様性を示しています。

: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}");
$vbLabelText   $csharpLabel

出力

バッチパイプラインの結果を示すターミナル出力。ファイルごとの文字数、信頼度スコア、破損したPDFからのエラー1件、および要約行が表示されます。

外側のcatchブロックは、共有ストレージでのネットワークタイムアウト、権限の問題、大きなTIFFファイルでのメモリ不足など、予期せぬエラーを処理します。 各失敗は、ファイルパスとエラーメッセージを要約のために記録し、ループは残りのファイルの処理を継続します。 batch_debug.log にあるログファイルには、内部診断をトリガーするすべてのファイルに関するエンジンレベルの詳細情報が記録されます。

サービスや Web アプリケーションでの非ブロッキング実行のために、 IronOCR は同じ try-catch 構造を使用するReadAsyncをサポートしています。

パイプラインがエラーなく実行されたにもかかわらず、抽出されたテキストが間違っている場合、根本原因はほぼ間違いなくコードではなく画像品質にある。 それに対処する方法は以下のとおりです。

OCRの精度をデバッグするにはどうすればよいですか?

信頼度スコアが継続的に低い場合、問題はOCRエンジンではなく、元の画像にあります。IronOCRは、この問題を解決するための前処理ツールを提供しています。

テキストの鮮明度を向上させるために、シャープ化、ノイズ除去、膨張、収縮などの画像品質フィルターを適用します。 ・向き補正機能を使用して、スキャンした文書の傾きや回転を自動的に補正します。 処理前に低解像度画像のDPI設定を調整してください。 ・コンピュータビジョンを用いて、複雑なレイアウト内のテキスト領域を検出・分離する IronOCRユーティリティを使用すると、フィルターの組み合わせを視覚的にテストし、最適なC#構成をエクスポートできます。

デプロイメント固有の問題については、 IronOCR はAzure FunctionsDocker および Linux一般的な環境設定に関する専用のトラブルシューティング ガイドを用意しています。

次はどこへ行くべきでしょうか?

IronOCRの実行時デバッグ方法が理解できたので、以下を試してみてください。

本番環境で使用する場合は、ライセンスを取得することを忘れないでください。

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

準備はできましたか?
Nuget ダウンロード 5,556,263 | バージョン: 2026.3 リリース
Still Scrolling Icon

まだスクロールしていますか?

すぐに証拠が欲しいですか? PM > Install-Package IronOcr
サンプルを実行 あなたの画像が検索可能なテキストになるのをご覧ください。