C#에서 OCR 디버깅 방법

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

OCR 파이프라인을 디버깅하는 것은 문제가 프로덕션에 도달하기 전에 오류를 잡고, 문제를 재현할 수 있을 만큼의 세부 사항을 기록하며, 추출된 텍스트가 정확성 기준을 충족하는지 검증하는 것을 의미합니다. IronOCR는 이러한 각 작업에 대해 파일 기반 진단 로깅, 유형화된 예외 계층 구조, 모든 세분화 수준에서의 신뢰도 점수 평가, 장기 실행 작업에 대한 실시간 진행 이벤트와 같은 내장 도구를 제공합니다.

퀵스타트: OCR 진단 로깅 활성화

OCR 호출 전에 Installation.LogFilePathInstallation.Logging방법를 구성하여 Tesseract 초기화, 언어 팩 로딩 및 이미지 전처리 단계를 포함한 자세한 엔진 출력을 캡처합니다.

  1. NuGet 패키지 관리자를 사용하여 https://www.nuget.org/packages/IronOcr 설치하기

    PM > Install-Package IronOcr
  2. 다음 코드 조각을 복사하여 실행하세요.

    using IronOcr;
    
    // Enable comprehensive logging before any OCR call
    Installation.LogFilePath = "ironocr_debug.log";
    Installation.Logging방법 = Installation.Logging방법s.All;
  3. 실제 운영 환경에서 테스트할 수 있도록 배포하세요.

    무료 체험판으로 오늘 프로젝트에서 IronOCR 사용 시작하기

    arrow pointer

진단 로깅을 활성화하는 방법?

IronOCR의 Installation 클래스는 어떤 Read 메서드를 호출하기 전에 우리가 구성하는 세 가지 로깅 컨트롤을 공개합니다.

using IronOcr;

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

// Enable all logging channels: file + debug output
Installation.Logging방법 = Installation.Logging방법s.All;

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

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

// Enable all logging channels: file + debug output
Installation.Logging방법 = Installation.Logging방법s.All;

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

도열 Logging방법Installation.Logging방법s 열거형의 플래그 값을 수용합니다:

표 1 — Logging방법s 옵션
방법출력 대상사용 사례
`None`비활성화됨외부 모니터링을 사용한 프로덕션
`Debug`IDE 디버그 출력 창로컬 개발
`File``LogFilePath`서버 측 로그 수집
`All`디버그 + 파일전체 진단 캡처

CustomLogger 속성은 모든 Microsoft.Extensions.Logging.ILogger 구현을 수용하므로, OCR 진단을 Serilog, NLog 또는 이미 파이프라인에서 실행 중인 다른 구조화된 로깅 싱크로 라우팅할 수 있습니다. Installation.ClearLogFiles()를 호출하여 실행 간 누적된 로그 데이터를 제거하십시오.


OCR 작업이 어떤 예외를 던질 수 있습니까?

IronOCR는 IronOcr.예외s 네임스페이스에서 형식화된 예외를 정의합니다. 이를 특정적으로 캡처하는 것은 포괄적인 catch (예외)보다 각 오류 유형을 올바른 수정 경로로 라우팅할 수 있도록 합니다.

표 2 — IronOCR 예외 참조
예외일반적인 원인수정 방법
`IronOcrInput예외`손상되거나 지원되지 않는 이미지/PDF`OcrInput`로 로딩하기 전에 파일을 검증하세요
`IronOcrProduct예외`OCR 실행 중 내부 엔진 오류로그를 활성화하고 로그 출력을 확인하고 최신 NuGet 버전으로 업데이트
`IronOcrDictionary예외`누락되었거나 손상된 `.traineddata` 언어 파일언어 팩 NuGet을 재설치하거나 `Installation.LanguagePackDirectory`를 설정하세요
`IronOcrNative예외`네이티브 C++ 상호 운용 실패Visual C++ 재배포 가능 패키지를 설치하고 AVX 지원 확인
`IronOcrLicensing예외`누락되었거나 만료된 라이선스 키`Read`를 호출하기 전에 `Installation.LicenseKey`를 설정하세요
`LanguagePack예외`언어 팩을 예상 경로에서 찾을 수 없습니다`LanguagePackDirectory`를 확인하거나 NuGet 언어 패키지를 재설치하세요
`IronOcrAssemblyVersionMismatch예외`부분 업데이트 후 어셈블리 버전이 일치하지 않음NuGet 캐시를 지우고, 패키지를 복원하고, 모든 IronOCR 패키지가 일치하는지 확인하세요

