Saltar al contenido principal
Los documentos oficiales de viaje o de identidad de muchos países contienen una zona de lectura mecánica (MRZ) que permite procesar con mayor precisión los datos del documento. La MRZ incluye 2 o 3 líneas de texto en fuente OCR-B, redactadas de conformidad con el Documento 9303 de ICAO (consulte las especificaciones en el sitio web de la ICAO). Este escenario se utiliza para extraer datos de una zona de lectura mecánica en documentos de identidad durante procesos de alta o verificación de clientes. El sistema reconoce la MRZ en la imagen del documento y extrae sus datos. Los datos extraídos contienen varios campos con información personal del documento y de su titular (tipo de documento y fecha de vencimiento, nombre y apellidos del titular del documento, etc.). Puede buscar en los campos, verificar los datos y guardarlos en un archivo externo para su posterior procesamiento. Para extraer los datos de la MRZ, los archivos de imagen obtenidos mediante escaneado o almacenados en formato electrónico suelen pasar por varias etapas de procesamiento, cada una con sus propias particularidades:
  1. Preprocesamiento de imágenes escaneadas o fotografías
Puede escanear o tomar una foto de la página de identidad de un documento de identidad con MRZ. Las fotos tomadas con las cámaras digitales de dispositivos móviles pueden tener baja resolución y calidad. Además, las imágenes pueden requerir cierto preprocesamiento antes del reconocimiento.
  1. Extracción de datos de la MRZ
De cada imagen solo puede capturarse una MRZ. El texto de cada una de las 2 o 3 líneas se reconocerá y analizará para extraer los campos de datos. Algunos campos, así como la MRZ en su conjunto, tienen dígitos de control que le ayudarán a verificar los datos.
  1. Exportación a un archivo externo
También puede guardar los datos extraídos en un formato externo: se admiten XML y JSON. El procedimiento que se describe a continuación está implementado en el ejemplo de código MRZExtraction para Linux y Windows.

Implementación del escenario

Los ejemplos de código proporcionados en este tema son específicos de Windows.
A continuación, se ofrece una descripción detallada del método recomendado para usar ABBYY FineReader Engine 12 en este escenario. Este método utiliza la configuración de procesamiento más adecuada para este caso.
Para comenzar a trabajar con ABBYY FineReader Engine, debe crear el objeto Engine. El objeto Engine es el objeto principal en la jerarquía de objetos de ABBYY FineReader Engine y proporciona varias opciones de configuración global, algunos métodos de procesamiento y métodos para crear los demás objetos.Para crear el objeto Engine, puede usar la función InitializeEngine. Consulte también otras formas de cargar el objeto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inicialice estas variables con la ruta completa a FREngine.dll, su Customer Project ID
        // y, si corresponde, la ruta al archivo de token de su licencia en línea y la contraseña de la licencia en línea
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Cargar la 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");
            }
            // Convertir los punteros en delegados
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Llamar a la función InitializeEngine 
            // pasando la ruta al archivo de licencia en línea y la contraseña de la licencia en línea
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Liberar la biblioteca FREngine.dll
            engine = null;
            // Eliminar todos los objetos antes de llamar a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funciones 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);
    // Funciones 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();
    // Variables 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;
}
Puede cargar la configuración de procesamiento adecuada para este escenario mediante el método LoadPredefinedProfile del objeto Engine. Este método usa como parámetro de entrada el nombre de un perfil de configuración. Consulte Trabajo con perfiles para obtener más información.La configuración para este escenario está disponible en el perfil predefinido MachineReadableZone:
  • Habilita la detección y extracción de todo el texto de una imagen (no se detectan imágenes, gráficos vectoriales ni tablas).
  • La corrección de la resolución y la geometría se realiza automáticamente.

C#

// Cargar el perfil predefinido
engine.LoadPredefinedProfile("MachineReadableZone");
Si desea cambiar la configuración de procesamiento, use los objetos Parameter adecuados. Consulte Optimización adicional para tareas específicas más abajo para obtener más información.La captura de MRZ solo es posible si su licencia de ABBYY FineReader Engine admite el módulo MRZCapture.
Para cargar imágenes en FineReader Engine, puede usar los métodos de estos objetos:
Los usuarios de Linux y Windows pueden consultar las ventajas y desventajas de cada enfoque en Parallel Processing with ABBYY FineReader Engine. Este tema se centra en FRDocument.
Para cargar imágenes en el objeto FRDocument, haga una de las siguientes acciones:Todos estos métodos aceptan como parámetro de entrada un objeto PrepareImageMode, que le permite especificar distintos parámetros de preprocesamiento de imágenes. Cree este objeto llamando al método IEngine::CreatePrepareImageMode, después cambie sus Propiedades según sea necesario y páselo al método de apertura de imágenes.

