単一行fieldを検出するために、FlexiLayout Studio には専用の Character String 要素があります。検索対象のfieldの形式が既知であれば、対応する要素のプロパティで、Character String タブの Regular expression field にその形式を記述できます。ただし、正規表現を使用するには、印字文書であり、かつ画質が良好であることが必要です。というのも、正規表現による記述ではfield内の誤りを許容できないため、少しでも誤りがあると要素は検出されないからです。また、文書のlayoutを記述できる場合でも、手書きで記入された文書に正規表現を使用してはいけません。それでも、そのようなfieldを検出することは可能です。
すべてのページで類似した形式を持つ単一行field「請求書番号」を検索する方法は、サンプルプロジェクト StructuredStrings.fsp (フォルダー %public%\ABBYY\FlexiCapture\12.0\Samples\FLS\Tips and Tricks\Structured strings) に示されています。
このプロジェクトには4つのページがあります。
- 1ページ目と2ページ目 - field「請求書番号」はプリンターで印字されており、印字品質は良好です。
- 3ページ目 – field「請求書番号」はプリンターで印字されていますが、画像にノイズがあります。
- 4ページ目 – 画質は良好ですが、field「請求書番号」は手書きで記入されています。
ここでは、field名を手がかりに field「請求書番号」を探します。まず、field名の検索条件を記述する要素を作成する必要があります。作成する要素は Static Text 型で、名前は InvoiceNumberHeader、値は “InvoiceN:” です。
field「請求書番号」は単一行fieldです。これを検出するために、Character String 型で NumAsRegularExpression という名前の要素を作成しました。プロジェクトのページを見ると、field「請求書番号」の形式は次の正規表現で記述できます。
NNNN”-“NN”-“[A-Z]”/“NN
または (同じ意味ですが)
[0-9]{4}”-“[0-9]{2}”-“[A-Z]”/” [0-9]{2}
これは、その番号が「4桁の数字 - 2桁の数字 - 1つのラテン大文字/2桁の数字」という並びであることを意味します。
プロジェクトを見ると、Match コマンドを選択して FlexiLayout のマッチング手順を実行した後、3ページ目と4ページ目では要素 NumAsRegularExpression に対して null 仮説が生成され、つまり要素は検出されませんでした。3ページ目では、ノイズによってfieldと正規表現が一致しませんでした。3ページ目を開いてツールバーの “L” (“Show Recognized Lines”) をクリックすると、そのページ上の請求書番号の事前認識結果は “10&0-20-A/04” のように表示されます。4ページ目では、請求書番号は手書きで記入されています。事前認識の結果 (Z.OOO-41-C/03) を見ると、これも記述された形式に一致していないことが分かります。
この問題に対しては、次の解決策を推奨します。もう1つ、Character String 型で NumAsAlphabet という名前の要素を作成します。この要素には、NumAsRegularExpression 要素と同じ検索条件を指定します。次に、この2つの要素を1つの Group 要素 InvoiceNumber にまとめます。ただし、要素 NumAsAlphabet は正規表現としてではなく、有効なすべての文字のリストとして記述します。
Advanced pre-search relations field には、次のコードを記述する必要があります。
if (NumAsRegularExpression.IsNull == FALSE) then Dontfind();
これは、固定形式の文字列を表す要素 NumAsRegularExpression でプログラムが検出できなかった場合にのみ、要素 NumAsAlphabet で表される形式不明の文字列の検索が試行されることを意味します。
要素 NumAsAlphabet の検索条件を指定する際は、ドラッグ&ドロップで、要素 NumAsRegularExpression の Relations セクションの設定を現在の要素の同じセクションにコピーできます。あるいは、Advanced pre-search relations field に次のコードを記述することもできます。
if (NumAsRegularExpression.IsNull == FALSE) then Dontfind();
else RestrictSearchArea (NumAsRegularExpression.Rect);
このコードは、請求書番号の構造が指定された形式に一致しない場合、つまりプログラムが要素 NumAsRegularExpression を検出できなかった場合にのみ、要素 NumAsAlphabet の検索が行われることを意味します。また、要素 NumAsAlphabet は、要素 NumAsRegularExpression が見つからなかったのと同じ領域内で検索されます。
ここで、すべてのページに対して FlexiLayout のマッチング手順をもう一度開始します。プロジェクトを見ると、請求書番号 field が各ページで正常に見つかるようになっていることがわかります。
プロジェクトツリーでは、InvoiceNum という名前のテキストブロックを作成しました。その Source 要素として、グループ SearchElements.InvoiceNumber が指定されています。この段階で、「請求書番号」field を検出するための FlexiLayout の作成は完了です。
何らかの理由で、上で説明したメソッドだけではデータ field の検出に不十分な場合は (形式が既知でも未知でも) 、グループ内に型 Object Collection の要素をもう 1 つ作成できます。このプロジェクトでは、これが NumAsObjectCollection という名前の型 Object Collection の要素です。これは、このプロジェクトでは画像品質が良好なため実際には不要で、あくまで例として示しているだけです (この要素には Disable command が指定されています) 。型 Object Collection の追加要素が必要になるのは、ページごとの事前認識の結果を予測するのは難しい一方で、検索領域は正確に定義でき、不要な情報が仮説に入り込むのを防げる場合です。
ここで、次のような疑問が生じるかもしれません。field が場合によってはそれなしでも検出できるのに、なぜ正規表現が必要なのでしょうか。答えは、正規表現を使うことで検索の信頼性が高まるからです。この要素が見つかれば、必要なその行を見つけたと確信できます。この情報は、その後の要素やそれらのリレーションを検出するために安心して使用できます。検索条件が緩い場合は、必要なものを正確に見つけたと完全に確信することはできません。
これは、画像にノイズが非常に多い場合に起こることがあります。そのような場合、指定されたアルファベットを持つ型 Character String の要素を使用すると、エラー率 (Percentage of non-アルファベット characters parameter) が高くなりすぎることがあります。その結果、要素はまったく検出されないか、一部しか検出されません。そのような状況の例を次の画像に示します。