다음 try-catch 블록은 조건부 로깅을 위한 예외 필터와 함께 표적 예외 처리를 설명합니다:

using IronOcr;
using IronOcr.예외s;

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 (IronOcrInput예외 ex)
{
    // File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}");
}
catch (IronOcrDictionary예외 ex)
{
    // Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}");
}
catch (IronOcrNative예외 ex) when (ex.Message.Contains("AVX"))
{
    // CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}");
}
catch (IronOcrLicensing예외)
{
    Console.Error.WriteLine("License key is missing or invalid.");
}
catch (IronOcrProduct예외 ex)
{
    // Catch-all for other IronOCR engine errors
    Console.Error.WriteLine($"OCR engine error: {ex.Message}");
    Console.Error.WriteLine($"Stack trace: {ex.StackTrace}");
}
using IronOcr;
using IronOcr.예외s;

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 (IronOcrInput예외 ex)
{
    // File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}");
}
catch (IronOcrDictionary예외 ex)
{
    // Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}");
}
catch (IronOcrNative예외 ex) when (ex.Message.Contains("AVX"))
{
    // CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}");
}
catch (IronOcrLicensing예외)
{
    Console.Error.WriteLine("License key is missing or invalid.");
}
catch (IronOcrProduct예외 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

우리는 catch 블록을 가장 구체적인 것에서 가장 일반적인 것으로 정렬합니다. when 절은 IronOcrNative예외에 대한 AVX 관련 오류를 필터링하며 관련 없는 네이티브 오류를 포착하지 않습니다. 각 핸들러는 사후 분석을 위한 충분한 컨텍스트 — 메시지, 스택 트레이스 — 를 기록합니다.


OCR 출력 결과를 신뢰 점수로 검증하는 방법은?

OcrResult는 모든 인식된 문자를 균등하게 확률화하는 엔진의 통계적 확신을 나타내는 0에서 1사이의 값을 가진 Confidence 속성을 포함합니다. 결과 계층의 모든 레벨에서 이를 액세스합니다: 문서, 페이지, 문단, 단어, 및 문자.

임계 값에 따라 차단되는 검증 패턴은 낮은 품질의 OCR 출력을 하류로 전달되지 않도록 막습니다.

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})");
    }
}
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이 데이터 입력, 송장 처리 또는 준수 워크플로에 피드되는 파이프라인에서 필수적입니다. 단어 별 세부 분석을 통해 소스 이미지의 어떤 부분이 품질 저하를 일으켰는지 정확히 식별합니다 — 그런 다음 이미지 품질 필터 또는 방향 수정을 적용하고 다시 처리할 수 있습니다. 신뢰 점수에 대한 자세한 내용은 신뢰 수준 사용법을 참조하세요.


실시간으로 OCR 진행 상황을 모니터링하는 방법은?

여러 페이지 문서의 경우, IronTesseractOcrProgress 이벤트는 각 페이지가 완료된 후 상태를 보고합니다. OcrProgressEventArgs 객체는 ProgressPercent, Duration, TotalPages, PagesComplete, StartTimeUTC, 및 EndTimeUTC를 노출합니다.

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

우리는 이 이벤트를 로깅 인프라에 연결하여 OCR 작업 시간을 기록하고 정체를 탐지합니다. DurationProgressPercent가 발전하지 않는 상태로 임계값을 초과할 경우, 파이프라인은 해당 작업을 조사 목록에 포함시킬 수 있습니다. 이는 단일 잘못된 페이지가 전체 작업을 정지시킬 수 있는 배치 PDF 처리에 특히 유용합니다.


배치 OCR 파이프라인에서 오류를 처리하는 방법은?

생산 OCR 시스템은 수백 또는 수천 개의 파일을 처리합니다. 단일 오류로 파이프라인이 중단되어서는 안 됩니다. 우리는 파일별로 오류를 격리하고, 실패를 컨텍스트와 함께 기록하며, 마지막에 요약 보고서를 생성합니다.

using IronOcr;
using IronOcr.예외s;