C#

// Crear documento
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
// Agregar archivo de imagen al documento
document.AddImageFile( imagePath, null, null );
Para extraer datos de la MRZ:
  1. [opcional] Cree el objeto MrzProcessingParams mediante el método CreateMrzProcessingParams del objeto Engine. Configure sus propiedades con los valores que necesite.
  2. Llame al método ExtractMrz del objeto FRPage y pase como parámetro de entrada el objeto MrzProcessingParams que configuró en el paso anterior; para usar la configuración predeterminada de captura de MRZ, simplemente pase NULL. Recibirá un objeto MrzData con la información analizada de la MRZ capturada.

C#

// Extraer MRZ
FREngine.IFRPage page = document.Pages.Item(0);
FREngine.IMrzData mrzData = page.ExtractMrz( null );
El objeto MrzData contiene todos los datos extraídos de la MRZ. Puede acceder a las líneas de texto legible por máquina mediante el método GetLine y recorrer los campos mediante los métodos GetField y GetFieldByType. Se extraen campos de los siguientes tipos:
  • Tipo de documento
  • Subtipo de documento
  • País emisor
  • Apellido
  • Nombre
  • Número de documento
  • Nacionalidad
  • Fecha de nacimiento
  • Sexo
  • Fecha de vencimiento
  • Número personal
  • Datos opcionales de la línea 1
  • Datos opcionales de la línea 2
El objeto MrzField proporciona información completa sobre el campo extraído. Use su propiedad Text para obtener el valor del campo y la propiedad Region para obtener la ubicación del campo en la imagen. Para verificar los datos, use las sumas de comprobación disponibles a través de las propiedades Checksum, HasChecksum e IsChecksumVerified de los objetos MrzData y MrzField. No todos los tipos de campo admiten sumas de comprobación; la propiedad HasChecksum se proporciona para que pueda comprobar su valor antes de intentar recuperar la suma de comprobación.Puede editar manualmente el texto reconocido de los campos mediante los métodos Insert y Remove del objeto MrzField.

C#

// Verificar la suma de comprobación del número de documento
FREngine.IMrzField documentNumberField = mrzData.GetFieldByType(FREngine.MrzFieldTypeEnum.MFT_DocumentNumber);
bool isNumberVerified = documentNumberField.IsChecksumVerified;
Los datos extraídos pueden guardarse en un archivo XML o JSON. Para exportarlos con los parámetros predeterminados, llame al método ExportToFile del objeto MrzData y pase la ruta del archivo como parámetro de entrada. Para exportarlos con parámetros definidos por el usuario, llame al método ExportToFileEx del objeto MrzData y pase como parámetro de entrada un puntero al objeto MrzJsonExportParams o al objeto MrzXmlExportParams.C#
// Guardar en formato XML
mrzData.ExportToFile("C:\\ExtractedData.xml", FREngine.MrzExportFormatEnum.MEF_Xml);
Después de terminar de trabajar con ABBYY FineReader Engine, debe descargar el objeto Engine. Para ello, use la función exportada DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Descargar FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // Engine no se cargó
            return;
        }
        engine = null;
        // Eliminar todos los objetos antes de la llamada 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;
        // generar la excepción después de la limpieza
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funciones 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);
    // Funciones 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();
    // variables privadas
    private FREngine.IEngine engine = null;
    // Handle a FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Recursos necesarios

Puede usar el archivo FREngineDistribution.csv para crear automáticamente una lista de los archivos necesarios para que su aplicación funcione. Para procesar con este escenario, seleccione en la columna 5 (RequiredByModule) los siguientes 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 Si modifica el escenario estándar, cambie los módulos necesarios según corresponda. También debe especificar los idiomas de la interfaz, los idiomas de reconocimiento y cualquier característica adicional que use su aplicación (por ejemplo, Opening.PDF si necesita abrir archivos PDF). Consulte Uso del archivo FREngineDistribution.csv para obtener más información.

Optimización adicional

Estas son las secciones del archivo de ayuda en las que puede encontrar información adicional sobre la configuración de los parámetros para las distintas etapas de procesamiento:

Consulte también

Implementación de escenarios básicos de uso