メインコンテンツへスキップ
多くの国の公的な渡航文書や身分証明書には、文書データをより正確に処理するための機械読取領域 (MRZ) が含まれています。MRZ には、ICAO Document 9303 に準拠して記載された OCR-B フォントのテキストが 2 行または 3 行含まれます (仕様については ICAO のウェブサイトを参照してください) 。 このシナリオは、顧客のオンボーディングや本人確認のプロセスにおいて、ID 文書上の機械読取領域からデータを抽出するために使用されます。システムは文書画像上の MRZ を認識し、そこからデータを抽出します。抽出されたデータには、文書およびその所持者に関する個人情報を含む複数の field が含まれます (文書の種類や有効期限、文書所持者の名と姓など) 。これらの field を検索し、データを検証して、後続の処理のために外部ファイルへ保存できます。 MRZ からデータを抽出するには、スキャンして取得した画像ファイルや電子形式で保存された画像ファイルが、通常、いくつかの処理段階を経ます。各段階にはそれぞれ固有の特性があります。
  1. スキャン画像または写真の前処理
MRZ がある ID 文書の個人情報ページをスキャンするか、写真を撮影します。モバイル端末のデジタルカメラで撮影した写真は、解像度や画質が低い場合があります。また、画像によっては認識前に前処理が必要になることがあります。
  1. MRZ からのデータ抽出
各画像から取得できる MRZ は 1 つまでです。2 行または 3 行の各テキスト行が認識・解析され、data field が抽出されます。一部の field と MRZ 全体にはチェックサムが含まれており、これを使用してデータを検証できます。
  1. 外部ファイルへのエクスポート
抽出したデータは、外部形式で保存することもできます。XML と JSON がサポートされています。 以下で説明する手順は、Linux および Windows 向けの MRZExtraction コードサンプルに実装されています。

シナリオの実装

このトピックで示すコードサンプルは、Windows 専用です。
以下では、このシナリオで ABBYY FineReader Engine 12 を使用する推奨方法について詳しく説明します。この方法では、このシナリオに最も適した処理設定を使用します。
ABBYY FineReader Engine の使用を開始するには、Engine オブジェクトを作成する必要があります。Engine オブジェクトは、ABBYY FineReader Engine オブジェクト階層の最上位に位置するオブジェクトで、さまざまなグローバル設定、一部の処理メソッド、および他のオブジェクトを作成するためのメソッドを提供します。Engine オブジェクトを作成するには、InitializeEngine 関数を使用できます。あわせて Engine オブジェクトを読み込むその他の方法 (Win) も参照してください。

C#

public class EngineLoader : IDisposable
{
    public EngineLoader()
    {
        // これらの変数を、FREngine.dll への完全パス、Customer Project ID、
        // および該当する場合は、オンライン ライセンスのトークン ファイルへのパスとオンライン ライセンス パスワードで初期化します
        string enginePath = "";
        string customerProjectId = "";
        string licensePath = "";
        string licensePassword = "";
        // 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");
            }
            // ポインターをデリゲートに変換します
            initializeEngine = (InitializeEngine)Marshal.GetDelegateForFunctionPointer(
                initializeEnginePtr, typeof(InitializeEngine));
            deinitializeEngine = (DeinitializeEngine)Marshal.GetDelegateForFunctionPointer(
                deinitializeEnginePtr, typeof(DeinitializeEngine));
            dllCanUnloadNow = (DllCanUnloadNow)Marshal.GetDelegateForFunctionPointer(
                dllCanUnloadNowPtr, typeof(DllCanUnloadNow));
            // InitializeEngine 関数を呼び出し、 
            // オンライン ライセンス ファイルへのパスとオンライン ライセンス パスワードを渡します
            int hresult = initializeEngine(customerProjectId, licensePath, licensePassword, 
                "", "", false, ref engine);
            Marshal.ThrowExceptionForHR(hresult);
        }
        catch (Exception)
        {
            // FREngine.dll ライブラリを解放します
            engine = null;
            // FreeLibrary 呼び出しの前にすべてのオブジェクトを削除します
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            FreeLibrary(dllHandle);
            dllHandle = IntPtr.Zero;
            initializeEngine = null;
            deinitializeEngine = null;
            dllCanUnloadNow = null;
            throw;
        }
    }
    // 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);
    // 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 変数
    private FREngine.IEngine engine = null;
    // FREngine.dll へのハンドル
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}
このシナリオに適した処理設定は、Engine オブジェクトの LoadPredefinedProfile メソッドを使用して読み込めます。このメソッドは、設定プロファイル名を入力パラメーターとして使用します。詳細については、Working with Profiles を参照してください。このシナリオの設定は、定義済みプロファイル MachineReadableZone で利用できます。
  • 画像上のすべてのテキストの検出と抽出を有効にします (画像、ベクターグラフィックス、表は検出されません) 。
  • 解像度補正と幾何補正は自動的に実行されます。

C#

