Vai al contenuto principale
I documenti di viaggio ufficiali o i documenti d’identità di molti Paesi contengono una zona leggibile da macchina (MRZ) che garantisce un’elaborazione più accurata dei dati del documento. La MRZ comprende 2 o 3 righe di testo nel font OCR-B, scritte in conformità al Documento 9303 dell’ICAO (vedere le specifiche sul sito web dell’ICAO). Questo scenario viene utilizzato per estrarre dati da una zona leggibile da macchina presente su documenti d’identità durante i processi di onboarding o verifica dei clienti. Il sistema riconosce la MRZ nell’immagine del documento ed estrae i dati da essa. I dati estratti contengono diversi field con le informazioni personali relative al documento e al suo titolare (tipo di documento e data di scadenza, nome e cognome del titolare del documento, ecc.). È possibile cercare nei field, verificare i dati e salvarli in un file esterno per un’ulteriore elaborazione. Per estrarre i dati dalla MRZ, i file immagine ottenuti tramite scansione o salvati in formato elettronico passano in genere attraverso diverse fasi di elaborazione, ciascuna con le proprie peculiarità:
  1. Preelaborazione di immagini scansionate o fotografie
È possibile acquisire tramite scansione o scattare una foto della pagina identificativa di un documento d’identità con MRZ. Le foto scattate con le fotocamere digitali dei dispositivi mobili possono avere risoluzione e qualità ridotte. Inoltre, le immagini possono richiedere una certa preelaborazione prima del riconoscimento.
  1. Estrazione dei dati dalla MRZ
Da ciascuna immagine può essere acquisita una sola MRZ. Il testo di ciascuna delle 2 o 3 righe verrà riconosciuto e analizzato per estrarre i field di dati. Alcuni dei field e la MRZ nel suo complesso dispongono di checksum, che consentono di verificare i dati.
  1. Esportazione in un file esterno
È inoltre possibile salvare i dati estratti in un formato esterno: sono supportati XML e JSON. La procedura descritta di seguito è implementata nell’esempio di codice MRZExtraction per Linux e Windows.

Implementazione dello scenario

Gli esempi di codice forniti in questo argomento sono specifici per Windows.
Di seguito è riportata una descrizione dettagliata del metodo consigliato per utilizzare ABBYY FineReader Engine 12 in questo scenario. Il metodo proposto utilizza le impostazioni di elaborazione più adatte a questo scenario.
Per iniziare a lavorare con ABBYY FineReader Engine, è necessario creare l’oggetto Engine. L’oggetto Engine è l’oggetto principale nella gerarchia degli oggetti di ABBYY FineReader Engine e fornisce diverse impostazioni globali, alcuni metodi di elaborazione e i metodi per creare gli altri oggetti.Per creare l’oggetto Engine, è possibile usare la funzione InitializeEngine. Vedere anche altri modi per caricare l’oggetto Engine (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Inizializzare queste variabili con il percorso completo di FREngine.dll, il proprio Customer Project ID,
        // e, se applicabile, il percorso del file token della licenza online e la password della licenza online
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Carica la libreria 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 i puntatori in delegati
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Chiama la funzione InitializeEngine 
            // passando il percorso del file della licenza online e la password della licenza online
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Libera la libreria FREngine.dll
            engine = null;
            // Elimina tutti gli oggetti prima della chiamata a FreeLibrary
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funzioni di 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);
    // Funzioni di 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();
    // Variabili private
    private FREngine.IEngine engine = null;
    // Handle della libreria FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}
È possibile caricare le impostazioni di elaborazione adatte a questo scenario utilizzando il metodo LoadPredefinedProfile dell’oggetto Engine. Questo metodo usa il nome di un profilo di impostazioni come parametro di input. Per ulteriori informazioni, vedere Uso dei profili.Le impostazioni per questo scenario sono disponibili nel profilo predefinito MachineReadableZone:
  • Consente di rilevare ed estrarre tutto il testo presente in un’immagine (immagini, grafica vettoriale e tabelle non vengono rilevate).
  • La risoluzione e la correzione geometrica vengono eseguite automaticamente.

C#

// Carica il profilo predefinito
engine.LoadPredefinedProfile("MachineReadableZone");
Se si desidera modificare le impostazioni di elaborazione, usare gli oggetti Parameter appropriati. Per ulteriori informazioni, vedere Ulteriore ottimizzazione per attività specifiche più avanti.L’acquisizione MRZ è possibile solo se la licenza di ABBYY FineReader Engine supporta il modulo MRZCapture.
Per caricare immagini in FineReader Engine, è possibile usare i metodi dei seguenti oggetti:
Gli utenti Linux e Windows possono approfondire i vantaggi e gli svantaggi di ciascun approccio in Elaborazione parallela con ABBYY FineReader Engine. Questo argomento è incentrato su FRDocument .
Per caricare immagini nell’oggetto FRDocument, eseguire una delle operazioni seguenti:Tutti questi metodi accettano come parametro di input un oggetto PrepareImageMode, che consente di specificare diversi parametri di pre-elaborazione dell’immagine. Creare questo oggetto chiamando il metodo IEngine::CreatePrepareImageMode, quindi modificarne le proprietà secondo necessità e passarlo al metodo di apertura dell’immagine.

