Pular para o conteúdo principal
Os documentos oficiais de viagem ou de identidade de muitos países contêm uma zona legível por máquina (MRZ) que garante um processamento mais preciso dos dados do documento. A MRZ inclui 2 ou 3 linhas com texto na fonte OCR-B, escritas de acordo com o Documento 9303 da ICAO (consulte as especificações no site da ICAO). Este cenário é usado para extrair dados de uma zona legível por máquina em documentos de identidade durante processos de cadastro ou verificação de clientes. O sistema reconhece a MRZ na imagem do documento e extrai seus dados. Os dados extraídos contêm vários campos com informações pessoais sobre o documento e seu titular (tipo de documento, data de validade, nome e sobrenome do titular etc.). Você pode pesquisar os campos, verificar os dados e salvá-los em um arquivo externo para processamento posterior. Para extrair os dados da MRZ, arquivos de imagem obtidos por digitalização ou salvos em formato eletrônico normalmente passam por várias etapas de processamento, cada uma com suas próprias particularidades:
  1. Pré-processamento de imagens digitalizadas ou fotos
Você pode digitalizar ou tirar uma foto da página de identificação de um documento de identidade com MRZ. Fotos tiradas com câmeras digitais de dispositivos móveis podem ter baixa resolução e qualidade. Além disso, as imagens podem exigir algum pré-processamento antes do reconhecimento.
  1. Extração de dados da MRZ
No máximo, uma MRZ pode ser capturada de cada imagem. O texto de cada uma das 2 ou 3 linhas será reconhecido e analisado para extrair os campos de dados. Alguns dos campos, assim como a MRZ como um todo, têm checksums, o que ajudará você a validar os dados.
  1. Exportação para um arquivo externo
Você também pode salvar os dados extraídos em um formato externo: XML e JSON são compatíveis. O procedimento descrito abaixo é implementado no exemplo de código MRZExtraction para Linux e Windows.

Implementação do cenário

