Como Depurar OCR em C#

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

Depurar pipelines de OCR significa capturar falhas antes que cheguem à produção, registrar detalhes suficientes para reproduzir problemas e validar que o texto extraído atende aos limites de precisão. IronOCR fornece ferramentas integradas para cada uma dessas etapas: registro de diagnóstico baseado em arquivo, hierarquia de exceções tipadas, pontuação de confiança em cada nível de granularidade e um evento de progresso em tempo real para tarefas de longa duração.

Início Rápido: Ativar Registro de Diagnóstico do OCR

Configure Installation.LogFilePath e Installation.LoggingModo antes de qualquer chamada OCR para capturar a saída detalhada do mecanismo cobrindo a inicialização do Tesseract, carregamento de pacotes de linguagem e etapas de pré-processamento de imagens.

  1. Instale IronOCR com o Gerenciador de Pacotes NuGet

    PM > Install-Package IronOcr
  2. Copie e execute este trecho de código.

    using IronOcr;
    
    // Enable comprehensive logging before any OCR call
    Installation.LogFilePath = "ironocr_debug.log";
    Installation.LoggingModo = Installation.LoggingModos.All;
  3. Implante para testar em seu ambiente de produção.

    Comece a usar IronOCR em seu projeto hoje com uma avaliação gratuita

    arrow pointer

Como Ativar o Registro de Diagnóstico?

A classe Installation do IronOCR expõe três controles de registro que configuramos antes de chamar qualquer método Read.

using IronOcr;

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

// Enable all logging channels: file + debug output
Installation.LoggingModo = Installation.LoggingModos.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.LoggingModo = Installation.LoggingModos.All;

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

LoggingModo aceita valores de bandeira do enum Installation.LoggingModos:

Tabela 1 — Opções de LoggingModos
ModoAlvo de SaídaCaso de uso
`Nenhum`DesativadoProdução com monitoramento externo
`Debug`Janela de saída de depuração do IDEDesenvolvimento local
`Arquivo``CaminhoDoArquivoDeLog`Coleta de log do lado do servidor
`Todos`Debug + ArquivoCaptura de diagnóstico completa

A propriedade CustomLogger aceita qualquer implementação Microsoft.Extensions.Logging.ILogger, para que possamos direcionar diagnósticos OCR para Serilog, NLog ou qualquer coletor de log estruturado já em execução no pipeline. Chame Installation.ClearLogFiles() para limpar dados de log acumulados entre execuções.


Quais Exceções Podem Ser Lançadas pelas Operações OCR?

IronOCR define exceções tipadas sob o namespace IronOcr.Exceçãos. Capturar essas especificamente — em vez de uma catch (Exceção) abrangente — nos permite direcionar cada tipo de falha para o caminho de remediação correto.

Tabela 2 — Referência de Exceções do IronOCR
ExceçãoCausa ComumCorreção
`IronOcrInputExceção`Imagem/PDF corrompido ou não suportadoValide o arquivo antes de carregá-lo em `OcrInput`
`IronOcrProductExceção`Erro interno do motor durante a execução do OCRAtivar log, verificar saída de log, atualizar para a última versão do NuGet
`IronOcrDictionaryExceção`Arquivo de idioma `.traineddata` ausente ou corrompidoReinstale o pacote de idiomas NuGet ou configure `Installation.LanguagePackDirectory`
`IronOcrNativeExceção`Falha na interoperabilidade nativa do C++Instale Visual C++ Redistributable; verifique o suporte a AVX
`IronOcrLicensingExceção`Chave de licença ausente ou expiradaDefina `Installation.LicenseKey` antes de chamar `Read`
`LanguagePackExceção`Pacote de idiomas não encontrado no caminho esperadoVerifique `LanguagePackDirectory` ou reinstale o pacote de idiomas NuGet
`IronOcrAssemblyVersionMismatchExceção`Versões de assembly incompatíveis após atualização parcialLimpe o cache do NuGet, restaure os pacotes, verifique se todos os pacotes IronOCR correspondem

O bloco try-catch a seguir demonstra o tratamento de exceções direcionadas com filtros de exceção para registro condicional de logs:

using IronOcr;
using IronOcr.Exceçãos;

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 (IronOcrInputExceção ex)
{
    // File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}");
}
catch (IronOcrDictionaryExceção ex)
{
    // Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}");
}
catch (IronOcrNativeExceção ex) when (ex.Message.Contains("AVX"))
{
    // CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}");
}
catch (IronOcrLicensingExceção)
{
    Console.Error.WriteLine("License key is missing or invalid.");
}
catch (IronOcrProductExceção 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.Exceçãos;

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 (IronOcrInputExceção ex)
{
    // File could not be loaded — corrupt, locked, or unsupported format
    Console.Error.WriteLine($"Input error: {ex.Message}");
}
catch (IronOcrDictionaryExceção ex)
{
    // Language pack missing — common in containerized deployments
    Console.Error.WriteLine($"Language pack error: {ex.Message}");
}
catch (IronOcrNativeExceção ex) when (ex.Message.Contains("AVX"))
{
    // CPU does not support AVX instructions
    Console.Error.WriteLine($"Hardware incompatibility: {ex.Message}");
}
catch (IronOcrLicensingExceção)
{
    Console.Error.WriteLine("License key is missing or invalid.");
}
catch (IronOcrProductExceção 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

Nós ordenamos blocos catch do mais específico ao mais geral. A cláusula when em IronOcrNativeExceção filtra falhas relacionadas a AVX sem capturar erros nativos não relacionados. Cada manipulador registra contexto suficiente — mensagem, rastreamento de pilha — para análise post-mortem.


Como Validar a Saída do OCR com Pontuações de Confiança?

Cada OcrResult carrega uma propriedade Confidence — um valor entre 0 e 1 representando a certeza estatística do mecanismo, média entre todos os caracteres reconhecidos. Acessamos isso em todos os níveis da hierarquia de resultados: documento, página, parágrafo, palavra e caractere.

Um padrão de validação com limiar evita que saídas de OCR de baixa qualidade se propaguem para outras etapas:

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

Este padrão é essencial em pipelines onde o OCR alimenta entrada de dados, processamento de faturas ou fluxos de trabalho de conformidade. A análise por palavra identifica exatamente quais regiões da imagem de origem causaram degradação — podemos então aplicar filtros de qualidade de imagem ou correções de orientação e reprocessar. Para um olhar mais profundo sobre a pontuação de confiança, veja o guia de níveis de confiança.


Como Monitorar o Progresso do OCR em Tempo Real?

Para documentos de várias páginas, o evento OcrProgress em IronTesseract relata o status após a conclusão de cada página. O objeto OcrProgressEventArgs expõe ProgressPercent, Duration, TotalPages, PagesComplete, StartTimeUTC, e 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

Conectamos esse evento à nossa infraestrutura de registro para acompanhar a duração do trabalho de OCR e detectar atrasos. Se Duration excede um limiar sem que ProgressPercent avance, o pipeline pode sinalizar o trabalho para investigação. Isso é particularmente útil para processamento em lote de PDFs, onde uma única página malformada pode atrasar o trabalho inteiro.


Como Lidar com Erros em Pipelines de OCR em Lote?

Sistemas de OCR de produção processam centenas ou milhares de arquivos. Uma única falha não deve interromper o pipeline. Isolamos erros por arquivo, registramos falhas com contexto, e produzimos um relatório resumido ao final.

using IronOcr;
using IronOcr.Exceçãos;

var ocr = new IronTesseract();
Installation.LogFilePath = "batch_debug.log";
Installation.LoggingModo = Installation.LoggingModos.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 (IronOcrInputExceção ex)
    {
        failed++;
        failures.Add((file, $"Input error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (IronOcrProductExceção ex)
    {
        failed++;
        failures.Add((file, $"Engine error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (Exceção 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.Exceçãos;

var ocr = new IronTesseract();
Installation.LogFilePath = "batch_debug.log";
Installation.LoggingModo = Installation.LoggingModos.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 (IronOcrInputExceção ex)
    {
        failed++;
        failures.Add((file, $"Input error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (IronOcrProductExceção ex)
    {
        failed++;
        failures.Add((file, $"Engine error: {ex.Message}"));
        Console.Error.WriteLine($"FAIL: {Path.GetFileName(file)} — {ex.Message}");
    }
    catch (Exceção 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

O bloco externo catch (Exceção) lida com erros imprevistos — tempos de espera de rede em armazenamento compartilhado, problemas de permissão ou condições de falta de memória em grandes TIFFs. Cada falha registra o caminho do arquivo e a mensagem de erro para o resumo, enquanto o loop continua processando os arquivos restantes. O arquivo de log em batch_debug.log captura detalhes de nível de mecanismo para qualquer arquivo que desencadeie diagnósticos internos.

Para execução não bloqueante em serviços ou aplicações web, IronOCR suporta ReadAsync — encapsule a chamada await ocr.ReadAsync(input) na mesma estrutura try-catch.


Como Depurar a Precisão do OCR?

Quando as pontuações de confiança são consistentemente baixas, o problema geralmente é a imagem de entrada, em vez do mecanismo OCR. IronOCR fornece ferramentas de pré-processamento para resolver isso:

  • Filtros de qualidade de imagem — filtros de nitidez, redução de ruído, dilatação e erosão melhoram a clareza do texto antes do reconhecimento.
  • Correção de orientação — correção automática de deskew e rotação para documentos escaneados.
  • Aumento de DPI — imagens de baixa resolução se beneficiam do ajuste de DPI antes do processamento.
  • Visão computacional — detecção de região de texto baseada em OpenCV isola áreas de texto em layouts complexos.
  • Utilitário IronOCR — uma ferramenta de desktop para testar visualmente combinações de filtros e exportar a configuração ideal em C#.

Para problemas específicos de implantação (runtimes ausentes, erros de biblioteca nativa), IronOCR mantém guias de solução de problemas dedicados para Azure Functions, Docker e Linux e configuração geral do ambiente.


Para Onde Ir a Partir Daqui?

Este guia abordou a depuração em tempo de execução — registro, exceções, validação de confiança, monitoramento de progresso e tratamento de erros em lote. Para tópicos relacionados, explore:

Compre uma licença do IronOCR para implantação em produção, ou inicie uma avaliação gratuita de 30 dias para testar esses padrões de depuração em seu ambiente.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais
Pronto para começar?
Nuget Downloads 5,525,971 | Versão: 2026.3 acaba de ser lançado
Still Scrolling Icon

Ainda está rolando a tela?

Quer provas rápidas? PM > Install-Package IronOcr
executar um exemplo Veja sua imagem se transformar em texto pesquisável.