Zum Hauptinhalt springen
Die offiziellen Reise- oder Ausweisdokumente vieler Länder enthalten eine maschinenlesbare Zone (MRZ), die eine genauere Verarbeitung der Dokumentdaten ermöglicht. Die MRZ umfasst 2 oder 3 Zeilen Text in der Schriftart OCR-B, der gemäß ICAO Document 9303 geschrieben ist (siehe die Spezifikationen auf der ICAO-Website). Dieses Szenario dient dazu, während des Kunden-Onboardings oder in Verifizierungsprozessen Daten aus der maschinenlesbaren Zone von Ausweisdokumenten zu extrahieren. Das System erkennt die MRZ im Dokumentbild und extrahiert die darin enthaltenen Daten. Die extrahierten Daten umfassen mehrere Felder mit personenbezogenen Angaben zum Dokument und zu seinem Inhaber (Dokumenttyp und Ablaufdatum, Vor- und Nachname des Dokumentinhabers usw.). Sie können die Felder durchsuchen, die Daten überprüfen und sie zur weiteren Verarbeitung in einer externen Datei speichern. Um Daten aus der MRZ zu extrahieren, durchlaufen Bilddateien, die durch Scannen erstellt oder in einem elektronischen Format gespeichert wurden, in der Regel mehrere Verarbeitungsschritte, von denen jeder seine eigenen Besonderheiten hat:
  1. Vorverarbeitung gescannter Bilder oder Fotos
Sie scannen entweder die Datenseite eines Ausweisdokuments mit MRZ oder machen ein Foto davon. Mit Digitalkameras mobiler Geräte aufgenommene Fotos können eine geringe Auflösung und Qualität aufweisen. Außerdem müssen Bilder vor der Erkennung unter Umständen vorverarbeitet werden.
  1. Extrahieren von Daten aus der MRZ
Aus jedem Bild kann höchstens eine MRZ erfasst werden. Der Text jeder der 2 oder 3 Zeilen wird erkannt und analysiert, um die Datenfelder zu extrahieren. Einige der Felder sowie die MRZ insgesamt verfügen über Prüfsummen, die Sie bei der Überprüfung der Daten unterstützen.
  1. Export in eine externe Datei
Sie können die extrahierten Daten auch in einem externen Format speichern: XML und JSON werden unterstützt. Das unten beschriebene Verfahren ist im Codebeispiel MRZExtraction für Linux und Windows implementiert.

Implementierung des Szenarios

Die in diesem Thema bereitgestellten Codebeispiele sind spezifisch für Windows.
Im Folgenden finden Sie eine detaillierte Beschreibung der empfohlenen Methode für den Einsatz von ABBYY FineReader Engine 12 in diesem Szenario. Dabei werden Verarbeitungseinstellungen verwendet, die für dieses Szenario am besten geeignet sind.
Um mit ABBYY FineReader Engine zu arbeiten, müssen Sie das Engine-Objekt erstellen. Das Engine-Objekt ist das oberste Objekt in der Hierarchie der ABBYY FineReader Engine-Objekte und stellt verschiedene globale Einstellungen, einige Verarbeitungsmethoden sowie Methoden zum Erstellen anderer Objekte bereit.Zum Erstellen des Engine-Objekts können Sie die Funktion InitializeEngine verwenden. Siehe auch andere Möglichkeiten zum Laden des Engine-Objekts (Win).

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // Initialisieren Sie diese Variablen mit dem vollständigen Pfad zu FREngine.dll, Ihrer Customer Project ID
        // und ggf. dem Pfad zu Ihrer Online License-Token-Datei sowie dem Online License-Passwort
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // Die Bibliothek FREngine.dll laden
        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");
            }
            // Zeiger in Delegates umwandeln
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // Die Funktion InitializeEngine aufrufen 
            // und dabei den Pfad zur Online License-Datei sowie das Online License-Passwort übergeben
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // Die Bibliothek FREngine.dll freigeben
            engine = null;
            // Alle Objekte vor dem Aufruf von FreeLibrary löschen
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // Funktionen aus 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);
    // Funktionen aus 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();
    // Private Variablen
    private FREngine.IEngine engine = null;
    // Handle für FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}