Os exemplos de código fornecidos neste tópico são específicos do Windows.
A seguir, apresentamos uma descrição detalhada do método recomendado para usar o ABBYY FineReader Engine 12 neste cenário. O método proposto usa as configurações de processamento mais adequadas para esse cenário.
Para começar a trabalhar com o ABBYY FineReader Engine, você precisa criar o objeto Engine. O objeto Engine é o objeto de nível superior na hierarquia de objetos do ABBYY FineReader Engine e fornece várias configurações globais, alguns métodos de processamento e métodos para criar os demais objetos.Para criar o objeto Engine, você pode usar a função InitializeEngine. Consulte também outras formas de carregar o objeto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicialize estas variáveis com o caminho completo para FREngine.dll, seu ID do projeto do cliente,
        // e, se aplicável, o caminho para o arquivo de token da Licença Online e a senha da Licença Online
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carrega a biblioteca FREngine.dll
        dllHandle = LoadLibraryEx(enginePath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);
           
        try
        {
            if (dllHandle == IntPtr.Zero)
            {
                throw new Exception("Can't load " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find InitializeEngine function");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DeinitializeEngine function");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("Can't find DllCanUnloadNow function");
            }
            // Converte os ponteiros em delegates
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chama a função InitializeEngine 
            // passando o caminho para o arquivo de Licença Online e a senha da Licença Online
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera a biblioteca FREngine.dll
            engine = null;
            // Exclui todos os objetos antes da chamada a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funções da Kernel32.dll
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // Funções de FREngine.dll
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine(string customerProjectId, string licensePath, 
        string licensePassword, string tempFolder, string dataFolder, bool isSharedCPUCoresMode, 
        ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // Variáveis privadas
    private FREngine.IEngine engine = null;
    // Handle para FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}
Você pode carregar as configurações de processamento adequadas para este cenário usando o método LoadPredefinedProfile do objeto Engine. Esse método usa o nome de um perfil de configurações como parâmetro de entrada. Consulte Working with Profiles para mais informações.As configurações para este cenário estão disponíveis no perfil predefinido MachineReadableZone:
  • Habilita a detecção e a extração de todo o texto da imagem (figuras, gráficos vetoriais e tabelas não são detectados).
  • A correção de resolução e geometria é realizada automaticamente.

C#

// Carrega o perfil predefinido
engine.LoadPredefinedProfile("MachineReadableZone");
Se quiser alterar as configurações de processamento, use os objetos Parameter apropriados. Consulte Additional optimization for specific tasks abaixo para mais informações.A captura de MRZ só é possível se sua licença do ABBYY FineReader Engine oferecer suporte ao módulo MRZCapture.
Para carregar imagens no FineReader Engine, você pode usar os métodos destes objetos:
Usuários de Linux e Windows podem saber mais sobre as vantagens e desvantagens de cada abordagem em Parallel Processing with ABBYY FineReader Engine. Este tópico se concentra em FRDocument .
Para carregar imagens no objeto FRDocument, faça um dos seguintes procedimentos:Todos esses métodos recebem como parâmetro de entrada um objeto PrepareImageMode, que permite especificar diferentes parâmetros de pré-processamento da imagem. Crie esse objeto chamando o método IEngine::CreatePrepareImageMode, depois altere suas propriedades conforme necessário e passe-o para o método de abertura da imagem.

C#

// Cria o documento
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
// Adiciona o arquivo de imagem ao documento
document.AddImageFile( imagePath, null, null );
Para extrair dados da MRZ:
  1. [opcional] Crie o objeto MrzProcessingParams com a ajuda do método CreateMrzProcessingParams do objeto Engine. Configure suas propriedades com os valores necessários.
  2. Chame o método ExtractMrz do objeto FRPage, passando como parâmetro de entrada o objeto MrzProcessingParams configurado na etapa anterior; para usar as configurações padrão de captura da MRZ, basta passar NULL. Você receberá um objeto MrzData contendo as informações extraídas da MRZ capturada.

C#

// Extrair MRZ
FREngine.IFRPage page = document.Pages.Item(0);
FREngine.IMrzData mrzData = page.ExtractMrz( null );
O objeto MrzData contém todos os dados extraídos da MRZ. Você pode acessar as linhas de texto legível por máquina usando o método GetLine e percorrer os campos usando os métodos GetField e GetFieldByType. São extraídos campos dos seguintes tipos:
  • Tipo de documento
  • Subtipo de documento
  • País emissor
  • Sobrenome
  • Nome próprio
  • Número do documento
  • Nacionalidade
  • Data de nascimento
  • Sexo
  • Data de validade
  • Número pessoal
  • Linha 1 de dados opcionais
  • Linha 2 de dados opcionais
O objeto MrzField fornece informações completas sobre o campo extraído. Use sua propriedade Text para obter o valor do campo e a propriedade Region para obter a localização do campo na imagem. Para verificar os dados, use os checksums disponíveis por meio das propriedades Checksum, HasChecksum e IsChecksumVerified dos objetos MrzData e MrzField. Nem todos os tipos de campo oferecem suporte a checksum; a propriedade HasChecksum é fornecida para que você possa verificar esse valor antes de tentar recuperá-lo.Você pode editar manualmente o texto reconhecido dos campos usando os métodos Insert e Remove do objeto MrzField.

C#

// Verificar o checksum do número do documento
FREngine.IMrzField documentNumberField = mrzData.GetFieldByType(FREngine.MrzFieldTypeEnum.MFT_DocumentNumber);
bool isNumberVerified = documentNumberField.IsChecksumVerified;
Os dados extraídos podem ser salvos em um arquivo XML ou JSON. Para exportar os dados com os parâmetros padrão, chame o método ExportToFile do objeto MrzData e passe o caminho do arquivo como parâmetro de entrada. Para exportar os dados com parâmetros definidos pelo usuário, chame o método ExportToFileEx do objeto MrzData e passe como parâmetro de entrada o ponteiro para o objeto MrzJsonExportParams ou para o objeto MrzXmlExportParams.C#
// Salvar no formato XML
mrzData.ExportToFile("C:\\ExtractedData.xml", FREngine.MrzExportFormatEnum.MEF_Xml);
Após concluir o trabalho com o ABBYY FineReader Engine, você precisa descarregar o objeto Engine. Para isso, use a função exportada DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Descarregar o FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // O Engine não foi carregado
            return;
        }
        engine = null;
        // Excluir todos os objetos antes da chamada a FreeLibrary
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        int hresult = deinitializeEngine();
 
        hresult = dllCanUnloadNow();
        if (hresult == 0)
        {
            FreeLibrary(dllHandle);
        }
        dllHandle = IntPtr.Zero;
        initializeEngine = null;
        deinitializeEngine = null;
        dllCanUnloadNow = null;
        // Gerar a exceção após a limpeza
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funções de Kernel32.dll
    [DllImport("kernel32.dll")]
    private static extern IntPtr LoadLibraryEx(string dllToLoad, IntPtr reserved, uint flags);
    private const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;
    [DllImport("kernel32.dll")]
    private static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
    [DllImport("kernel32.dll")]
    private static extern bool FreeLibrary(IntPtr hModule);
    // Funções de FREngine.dll
    [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
    private delegate int InitializeEngine( string customerProjectId, string LicensePath, string LicensePassword, , , , ref FREngine.IEngine engine);
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DeinitializeEngine();
    [UnmanagedFunctionPointer(CallingConvention.StdCall)]
    private delegate int DllCanUnloadNow();
    // variáveis privadas
    private FREngine.IEngine engine = null;
    // Handle de FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Recursos necessários

Você pode usar o arquivo FREngineDistribution.csv para criar automaticamente uma lista dos arquivos necessários para o funcionamento do seu aplicativo. Para o processamento neste cenário, selecione na coluna 5 (RequiredByModule) os seguintes valores: Core Core.Resources Opening Opening, Processing Processing Processing.OCR Processing.OCR, Processing.ICR Processing.OCR.NaturalLanguages Processing.OCR.NaturalLanguages, Processing.ICR.NaturalLanguages Export Export, Processing Se você modificar o cenário padrão, ajuste os módulos necessários conforme apropriado. Você também precisa especificar os idiomas da interface, os idiomas de reconhecimento e quaisquer recursos adicionais usados pelo seu aplicativo (como, por exemplo, Opening.PDF, se você precisar abrir arquivos PDF). Consulte Working with the FREngineDistribution.csv File para mais detalhes.

Otimização adicional

Estas são as seções do arquivo de Ajuda em que você pode encontrar informações adicionais sobre como configurar os parâmetros para as várias etapas do processamento:

Veja também

Implementação de cenários básicos de uso