Saltar al contenido principal
Este escenario se utiliza para extraer todos los datos posibles de un documento y almacenarlos de forma estructurada. El resultado es un archivo JSON que representa la estructura del documento. Almacena todos los objetos del documento: texto impreso y escrito a mano, tablas, códigos de barras, marcas de verificación e imágenes con su ubicación y atributos. Este formato es óptimo para su procesamiento posterior, para almacenar datos en una base de datos o para integrarlo con otra aplicación. En este escenario, un documento pasa por varias etapas de procesamiento:
  1. Preprocesamiento de imágenes escaneadas o fotografías
Es posible que las imágenes obtenidas con un escáner o una cámara digital necesiten algunos ajustes antes de poder reconocerse ópticamente. Por ejemplo, las imágenes con ruido o con líneas de texto distorsionadas requerirán cierta corrección para que el reconocimiento óptico se realice correctamente.
  1. Extracción de todos los datos del documento de forma estructurada
Durante el análisis del diseño, se detectan varios objetos en la imagen y se agrupan en bloques del tipo correspondiente. Los bloques se reconocen según la configuración óptima para su tipo. Durante la síntesis, la estructura lógica del documento se reconstruye de forma coherente. El orden del texto, incluso en diseños complejos, se conserva para que se parezca a cómo lo leería una persona. Esto garantiza que, si se vuelve a reconocer el mismo documento, el orden del texto sea el mismo.
  1. Exportación a un formato estructurado
El documento reconocido se guarda en JSON o XML.

Implementación del escenario

Los ejemplos de código proporcionados en este tema son específicos de Windows.
A continuación, encontrará una descripción detallada del método recomendado para usar ABBYY FineReader Engine 12 para extraer datos de los documentos. El método propuesto utiliza la configuración de procesamiento más adecuada para este propósito.
Para comenzar a trabajar con ABBYY FineReader Engine, es necesario crear el objeto Engine. El objeto Engine es el objeto de nivel superior en la jerarquía de objetos de ABBYY FineReader Engine y proporciona diversas configuraciones globales, 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 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("No se puede cargar " + enginePath);
            }
            IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
            if (initializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("No se encuentra la función InitializeEngine");
            }
            IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
            if (deinitializeEnginePtr == IntPtr.Zero)
            {
                throw new Exception("No se encuentra la función DeinitializeEngine");
            }
            IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
            if (dllCanUnloadNowPtr == IntPtr.Zero)
            {
                throw new Exception("No se encuentra la función DllCanUnloadNow");
            }
            // Convertir 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;
}

C++ (COM)

// Inicialice estas variables con la ruta a FREngine.dll, el Customer Project ID de FineReader Engine,
// y, si corresponde, la ruta al token de licencia en línea y la contraseña de licencia en línea
wchar_t* FreDllPath;
wchar_t* CustomerProjectId;
wchar_t* LicensePath;  // si no utiliza una licencia en línea, asigne cadenas vacías a estas variables
wchar_t* LicensePassword;
// HANDLE de FREngine.dll
static HMODULE libraryHandle = 0;
// Objeto global de FineReader Engine
FREngine::IEnginePtr Engine;
void LoadFREngine()
{
    if( Engine != 0 ) {
    // Ya cargado
    return;
    }
    // Primer paso: cargar FREngine.dll
    if( libraryHandle == 0 ) {
        libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
        if( libraryHandle == 0 ) {
            throw L"Error al cargar ABBYY FineReader Engine";
        }
    }
    // Segundo paso: obtener el objeto Engine
    typedef HRESULT ( STDAPICALLTYPE* InitializeEngineFunc )( BSTR, BSTR, BSTR, BSTR, 
        BSTR, VARIANT_BOOL, FREngine::IEngine** );
    InitializeEngineFunc pInitializeEngine =
    ( InitializeEngineFunc )GetProcAddress( libraryHandle, "InitializeEngine" );
    if( pInitializeEngine == 0 || pInitializeEngine( CustomerProjectId, LicensePath, 
        LicensePassword, L"", L"", VARIANT_FALSE, &Engine ) != S_OK ) {
    UnloadFREngine();
    throw L"Error al cargar ABBYY FineReader Engine";
    }
}
ABBYY FineReader Engine permite cargar, mediante el método LoadPredefinedProfile del objeto Engine, toda la configuración de procesamiento más adecuada para este escenario. Este método recibe el nombre del perfil como parámetro de entrada. Para obtener más información, consulte Working with Profiles.La configuración para este escenario está disponible en el perfil predefinido DataExtraction:
  • El análisis del diseño y el reconocimiento priorizan la precisión frente a la velocidad.
  • Detecta todo el texto de una imagen, incluido el texto escrito a mano y las áreas de texto pequeñas de baja calidad.
  • Detecta tablas, marcas de verificación y códigos de barras.
  • Se realiza una síntesis completa de la estructura lógica de un documento.

C#

// Cargar un perfil predefinido
engine.LoadPredefinedProfile("DataExtraction");

C++ (COM)

// Cargar un perfil predefinido
Engine->LoadPredefinedProfile( L"DataExtraction" );
Si desea cambiar la configuración de procesamiento, use los objetos Parameter correspondientes. Para obtener más información, consulte la sección Additional optimization a continuación.
ABBYY FineReader Engine proporciona el objeto FRDocument, que permite procesar documentos de varias páginas. El uso de este objeto le permite conservar la organización lógica del documento y mantener el texto, las columnas, las fuentes, los estilos, etc. originales.Para cargar las imágenes de un solo documento y preprocesarlas, debe crear el objeto FRDocument y agregarle imágenes. Puede hacerlo de una de las siguientes maneras:

C#

// Crear el objeto FRDocument a partir de un archivo de imagen
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );

C++ (COM)

// Crear el objeto FRDocument a partir de un archivo de imagen
FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
Para reconocer un documento, le recomendamos usar los métodos de análisis y reconocimiento del objeto FRDocument. Este objeto ofrece toda una gama de métodos para analizar, reconocer y sintetizar documentos. El método más práctico, que reúne en uno solo el análisis, el reconocimiento y la síntesis del documento, es Process. Además, aprovecha de la forma más eficiente las funciones de procesamiento simultáneo de los sistemas multiprocesador y multinúcleo. No obstante, también puede realizar el preprocesamiento, el análisis, el reconocimiento y la síntesis de forma consecutiva mediante los métodos Preprocess, Analyze, Recognize y Synthesize.

C#

// Analizar, reconocer y sintetizar el documento
// No se necesitan parámetros adicionales porque los establece el perfil de procesamiento
frDocument.Process( null );

C++ (COM)

// Analizar, reconocer y sintetizar el documento
// No se necesitan parámetros adicionales porque los establece el perfil de procesamiento
frDocument->Process( 0 );
Para guardar un documento reconocido, puede usar el método Export del objeto FRDocument y especificar la constante FileExportFormatEnum como uno de los parámetros. Puede cambiar los parámetros de exportación predeterminados mediante el objeto de exportación correspondiente. Consulte Optimización adicional para tareas específicas más abajo para obtener más información.Cuando haya terminado de trabajar con el objeto FRDocument, libere todos los recursos que haya utilizado este objeto. Use el método IFRDocument::Close.

C#

// Guardar el documento reconocido en un formato estructurado
frDocument.Export( "C:\\Data.json", FREngine.FileExportFormatEnum.FEF_JSON, null );
// Liberar el objeto FRDocument
frDocument.Close();

C++ (COM)

// Guardar el documento reconocido en un formato estructurado
frDocument->Export( L"C:\\Data.json", FREngine::FEF_JSON, 0 );
// Liberar el objeto FRDocument
frDocument->Close();
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 llamar 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;
    // Identificador de FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

C++ (COM)

void UnloadFREngine()
{
 if( libraryHandle == 0 ) {
  return;
 }
 // Liberar el objeto Engine
 Engine = 0;
 // Desinicializar FineReader Engine
 typedef HRESULT ( STDAPICALLTYPE* DeinitializeEngineFunc )();
 DeinitializeEngineFunc pDeinitializeEngine =
  ( DeinitializeEngineFunc )GetProcAddress( libraryHandle, "DeinitializeEngine" );
 if( pDeinitializeEngine == 0 || pDeinitializeEngine() != S_OK ) {
  throw L"Error al descargar ABBYY FineReader Engine";
 }
 // Ahora es seguro liberar la biblioteca FREngine.dll
 FreeLibrary( libraryHandle );
 libraryHandle = 0;
}

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 los siguientes valores en la columna 5 (RequiredByModule): 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 en consecuencia. También debe especificar los idiomas de la interfaz, los idiomas de reconocimiento y cualquier funcionalidad adicional que utilice su aplicación (como, por ejemplo, Opening.PDF si necesita abrir archivos PDF, o Processing.OCR.CJK si necesita reconocer texto en idiomas CJK). Consulte Working with the FREngineDistribution.csv File para obtener más información.

Optimización adicional para tareas específicas

A continuación, se ofrece una descripción general de los temas de Ayuda que contienen información adicional sobre la personalización de la configuración en las distintas etapas de la conversión de documentos a un formato editable:
  • Escaneo: solo Windows
    • Escaneo
      Descripción del escenario de ABBYY FineReader Engine para el escaneo de documentos.
  • Reconocimiento
    • Ajuste de parámetros de preprocesamiento, análisis, reconocimiento y síntesis
      Personalización del procesamiento de documentos mediante objetos de parámetros de análisis, reconocimiento y síntesis.
    • Objeto PageProcessingParams
      Este objeto permite personalizar los parámetros de análisis y reconocimiento. Con este objeto, puede indicar qué características de la imagen y del texto deben detectarse (imagen invertida, orientación, códigos de barras, idioma de reconocimiento, margen de error de reconocimiento).
    • Objeto SynthesisParamsForPage
      Este objeto incluye los parámetros responsables de restaurar el formato de una página durante la síntesis.
    • Objeto SynthesisParamsForDocument
      Este objeto permite personalizar la síntesis del documento: restaurar su estructura y formato.
    • Objeto MultiProcessingParams - Implementado para Linux y Windows
      El procesamiento simultáneo puede ser útil al procesar un gran número de imágenes. En este caso, la carga de procesamiento se distribuirá entre los núcleos del procesador durante la apertura y el preprocesamiento de imágenes, el análisis de diseño, el reconocimiento y la exportación, lo que permite acelerar el procesamiento.
      Los modos de lectura (simultáneo o consecutivo) se establecen mediante la propiedad MultiProcessingMode. La propiedad RecognitionProcessesCount controla el número de procesos que pueden iniciarse.
  • Exportación

Consulte también

Implementación de escenarios de uso básicos