var ocr = new IronTesseract();
Installation.LogFilePath = "batch_debug.log";
Installation.Logging방법 = Installation.Logging방법s.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 (IronOcrInput예외 ex)
    {
        failed++;
        failures.Add((file, $"Input error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (IronOcrProduct예외 ex)
    {
        failed++;
        failures.Add((file, $"Engine error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (예외 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}");
using IronOcr;
using IronOcr.예외s;

var ocr = new IronTesseract();
Installation.LogFilePath = "batch_debug.log";
Installation.Logging방법 = Installation.Logging방법s.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 (IronOcrInput예외 ex)
    {
        failed++;
        failures.Add((file, $"Input error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (IronOcrProduct예외 ex)
    {
        failed++;
        failures.Add((file, $"Engine error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (예외 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

외부 catch (예외) 블록은 예기치 않은 오류 — 공유 저장소에서의 네트워크 타임아웃, 권한 문제 또는 대형 TIFF에서의 메모리 부족 상황 — 를 처리합니다. 각 오류는 파일 경로와 오류 메시지를 요약 보고서에 기록하며, 루프는 나머지 파일을 계속 처리합니다. batch_debug.log에 있는 로그 파일은 내부 진단을 유발하는 파일의 엔진 수준 세부사항을 캡처합니다.

서비스 또는 웹 애플리케이션에서 비블로킹 실행을 위해, IronOCR는 ReadAsync을 지원하며 같은 try-catch 구조 내에 await ocr.ReadAsync(input) 호출을 랩핑합니다.


OCR 정확도 디버깅은 어떻게 해야 하나요?

신뢰 점수가 지속적으로 낮을 때, 문제는 일반적으로 OCR 엔진이 아니라 입력 이미지입니다. IronOCR는 이를 해결할 전처리 도구를 제공합니다:

  • 이미지 품질 필터 — 인식 전에 텍스트 선명도를 향상시킬 수 있도록 샤픈, 소음 제거, 팽창, 침식 필터를 적용합니다.
  • 방향 수정 — 스캔된 문서의 자동 비스듬이 제거 및 회전 수정.
  • DPI 업스케일링 — 저해상도 이미지는 처리 전에 DPI 조정으로 이점을 얻습니다.
  • 컴퓨터 비전 — OpenCV 기반 텍스트 영역 감지는 복잡한 레이아웃에서 텍스트 영역을 분리합니다.
  • IronOCR 유틸리티 — 필터 조합을 시각적으로 테스트하고 최적의 C# 구성을 내보내는 데스크톱 도구입니다.

배포 시 특정 문제 (누락된 런타임, 네이티브 라이브러리 오류)에 대해 IronOCR는 Azure Functions, Docker 및 Linux, 및 일반 환경 설정에 대한 전용 문제 해결 가이드를 유지합니다.


여기서 어디로 가야 하나요?

이 가이드는 런타임 디버깅 — 로깅, 예외, 신뢰 검증, 진행 상황 모니터링, 배치 오류 처리 — 을 다루었습니다. 관련 주제를 확인하려면 다음을 탐색하세요:

IronOCR 라이선스 구매를 통해 프로덕션에 배포하거나, 환경에서 이러한 디버깅 패턴을 테스트하기 위해 무료 30일 체험판을 시작하세요.

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'name'

Filename: sections/author_component.php

Line Number: 18

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 18
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'title'

Filename: sections/author_component.php

Line Number: 38

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 38
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

A PHP Error was encountered

Severity: Warning

Message: Illegal string offset 'comment'

Filename: sections/author_component.php

Line Number: 48

Backtrace:

File: /var/www/ironpdf.com/application/views/main/sections/author_component.php
Line: 48
Function: _error_handler

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 63
Function: view

File: /var/www/ironpdf.com/application/views/products/sections/three_column_docs_page_structure.php
Line: 64
Function: main_view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/views/products/how-to/index.php
Line: 2
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 88
Function: view

File: /var/www/ironpdf.com/application/libraries/Render.php
Line: 552
Function: view

File: /var/www/ironpdf.com/application/controllers/Products/Howto.php
Line: 31
Function: render_products_view

File: /var/www/ironpdf.com/index.php
Line: 292
Function: require_once

시작할 준비 되셨나요?
Nuget 다운로드 5,525,971 | 버전: 2026.3 방금 출시되었습니다
Still Scrolling Icon

아직도 스크롤하고 계신가요?

빠른 증거를 원하시나요? PM > Install-Package IronOcr
샘플을 실행하세요 이미지가 검색 가능한 텍스트로 바뀌는 것을 확인해 보세요.