Sie können die für dieses Szenario geeigneten Verarbeitungseinstellungen mit der Methode LoadPredefinedProfile des Engine-Objekts laden. Diese Methode verwendet den Namen eines Einstellungsprofils als Eingabeparameter. Weitere Informationen finden Sie unter Arbeiten mit Profilen.Die Einstellungen für dieses Szenario sind im vordefinierten Profil MachineReadableZone verfügbar:
  • Aktiviert die Erkennung und Extraktion des gesamten Textes in einem Bild (Abbildungen, Vektorgrafiken und Tabellen werden nicht erkannt).
  • Die Korrektur von Auflösung und Geometrie erfolgt automatisch.

C#

// Das vordefinierte Profil laden
engine.LoadPredefinedProfile("MachineReadableZone");
Wenn Sie die Verarbeitungseinstellungen ändern möchten, verwenden Sie die entsprechenden Parameter-Objekte. Weitere Informationen finden Sie weiter unten unter Additional optimization for specific tasks.Die MRZ-Erfassung ist nur möglich, wenn Ihre ABBYY FineReader Engine-Lizenz das Modul MRZCapture unterstützt.
Um Bilder in FineReader Engine zu laden, können Sie die Methoden dieser Objekte verwenden:
Linux- und Windows-Benutzer finden in Parallel Processing with ABBYY FineReader Engine Informationen zu den Vor- und Nachteilen der einzelnen Ansätze. Das vorliegende Thema konzentriert sich auf FRDocument.
Um Bilder in das FRDocument-Objekt zu laden, führen Sie einen der folgenden Schritte aus:Alle diese Methoden verwenden ein Objekt vom Typ PrepareImageMode als Eingabeparameter, mit dem Sie verschiedene Parameter für die Bildvorverarbeitung festlegen können. Erstellen Sie dieses Objekt, indem Sie die Methode IEngine::CreatePrepareImageMode aufrufen, passen Sie anschließend seine Eigenschaften nach Bedarf an und übergeben Sie es an die Methode zum Öffnen des Bildes.

C#

// Dokument erstellen
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
// Bilddatei zum Dokument hinzufügen
document.AddImageFile( imagePath, null, null );
So extrahieren Sie Daten aus der MRZ:
  1. [optional] Erstellen Sie das Objekt MrzProcessingParams mit der Methode CreateMrzProcessingParams des Objekts Engine. Legen Sie die Eigenschaften auf die gewünschten Werte fest.
  2. Rufen Sie die Methode ExtractMrz des Objekts FRPage auf und übergeben Sie das im vorherigen Schritt konfigurierte Objekt MrzProcessingParams als Eingabeparameter. Wenn Sie die Standardwerte für die MRZ-Erfassung verwenden möchten, übergeben Sie einfach NULL. Sie erhalten ein Objekt MrzData, das die aus der erfassten MRZ ausgelesenen Informationen enthält.

C#

// MRZ extrahieren
FREngine.IFRPage page = document.Pages.Item(0);
FREngine.IMrzData mrzData = page.ExtractMrz( null );
Das Objekt MrzData enthält alle aus der MRZ extrahierten Daten. Sie können mit der Methode GetLine auf die Zeilen des maschinenlesbaren Textes zugreifen und mit den Methoden GetField und GetFieldByType die Felder durchlaufen. Felder der folgenden Typen werden extrahiert:
  • Dokumenttyp
  • Dokumentuntertyp
  • Ausstellungsland
  • Nachname
  • Vorname
  • Dokumentnummer
  • Staatsangehörigkeit
  • Geburtsdatum
  • Geschlecht
  • Ablaufdatum
  • Persönliche Nummer
  • Optionale Datenzeile 1
  • Optionale Datenzeile 2
