Saltar al contenido principal
Las tarjetas de presentación contienen información profesional sobre una empresa o una persona. Pueden incluir el nombre de una persona, la empresa, números de teléfono, fax, correo electrónico, direcciones de sitios web y otra información similar. Puede que necesite capturar esta información de tarjetas de presentación en papel y guardarla en formato electrónico. Puede tratarse de una libreta de direcciones electrónica de un teléfono móvil, un cliente de correo electrónico o cualquier otro sistema de almacenamiento de datos. Por ejemplo, las tarjetas de presentación suelen compartirse por correo electrónico o a través de la red en formato vCard. Los pasos principales que debe realizar en este escenario son:
  1. Obtener una copia digital de una tarjeta de presentación
Puede escanear o tomar una foto de una tarjeta de presentación. Las fotos tomadas con cámaras digitales de dispositivos móviles pueden tener baja resolución y poca calidad. Por lo tanto, puede ser necesaria una preparación adicional de las imágenes.
  1. Reconocer tarjetas de presentación
Las páginas escaneadas pueden contener varias tarjetas de presentación por página. El reconocimiento debe ser de alta calidad; toda la información debe extraerse con precisión.
  1. Guardar los datos reconocidos en un formato adecuado
Puede guardar los datos reconocidos en distintos sistemas de almacenamiento de datos o exportarlos en formato vCard y enviarlos por correo electrónico.

Implementación del escenario

Los ejemplos de código proporcionados en este tema son específicos de Windows.
A continuación se describe en detalle la forma recomendada de usar ABBYY FineReader Engine en este escenario.
Para empezar a trabajar con ABBYY FineReader Engine, debe 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 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 Online License y la contraseña de Online License
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Cargue 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");
            }
            // Convierta 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));
            // Llame a la función InitializeEngine 
            // pasando la ruta al archivo de Online License y la contraseña de Online License
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libere la biblioteca FREngine.dll
            engine = null;
            // Elimine 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;
    // Identificador 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 BusinessCardsProcessing:
  • Detecta únicamente tarjetas de presentación (establece la propiedad SynthesizeBusinessCards del objeto SynthesisParamsForPage en TRUE).
  • Habilita la detección de todo el texto de una imagen, incluidas las áreas pequeñas de texto de baja calidad (no se detectan imágenes ni tablas).
  • Se realiza la corrección de resolución.
  • No se realiza la síntesis completa de la estructura lógica de un documento.

C#

// Cargar el perfil predefinido
engine.LoadPredefinedProfile("BusinessCardsProcessing");
Si desea cambiar la configuración de procesamiento, utilice los objetos de parámetros adecuados. Consulte Additional optimization for specific tasks más abajo para obtener más información.
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 Procesamiento paralelo con 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 usan como parámetro el objeto PrepareImageMode, que le permite especificar distintos parámetros de preprocesamiento de imágenes. Cree este objeto llamando a la función IEngine::CreatePrepareImageMode, después cambie sus propiedades según sea necesario y, a continuación, páselo a la función que lo requiera.

C#

FREngine.IEngine engine;
string imagePath;
FREngine.IPrepareImageMode pim = engine.CreatePrepareImageMode();
pim.DocumentType = FREngine.DocumentTypeEnum.DT_BusinessCard;
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
frDoc.AddImageFile(imagePath, pim, null);
Para reconocer tarjetas de presentación:
  1. Especifique el idioma de las tarjetas de presentación mediante el método SetPredefinedTextLanguage del objeto RecognizerParams. Consulte la lista de idiomas predefinidos disponibles para el reconocimiento de tarjetas de presentación.
  2. Configure otros parámetros de procesamiento, si es necesario. Consulte Tuning Parameters of Page Preprocessing, Analysis, Recognition, and Synthesis.
  3. Pase los parámetros a cualquiera de los métodos de procesamiento (por ejemplo, el método Process del objeto FRDocument). El método completa las colecciones de tarjetas de presentación del documento y de sus páginas (IFRDocument::BusinessCards, IFRPage::BusinessCards).
También puede sintetizar una tarjeta de presentación a partir de toda la página o de una región de cada página mediante el método SynthesizeBusinessCard o SynthesizeBusinessCardEx del objeto FRPage. El método devuelve un objeto BusinessCard. Tenga en cuenta que, en este caso, la tarjeta de presentación no se agrega a la colección de tarjetas de presentación de la página. Este enfoque es especialmente útil si selecciona el modo de procesamiento que utiliza Batch Processor.

C#

// Crear parámetros de procesamiento del documento
FREngine.IDocumentProcessingParams dpp = engine.CreateDocumentProcessingParams();
// Realizar el reconocimiento con los parámetros especificados
frDoc.Process( dpp );
// Acceder a una tarjeta de presentación
FREngine.IBusinessCard card = frDoc.BusinessCards[0];
Una tarjeta de presentación reconocida (el objeto BusinessCard) puede contener los siguientes campos:

BusinessCard_pict

  • Nombre de la persona
  • Nombre de la empresa
  • Cargo en la empresa
  • Dirección de la empresa
  • Número de teléfono
  • Fax
  • Número de teléfono móvil
  • Correo electrónico
  • Sitio web
Puede acceder a cada campo por su tipo (propiedad FieldByType) o por su índice en la colección de fields (propiedad Field). Cada campo tiene la propiedad Value, que da acceso al valor del campo en formato string. Para cada carácter del campo, están disponibles sus variantes de reconocimiento (método GetCharParams).Algunos campos pueden constar de varios componentes; por ejemplo, el campo de dirección puede contener código postal, país, estado de USA, ciudad y dirección. Para acceder a un componente del campo, puede usar la propiedad Component o el método FindComponent. La primera permite acceder al componente por su índice; la segunda lo busca por su tipo. Para cada componente, puede ver su tipo y su valor, así como obtener los parámetros y las variantes de reconocimiento de cada carácter (método GetCharParams).

C#

// Obtener el campo de nombre
FREngine.IBusinessCardField nameField = card.FieldByType( FREngine.BusinessCardFieldTypeEnum.BCFT_Name, 0 );
// Obtener el componente que contiene el nombre
FREngine.IBusinessCardFieldComponent firstNameComponent =
  nameField.FindComponent( FREngine.BusinessCardFieldComponentTypeEnum.BCFCT_FirstName );
// El nombre reconocido
string firstName = firstNameComponent.Value;
El objeto BusinessCard proporciona el método especial ExportToVCard para guardar una tarjeta de presentación en formato vCard. La ruta del archivo se pasa como parámetro.Puede guardar la tarjeta de presentación en cualquier otro formato de exportación disponible, por ejemplo, en XML.

C#

// Guardar los datos reconocidos en formato vCard
card.ExportToVCard("D:\\sample.vcf");
// Guardar en XML
frDoc.Export("D:\\Demo.xml", FREngine.FileExportFormatEnum.FEF_XML, null);
Cuando termine 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;
        // Lanzar la excepción después de limpiar
        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;
}

Recursos necesarios

Puede utilizar 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.BCR 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 requeridos según corresponda. También debe especificar los idiomas de la interfaz, los idiomas de reconocimiento y cualquier función adicional que utilice su aplicación (como, por ejemplo, Opening.PDF si necesita abrir archivos PDF, o Processing.OCR.CJK si necesita reconocer textos en idiomas CJK). Consulte Working with the FREngineDistribution.csv File para obtener más información.

Optimización adicional

Estas son las secciones del archivo de ayuda donde puede encontrar información adicional sobre cómo configurar los parámetros para las distintas etapas del procesamiento:

Consulte también

Implementación de escenarios de uso básicos