C#

// Crea il documento
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
// Aggiungi il file immagine al documento
document.AddImageFile( imagePath, null, null );
Per estrarre i dati dall’MRZ:
  1. [facoltativo] Creare l’oggetto MrzProcessingParams mediante il metodo CreateMrzProcessingParams dell’oggetto Engine. Impostarne le proprietà con i valori desiderati.
  2. Chiamare il metodo ExtractMrz dell’oggetto FRPage, passando come parametro di input l’oggetto MrzProcessingParams configurato nel passaggio precedente; per usare le impostazioni predefinite di acquisizione MRZ, è sufficiente passare NULL. Si otterrà un oggetto MrzData contenente le informazioni analizzate dall’MRZ acquisita.

C#

// Estrai MRZ
FREngine.IFRPage page = document.Pages.Item(0);
FREngine.IMrzData mrzData = page.ExtractMrz( null );
L’oggetto MrzData contiene tutti i dati estratti dall’MRZ. È possibile accedere alle righe di testo leggibile automaticamente usando il metodo GetLine e scorrere i field usando i metodi GetField e GetFieldByType. Vengono estratti field dei seguenti tipi:
  • Tipo di documento
  • Sottotipo di documento
  • Paese emittente
  • Cognome
  • Nome
  • Numero del documento
  • Nazionalità
  • Data di nascita
  • Sesso
  • Data di scadenza
  • Numero personale
  • Dati facoltativi riga 1
  • Dati facoltativi riga 2
L’oggetto MrzField fornisce informazioni complete sul field estratto. Usare la proprietà Text per ottenere il valore del field e la proprietà Region per ottenerne la posizione nell’immagine. Per verificare i dati, usare i checksum disponibili tramite le proprietà Checksum, HasChecksum e IsChecksumVerified degli oggetti MrzData e MrzField. Non tutti i tipi di field supportano i checksum; la proprietà HasChecksum consente di verificarne il valore prima di tentare di recuperare il checksum.È possibile modificare manualmente il testo riconosciuto dei field usando i metodi Insert e Remove dell’oggetto MrzField.

C#

// Verifica il checksum del numero del documento
FREngine.IMrzField documentNumberField = mrzData.GetFieldByType(FREngine.MrzFieldTypeEnum.MFT_DocumentNumber);
bool isNumberVerified = documentNumberField.IsChecksumVerified;
I dati estratti possono essere salvati in un file XML o JSON. Per esportare i dati con i parametri predefiniti, chiamare il metodo ExportToFile dell’oggetto MrzData e passare il percorso del file come parametro di input. Per esportare i dati con parametri definiti dall’utente, chiamare il metodo ExportToFileEx dell’oggetto MrzData e passare il puntatore all’oggetto MrzJsonExportParams oppure all’oggetto MrzXmlExportParams come parametro di input.C#
// Salva in formato XML
mrzData.ExportToFile("C:\\ExtractedData.xml", FREngine.MrzExportFormatEnum.MEF_Xml);
Dopo aver terminato di usare ABBYY FineReader Engine, è necessario scaricare l’oggetto Engine. Per farlo, utilizzare la funzione esportata DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // Scarica FineReader Engine
    public void Dispose()
    {
        if (engine == null)
        {
            // Il motore non è stato caricato
            return;
        }
        engine = null;
        // Eliminazione di tutti gli oggetti prima della chiamata 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;
        // genera un'eccezione dopo la pulizia
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funzioni di 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);
    // Funzioni di 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();
    // variabili private
    private FREngine.IEngine engine = null;
    // Handle di FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Risorse necessarie

Puoi usare il file FREngineDistribution.csv per creare automaticamente un elenco dei file necessari al funzionamento della tua applicazione. Per l’elaborazione in questo scenario, seleziona nella colonna 5 (RequiredByModule) i seguenti valori: 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 modifichi lo scenario standard, aggiorna di conseguenza i moduli richiesti. Devi inoltre specificare le lingue dell’interfaccia, le lingue per il riconoscimento ed eventuali funzionalità aggiuntive usate dalla tua applicazione (ad esempio, Opening.PDF se devi aprire file PDF). Per ulteriori dettagli, vedi Working with the FREngineDistribution.csv File.

Ottimizzazione aggiuntiva

Queste sono le sezioni del file della Guida in cui puoi trovare ulteriori informazioni sulla configurazione dei parametri per le varie fasi di elaborazione:

Vedi anche

Implementazione degli scenari di utilizzo di base