// 定義済みプロファイルを読み込む
engine.LoadPredefinedProfile("MachineReadableZone");
処理設定を変更する場合は、適切な Parameter オブジェクトを使用してください。詳細については、以下の Additional optimization for specific tasks を参照してください。MRZ キャプチャは、お使いの ABBYY FineReader Engine のライセンスが MRZCapture モジュールをサポートしている場合にのみ使用できます。
FineReader Engine に画像を読み込むには、次のオブジェクトのメソッドを使用できます。
Linux および Windows のユーザーは、各アプローチの利点と欠点について Parallel Processing with ABBYY FineReader Engine で確認できます。このトピックでは FRDocument に焦点を当てます。
FRDocument オブジェクトに画像を読み込むには、次のいずれかを行います。これらのメソッドはすべて、画像の前処理に関するさまざまなパラメーターを指定できる PrepareImageMode オブジェクトを入力パラメーターとして受け取ります。このオブジェクトは、IEngine::CreatePrepareImageMode メソッドを呼び出して作成し、必要に応じてそのプロパティを変更してから、画像を開くメソッドに渡します。

C#

// ドキュメントを作成する
FREngine.IFRDocument frDoc = engine.CreateFRDocument();
// ドキュメントに画像ファイルを追加する
document.AddImageFile( imagePath, null, null );
MRZ からデータを抽出するには、次の手順に従います。
  1. [任意] Engine オブジェクトの CreateMrzProcessingParams メソッドを使用して、MrzProcessingParams オブジェクトを作成します。必要に応じて、そのプロパティを設定します。
  2. FRPage オブジェクトの ExtractMrz メソッドを呼び出し、前の手順で設定した MrzProcessingParams オブジェクトを入力パラメーターとして渡します。既定の MRZ 取得設定を使用する場合は、NULL を渡すだけでかまいません。取得した MRZ から解析された情報を含む MrzData オブジェクトが返されます。

C#

// MRZ を抽出する
FREngine.IFRPage page = document.Pages.Item(0);
FREngine.IMrzData mrzData = page.ExtractMrz( null );
MrzData オブジェクトには、MRZ から抽出されたすべてのデータが含まれています。GetLine メソッドを使用すると機械可読テキストの行にアクセスでき、GetField メソッドおよび GetFieldByType メソッドを使用すると field を順に処理できます。抽出される field の type は次のとおりです。
  • 文書の種類
  • 文書のサブタイプ
  • 発行国
  • 文書番号
  • 国籍
  • 生年月日
  • 性別
  • 有効期限
  • 個人番号
  • 任意データ行 1
  • 任意データ行 2
MrzField オブジェクトは、抽出された field に関する完全な情報を提供します。Text property を使用して field の値を取得し、Region property を使用して画像上の field の位置を取得します。データを検証するには、MrzData オブジェクトおよび MrzField オブジェクトの Checksum、HasChecksum、IsChecksumVerified properties で利用できるチェックサムを使用します。すべての field type がチェックサムをサポートしているわけではありません。HasChecksum property が用意されているため、チェックサムを取得する前にその値を確認できます。MrzField オブジェクトの Insert メソッドおよび Remove メソッドを使用すると、field の認識テキストを手動で編集できます。

C#

// 文書番号のチェックサムを検証する
FREngine.IMrzField documentNumberField = mrzData.GetFieldByType(FREngine.MrzFieldTypeEnum.MFT_DocumentNumber);
bool isNumberVerified = documentNumberField.IsChecksumVerified;
抽出データは XML ファイルまたは JSON ファイルとして保存できます。既定のパラメーターでデータをエクスポートするには、MrzData オブジェクトの ExportToFile メソッドを呼び出し、入力パラメーターとしてファイルのパスを渡します。ユーザー定義のパラメーターでデータをエクスポートするには、MrzData オブジェクトの ExportToFileEx メソッドを呼び出し、入力パラメーターとして MrzJsonExportParams オブジェクトまたは MrzXmlExportParams オブジェクトへのポインターを渡します。C#
// XML 形式で保存
mrzData.ExportToFile("C:\\ExtractedData.xml", FREngine.MrzExportFormatEnum.MEF_Xml);
ABBYY FineReader Engine での作業が完了したら、Engine オブジェクトをアンロードする必要があります。これを行うには、エクスポート関数 DeinitializeEngine を使用します。

C#

public class EngineLoader : IDisposable
{
    // FineReader Engine をアンロード
    public void Dispose()
    {
        if (engine == null)
        {
            // Engine はロードされていません
            return;
        }
        engine = null;
        // 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;
        // クリーンアップ後に例外をスロー
        Marshal.ThrowExceptionForHR(hresult);
    }
    // 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);
    // 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 FREngine.IEngine engine = null;
    // FREngine.dll へのハンドル
    private IntPtr dllHandle = IntPtr.Zero;
    private InitializeEngine initializeEngine = null;
    private DeinitializeEngine deinitializeEngine = null;
    private DllCanUnloadNow dllCanUnloadNow = null;
}

必要なリソース

FREngineDistribution.csv ファイルを使用すると、アプリケーションの動作に必要なファイルのリストを自動的に作成できます。このシナリオで処理を行うには、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 標準シナリオを変更する場合は、それに応じて必要なモジュールも変更してください。また、インターフェイス言語、認識言語、およびアプリケーションで使用する追加機能も指定する必要があります (たとえば、PDF ファイルを開く必要がある場合は Opening.PDF など) 。詳細については、Working with the FREngineDistribution.csv File を参照してください。

追加の最適化

さまざまな処理段階のパラメーター設定に関する詳細情報は、ヘルプファイルの以下のセクションに記載されています。

関連項目

基本的な使用シナリオの実装