このシナリオは、紙文書を処理してデジタルアーカイブに保存するために使用します。特に、契約書、プロジェクト文書、請求書、証明書などのアーカイブを作成する場合に適しています。
この処理シナリオでは、紙文書は、文書内のすべての情報を検索可能な形式で含む、編集できないデジタルコピーに変換されます。このように処理することで、文書のデジタルコピーを電子アーカイブ内で全文検索により簡単に見つけられるようになり、文書内のテキスト部分をコピーしたり、文書を電子メールで送信したり、印刷したりすることもできます。
デジタルコピーを作成するには、まず文書をいくつかの処理段階に通す必要があり、それぞれの段階には固有の特性があります。
- スキャン画像の前処理
スキャン画像は、認識の前に前処理が必要になる場合があります。たとえば、スキャンした文書に背景ノイズ、文字の傾き、色の反転、黒い余白、不正な向き、または解像度の問題がある場合です。
- 大量の文書の同時認識
文書からテキストデータを抽出するには、認識処理を行う必要があります。大量の文書を処理する場合は、文書の同時処理が役立ちます。この場合、解析および認識の負荷をプロセッサコアに分散できるため、処理を高速化できます。
- アーカイブ形式へのエクスポート
認識された文書は、適切な保存形式で保存されます。文書の保存に最も適した形式は、PDF、PDF/A、PDF、および MRC 付き PDF/A です。これらの形式で保存する際には、文書画像の下にテキストを配置するモードを使用できます。これにより、文書の書式を完全に保持しながら、全文検索も可能になります。MRC の設定を使用すると、見た目の品質を損なうことなくファイルサイズを大幅に削減できます。また、PDF 形式で保存する場合は、不正な閲覧や印刷から文書を保護するためのセキュリティ設定をカスタマイズすることもできます。
このトピックのコードサンプルは Windows 固有です。
以下では、アーカイブ用の文書のデジタルコピーを作成する際に ABBYY FineReader Engine 12 を使用する推奨方法を詳しく説明します。この方法では、この目的に最も適した処理設定を使用します。この実装では、文書のスキャン工程は省略しています。スキャンの実装に関するヒントについては、下記の特定のタスク向けの追加最適化を参照してください。
手順 1. ABBYY FineReader Engine を読み込む
ABBYY FineReader Engine を使い始めるには、Engine オブジェクトを作成する必要があります。Engine オブジェクトは ABBYY FineReader Engine のオブジェクト階層における最上位のオブジェクトであり、さまざまなグローバル設定、一部の処理メソッド、およびその他のオブジェクトを作成するためのメソッドを提供します。Engineオブジェクトを作成するには、InitializeEngine関数を使用します。Engineオブジェクトを読み込むその他の方法 (Win) も参照してください。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("読み込めません: " + enginePath);
}
IntPtr initializeEnginePtr = GetProcAddress(dllHandle, "InitializeEngine");
if (initializeEnginePtr == IntPtr.Zero)
{
throw new Exception("InitializeEngine 関数が見つかりません");
}
IntPtr deinitializeEnginePtr = GetProcAddress(dllHandle, "DeinitializeEngine");
if (deinitializeEnginePtr == IntPtr.Zero)
{
throw new Exception("DeinitializeEngine 関数が見つかりません");
}
IntPtr dllCanUnloadNowPtr = GetProcAddress(dllHandle, "DllCanUnloadNow");
if (dllCanUnloadNowPtr == IntPtr.Zero)
{
throw new Exception("DllCanUnloadNow 関数が見つかりません");
}
// ポインターをデリゲートに変換する
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 FREngine.IEngine engine = null;
// FREngine.dll へのハンドル
private IntPtr dllHandle = IntPtr.Zero;
private InitializeEngine initializeEngine = null;
private DeinitializeEngine deinitializeEngine = null;
private DllCanUnloadNow dllCanUnloadNow = null;
}
C++ (COM)
// これらの変数を、FREngine.dll へのパス、FineReader Engine の Customer Project ID、
// および必要に応じてオンラインライセンストークンとオンラインライセンスパスワードへのパスで初期化してください
wchar_t* FreDllPath;
wchar_t* CustomerProjectId;
wchar_t* LicensePath; // オンラインライセンスを使用しない場合は、これらの変数に空文字列を設定してください
wchar_t* LicensePassword;
// FREngine.dll へのハンドル
static HMODULE libraryHandle = 0;
// グローバル FineReader Engine オブジェクト
FREngine::IEnginePtr Engine;
void LoadFREngine()
{
if( Engine != 0 ) {
// 既にロード済み
return;
}
// ステップ 1: FREngine.dll をロードする
if( libraryHandle == 0 ) {
libraryHandle = LoadLibraryEx( FreDllPath, 0, LOAD_WITH_ALTERED_SEARCH_PATH );
if( libraryHandle == 0 ) {
throw L"ABBYY FineReader Engine のロード中にエラーが発生しました";
}
}
// ステップ 2: 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"ABBYY FineReader Engine のロード中にエラーが発生しました";
}
}
ABBYY FineReader Engine では、Engine オブジェクトの LoadPredefinedProfile メソッドを使用して、このシナリオに最適な一連の処理設定を読み込めます。このメソッドは、入力パラメーターとしてプロファイル名を受け取ります。詳細については、Working with Profiles を参照してください。ABBYY FineReader Engine では、このシナリオ向けに 2 種類の設定をサポートしています。プロファイル名 | 説明 |
|---|
DocumentArchiving_Accuracy | この設定は、精度を重視して最適化されています。 - 画像に埋め込まれたテキストを含め、画像上のテキストを最大限検出します。
- 文書の論理構造の完全な合成は行われません。
このプロファイルは、文書を RTF、DOCX、またはテキストのみの PDF に変換する用途には適していません。その場合は、文書変換用のプロファイルを使用してください。 |
DocumentArchiving_Speed | この設定は、処理速度を重視して最適化されています。 - 画像に埋め込まれたテキストを含め、画像上のテキストを最大限検出します。
- 傾き補正は行われません。
- 文書の論理構造の完全な合成は行われません。
- 文書解析と認識の処理が高速化されます。
このプロファイルは、文書を RTF、DOCX、またはテキストのみの PDF に変換する用途には適していません。その場合は、文書変換用のプロファイルを使用してください。 |
// 事前定義済みプロファイルを読み込む
engine.LoadPredefinedProfile("DocumentArchiving_Accuracy");
// 事前定義済みプロファイルを読み込む
Engine->LoadPredefinedProfile( L"DocumentArchiving_Accuracy" );
処理設定を変更する場合は、適切な Parameter オブジェクトを使用してください。詳細については、特定のタスク向けの追加の最適化 を参照してください。
ABBYY FineReader Engine には、複数ページの文書を処理できる FRDocument オブジェクトが用意されています。このオブジェクトを使用すると、文書の論理的な構成を保持できます。1 つの文書の画像を読み込んで前処理するには、FRDocument オブジェクトを作成し、そこに画像を追加する必要があります。方法は次のいずれかです。// 画像ファイルから FRDocument オブジェクトを作成する
FREngine.IFRDocument frDocument = engine.CreateFRDocumentFromImage( "C:\\MyImage.tif", null );
// 画像ファイルから FRDocument オブジェクトを作成する
FREngine::IFRDocumentPtr frDocument = Engine->CreateFRDocumentFromImage( L"C:\\MyImage.tif", 0 );
ドキュメントを認識するには、FRDocument オブジェクトの解析および認識用のメソッドを使用することをお勧めします。このオブジェクトには、ドキュメントの解析、認識、合成のための各種メソッドが用意されています。1 つのメソッドだけでドキュメントの解析、認識、合成を実行できる最も便利なメソッドは、Process メソッドです。また、このメソッドは、マルチプロセッサおよびマルチコア システムの並列処理機能を最も効率的に活用します。一方、Preprocess、Analyze、Recognize、および Synthesize メソッドを使用して、前処理、解析、認識、合成を順番に実行することもできます。// ドキュメントを解析、認識、および合成します
// 追加のパラメーターは処理プロファイルで設定されるため不要です
frDocument.Process( null );
// ドキュメントを解析、認識、および合成します
// 追加のパラメーターは処理プロファイルで設定されるため不要です
frDocument->Process( 0 );
認識済みのドキュメントを保存するには、FRDocument オブジェクトの Export メソッドを使用し、パラメーターの 1 つとして FileExportFormatEnum 定数を指定します。このシナリオでは、たとえば、MRC を使用し、エクスポート モード PEM_ImageOnText (PDFExportParams オブジェクトの TextExportMode プロパティ) で、ドキュメントを PDF 形式で保存できます。対応するエクスポート オブジェクトを使用すると、デフォルトのエクスポート パラメーターを変更できます。詳細については、以下の 特定のタスク向けの追加の最適化 を参照してください。FRDocument オブジェクトの使用が完了したら、このオブジェクトで使用されていたすべてのリソースを解放します。IFRDocument::Close メソッドを使用してください。// 認識済みドキュメントをアーカイブ形式(たとえば PDF)で保存します
// PDFExportParams オブジェクトを作成します
FREngine.PDFExportParams exportParams = engine.CreatePDFExportParams();
// 必要なパラメーターを設定します
exportParams.MRCMode = FREngine.PDFMRCModeEnum.MRC_Auto;
exportParams.TextExportMode = FREngine.PDFExportModeEnum.PEM_ImageOnText;
// エクスポート時にこれらのパラメーターを使用します
frDocument.Export( "C:\\MyText.pdf", FREngine.FileExportFormatEnum.FEF_PDF, exportParams );
// FRDocument オブジェクトを解放します
frDocument.Close();
// 認識済みドキュメントをアーカイブ形式(例: PDF)で保存します
// PDFExportParams オブジェクトを作成します
FREngine::IPDFExportParamsPtr params = Engine->CreatePDFExportParams();
// 必要なパラメーターを設定します
params->MRCMode = FREngine::MRC_Auto;
params->TextExportMode = FREngine::PEM_ImageOnText;
// エクスポート時にこれらのパラメーターを使用します
frDocument->Export(L"C:\\MyText.pdf", FREngine::FEF_PDF, params);
// FRDocument オブジェクトを解放します
frDocument->Close();
ステップ 6. ABBYY FineReader Engine のアンロード
ABBYY FineReader Engine での作業が完了したら、Engine オブジェクトをアンロードする必要があります。これを行うには、エクスポートされた DeinitializeEngine 関数を使用します。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;
}
void UnloadFREngine()
{
if( libraryHandle == 0 ) {
return;
}
// Engine オブジェクトを解放する
Engine = 0;
// FineReader Engine を終了する
typedef HRESULT ( STDAPICALLTYPE* DeinitializeEngineFunc )();
DeinitializeEngineFunc pDeinitializeEngine =
( DeinitializeEngineFunc )GetProcAddress( libraryHandle, "DeinitializeEngine" );
if( pDeinitializeEngine == 0 || pDeinitializeEngine() != S_OK ) {
throw L"Error while unloading ABBYY FineReader Engine";
}
// これで FREngine.dll ライブラリを安全に解放できる
FreeLibrary( libraryHandle );
libraryHandle = 0;
}
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
Export.Pdf
Export.Pdf, Opening.Pdf
標準シナリオを変更する場合は、それに応じて必要なモジュールも変更してください。また、インターフェイス言語、認識言語、およびアプリケーションで使用する追加機能も指定する必要があります (たとえば、PDF ファイルを開く必要がある場合は Opening.PDF、CJK 言語 のテキストを認識する必要がある場合は Processing.OCR.CJK など) 。詳細については、Working with the FREngineDistribution.csv File を参照してください。
以下に、文書処理の各段階での設定のカスタマイズに関する追加情報を掲載したヘルプトピックの概要を示します。
-
スキャン - Windows のみ
- スキャン
文書をスキャンするABBYY FineReader Engineのシナリオについて説明します。
-
認識
-
手書き文字を認識する
DocumentArchiving_*** プロファイルには、手書き文字や手書きのブロック体文字の認識は含まれていません。手書き文字を認識する必要がある場合は、PageAnalysisParams オブジェクトの DetectHandwritten プロパティを TRUE に設定してください。
-
PageProcessingParams オブジェクト
このオブジェクトでは、解析および認識のパラメーターをカスタマイズできます。また、このオブジェクトを使用して、検出する画像およびテキストの特性 (反転画像、向き、バーコード、認識言語、認識の許容誤差) を指定できます。
-
SynthesisParamsForPage Object
このオブジェクトには、合成時にページ書式を復元するためのパラメーターが含まれています。
-
SynthesisParamsForDocument オブジェクト
このオブジェクトを使用すると、文書の構造や書式の復元など、文書合成をカスタマイズできます。
-
MultiProcessingParams オブジェクト - Linux および Windows に対応
大量の画像を処理する場合は、同時処理が有効です。この場合、画像の読み込みと前処理、レイアウト解析、認識、エクスポートの各処理で負荷がプロセッサ コアに分散されるため、処理を高速化できます。
読み取りモード (同時または逐次) は MultiProcessingMode プロパティで設定し、開始可能なプロセス数は RecognitionProcessesCount プロパティで制御します。
-
エクスポート
- エクスポートパラメーターの調整
エクスポート パラメーター オブジェクトを使用した文書エクスポートのカスタマイズ。
- PDFExportParams Object
このオブジェクトを使用すると、わずか数個のパラメーターで PDF (PDF/A) エクスポートを調整できます。
- PDF (PDF/A) 形式のエクスポート モードをカスタマイズするには、PDFExportParams オブジェクトの TextExportMode プロパティを使用します。MRC 設定をカスタマイズするには、MRCMode プロパティを使用します。
- さらに、画像のエクスポート設定をカスタマイズして、処理の高速化やファイル サイズのさらなる削減などを実現できます。たとえば、用途に応じて、カラー画像をグレースケール画像または白黒画像として保存できます (PDFExportParams オブジェクトの Colority プロパティを使用) 。
- 画像の解像度は、生成される電子コピーを後でプリンターで印刷したり、コンピューター画面で表示したりできるように変更できます。また、テキストの判読のみに適し、グラフィックス品質が非常に低い低解像度を選択することもできます (PDFExportParams オブジェクトの Resolution プロパティおよび ResolutionType プロパティを使用) 。
-
文書への分割
- このシナリオでは、画像のバッチを複数の文書に分割する必要が生じることがあります。ABBYY FineReader Engine 12 は文書の自動分割をサポートしていません。ただし、ABBYY FlexiCapture Engine を使用すれば、自動分割を実装できます。たとえば、文書のページ数に基づいて分割したり、区切り用バーコードがあるページに基づいて分割したりできます。バーコードによる分割を実装する場合は、文書からバーコード値のみを抽出するシナリオを使用できます。
基本的な使用シナリオの実装