Das Objekt MrzField liefert vollständige Informationen zum extrahierten Feld. Verwenden Sie die Eigenschaft Text, um den Feldwert abzurufen, und die Eigenschaft Region, um die Position des Feldes im Bild abzurufen. Um die Daten zu überprüfen, verwenden Sie die Prüfsummen, die über die Eigenschaften Checksum, HasChecksum und IsChecksumVerified der Objekte MrzData und MrzField verfügbar sind. Nicht alle Feldtypen unterstützen Prüfsummen; die Eigenschaft HasChecksum ist vorhanden, damit Sie ihren Wert prüfen können, bevor Sie versuchen, die Prüfsumme abzurufen.Sie können den erkannten Text der Felder manuell bearbeiten, indem Sie die Methoden Insert und Remove des Objekts MrzField verwenden.

C#

// Prüfsumme der Dokumentnummer überprüfen
FREngine.IMrzField documentNumberField = mrzData.GetFieldByType(FREngine.MrzFieldTypeEnum.MFT_DocumentNumber);
bool isNumberVerified = documentNumberField.IsChecksumVerified;
Die extrahierten Daten können in einer XML- oder JSON-Datei gespeichert werden. Um die Daten mit den Standardparametern zu exportieren, rufen Sie die ExportToFile-Methode des MrzData-Objekts auf und übergeben den Dateipfad als Eingabeparameter. Um die Daten mit benutzerdefinierten Parametern zu exportieren, rufen Sie die ExportToFileEx-Methode des MrzData-Objekts auf und übergeben einen Zeiger auf das MrzJsonExportParams-Objekt oder das MrzXmlExportParams-Objekt als Eingabeparameter.C#
// Im XML-Format speichern
mrzData.ExportToFile("C:\\ExtractedData.xml", FREngine.MrzExportFormatEnum.MEF_Xml);
Wenn Sie die Arbeit mit ABBYY FineReader Engine abgeschlossen haben, müssen Sie das Engine-Objekt entladen. Verwenden Sie dazu die exportierte Funktion DeinitializeEngine.

C#

public class EngineLoader : IDisposable
{
    // FineReader Engine entladen
    public void Dispose()
    {
        if (engine == null)
        {
            // Engine wurde nicht geladen
            return;
        }
        engine = null;
        // Alle Objekte vor dem Aufruf von FreeLibrary löschen
        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;
        // Ausnahme nach dem Bereinigen auslösen
        Marshal.ThrowExceptionForHR(hresult);
    }
    // Funktionen aus 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);
    // Funktionen aus 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();
    // private Variablen
    private FREngine.IEngine engine = null;
    // Handle für FREngine.dll
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

Erforderliche Ressourcen

Sie können die Datei FREngineDistribution.csv verwenden, um automatisch eine Liste der Dateien zu erstellen, die für die Funktionsfähigkeit Ihrer Anwendung erforderlich sind. Wählen Sie für die Verarbeitung in diesem Szenario in Spalte 5 (RequiredByModule) die folgenden Werte aus: 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 Wenn Sie das Standardszenario ändern, passen Sie die erforderlichen Module entsprechend an. Außerdem müssen Sie die Sprachen der Benutzeroberfläche, die Erkennungssprachen und alle zusätzlichen Funktionen angeben, die von Ihrer Anwendung verwendet werden (z. B. Opening.PDF, wenn Sie PDF-Dateien öffnen müssen). Weitere Informationen finden Sie unter Working with the FREngineDistribution.csv File.

Zusätzliche Optimierung

Dies sind die Abschnitte der Hilfedatei, in denen Sie weitere Informationen zum Konfigurieren der Parameter für die verschiedenen Verarbeitungsstufen finden:

Siehe auch

Implementierung grundlegender Anwendungsszenarien