跳轉到主要內容
C# 範例僅適用於 Windows 版 FRE。
ABBYY FineReader Engine 12 支援兩種核取記號區塊類型:核取記號和核取記號群組。核取記號群組區塊是由多個核取記號區塊組成的集合。這些區塊類型在 BlockTypeEnum 列舉中對應的常數為 BT_Checkmark 和 BT_CheckmarkGroup。CheckmarkBlockCheckmarkGroup 物件可用來存取這些類型的區塊。若要取得這些物件,您應使用 Block 物件的對應方法。
若要辨識核取記號,您必須擁有支援 OMR 模組的 ABBYY FineReader Engine 授權。
您可以辨識單一核取記號以及核取記號群組。 一個核取方塊對應一個 CheckmarkBlock 物件。核取方塊可能的狀態包括:已勾選、未勾選、已更正。這些狀態對應於 CheckmarkCheckStateEnum。所謂已更正的核取記號,是指使用者先在核取方塊中做了標記,之後又將其劃掉。

在影像中偵測核取記號

可在版面分析期間於影像中偵測核取記號。若要啟用核取記號偵測,請將 IPageAnalysisParams::DetectCheckmarks 屬性設為 TRUE。 分析完成後,版面中會包含一個 CheckmarkBlock 物件,對應影像上找到的每個核取記號。這些核取記號不會歸入 CheckmarkGroup 群組。系統會自動偵測核取記號類型。 在您呼叫執行辨識的方法之後 (例如 IFRDocument::Recognize) ,或使用單一方法完成整個處理流程時 (例如 IFRDocument::Process) ,系統便會填入核取記號辨識結果。
FREngine.IEngine engine;
FREngine.IFRDocument frdoc;
// 我們假設文件已建立,且影像已新增至文件中
// 建立 DocumentProcessingParams 並設定參數
FREngine.IDocumentProcessingParams dpp = engine.CreateDocumentProcessingParams();
FREngine.IPageProcessingParams ppp = dpp.PageProcessingParams;
ppp.PageAnalysisParams.DetectCheckmarks = true;
// 使用這些參數進行處理
frDoc.Process( dpp );
如果您對自動核取記號偵測的結果不滿意,或需要辨識核取記號群組或自訂核取記號,請手動指定核取記號區域。以下各節說明不同的情境:

識別一組核取記號

對於核取記號群組,您可以指定群組中已勾選核取方塊的最小與最大數量 (分別為 MinimumCheckedInGroupMaximumCheckedInGroup) 。這些值可透過 CheckmarkGroup 物件設定,並會在識別時使用。 核取記號群組中的所有核取記號,其 IsCorrectionEnabledCheckmarkType 屬性都必須具有相同的值。 核取記號的狀態是根據區域中的黑色像素百分比計算而得。未勾選的核取記號最小,已勾選的核取記號較大,而已修正的核取記號最大。因此,若要獲得正確的識別結果,務必:
  • 正確設定核取記號類型,因為 CMT_CircleCMT_Square 類型的核取記號具有黑色邊框,在計算百分比時必須將其納入考量;
  • 指定核取記號的精確區域,因為黑色百分比會以整個區域為基礎計算;如果區域中包含無關部分,估算結果可能會變差。
若要識別核取記號群組:
  1. 從含有核取記號群組的影像建立 FRDocument 物件。例如,您可以使用 Engine 物件的 CreateFRDocumentFromImage 方法。
  2. 從文件的頁面集合中取得包含核取記號影像的頁面 (IFRDocument::Pages) ——使用 FRPages 集合的屬性和方法。
  3. 透過 IFRPage::Layout 屬性,取得與此頁面對應的 Layout 物件。
  4. 對於每個核取記號群組:
  5. 使用 IEngine::CreateRegion 方法建立 Region 物件,並使用 IRegion::AddRect 方法向其中新增矩形。
  6. 建立核取記號群組類型的 Block 物件,並使用 ILayoutBlocks::AddNew 方法將其新增至版面配置區塊集合 (ILayout::Blocks) 中 (使用 BT_CheckmarkGroup 常數和已建立的 Region 物件作為輸入參數。此方法還要求將版面配置中的區塊索引作為第三個輸入參數) 。
  7. 取得 CheckmarkGroup 物件 (使用 IBlock::GetAsCheckmarkGroup 方法) 。
若要獲得正確的識別結果,務必正確設定核取記號的類型和區域。
  1. 對於群組中的每個核取記號:
  2. 使用 IEngine::CreateRegion 方法建立 Region 物件,並使用 IRegion::AddRect 方法將矩形新增至其中。
  3. 使用 ICheckmarkGroup::AddNew 方法,在群組中建立新的核取記號區塊 (將已建立的 Region 物件作為輸入參數) 。
  4. 取得 CheckmarkBlock 物件 (使用 IBlock::GetAsCheckmarkBlock 方法) ,並設定所需參數 (CheckmarkType、IsCorrectionEnabled) 。
  5. 設定核取記號群組的必要參數 (MinimumCheckedInGroup、MaximumCheckedInGroup) 。
  6. 若要辨識核取記號,請使用任何可執行辨識的可用方法,例如 IFRPage::RecognizeIFRPage::RecognizeBlocksIFRDocument::RecognizeIFRDocument::RecognizePages 等。
...
// 取得 Layout 物件
FREngine.IFRDocument document = Engine.CreateFRDocumentFromImage("D:\\Sample.tiff", null);
FREngine.ILayout layout = document.Pages[0].Layout;
// 設定區塊區域
FREngine.IRegion region = Engine.CreateRegion();
region.AddRect(0, 0, 100, 50);
// 建立核取記號群組類型的區塊,並將其新增至版面配置集合的結尾
FREngine.IBlock block = layout.Blocks.AddNew(FREngine.BlockTypeEnum.BT_CheckmarkGroup, region, layout.Blocks.Count);
FREngine.ICheckmarkGroup checkmarkGroup = block.GetAsCheckmarkGroup();
// 建立核取記號類型的區塊
// 並將其新增至核取記號群組
for (int i = 0; i < 5; i++)
{
  FREngine.IRegion checkmarkRegion = Engine.CreateRegion();
  checkmarkRegion.AddRect(10, 10 + i * 20, 90, 10 + (i + 1) * 20);
  FREngine.ICheckmarkBlock checkmark = checkmarkGroup.AddNew(0, checkmarkRegion);
}
...

辨識單一核取記號

  1. 從含有核取記號的影像建立 FRDocument 物件。例如,您可以使用 Engine 物件的 CreateFRDocumentFromImage 方法。
  2. 從文件的頁面集合中取得包含核取記號影像的頁面 (IFRDocument::Pages) — 使用 FRPages 集合的屬性和方法。
  3. 透過 IFRPage::Layout 屬性,取得與此頁面對應的 Layout 物件。
  4. 使用 IEngine::CreateRegion 方法建立 Region 物件,並使用 IRegion::AddRect 方法將矩形新增至其中。
  5. 建立核取記號類型的 Block 物件,並使用 ILayoutBlocks::AddNew 方法將其新增至版面配置區塊集合 (ILayout::Blocks) 中 (使用 BT_Checkmark 常數和已建立的 Region 物件作為輸入參數) 。
  6. 取得 CheckmarkBlock 物件 (使用 IBlock::GetAsCheckmarkBlock 方法) ,並設定所需的參數 (CheckmarkType、IsCorrectionEnabled) 。
務必正確設定核取記號的類型和區域,才能獲得正確的辨識結果。
  1. 若要辨識核取記號,請使用任何可用的辨識方法,例如 IFRPage::RecognizeIFRPage::RecognizeBlocksIFRDocument::RecognizeIFRDocument::RecognizePages 等。
...
// 取得 Layout 物件
FREngine.IFRDocument document = Engine.CreateFRDocumentFromImage("D:\\Sample.tiff", null);
FREngine.ILayout layout = document.Pages[0].Layout;
// 設定區塊區域
FREngine.IRegion region = Engine.CreateRegion();
region.AddRect(0, 0, 100, 50);
// 建立核取記號類型的區塊,並將其新增至版面配置中集合的末尾
FREngine.IBlock block = layout.Blocks.AddNew(FREngine.BlockTypeEnum.BT_Checkmark, region, layout.Blocks.Count);
FREngine.ICheckmarkBlock checkmark = block.GetAsCheckmarkBlock();
...

學習辨識自訂類型的核取記號

ABBYY FineReader Engine 可以辨識標準形式的核取記號:方框中的核取記號、空白背景上的核取記號,以及圓圈中的核取記號 (請參閱 CheckmarkTypeEnum 常數) 。如您在 CheckmarkTypeEnum 列舉常數的說明中所見,還有另一種可辨識的核取記號類型 — CMT_Custom。它用於非標準類型的核取記號。如果您要辨識的影像包含非標準類型的核取記號,您可以訓練 FineReader Engine 來辨識這類核取記號。 若要辨識非標準類型的核取記號:
  1. 找出一張影像,其中包含一些您想要辨識之類型的未勾選核取記號。這可以是包含這些核取記號的空白表單影像。
  2. 由此影像建立 FRDocument 物件。例如,您可以使用 Engine 物件的 CreateFRDocumentFromImage 方法。
  3. 從文件的頁面集合中取得包含核取記號影像的頁面 (IFRDocument::Pages) — 使用 FRPages 集合的屬性和方法。
  4. 透過 IFRPage::Layout 屬性,取得與此頁面對應的 Layout 物件。
  5. 指定頁面上每個核取記號區塊的區域與類型:
  6. 使用 IEngine::CreateRegion 方法建立 Region 物件,並使用 IRegion::AddRect 方法將核取記號區域的矩形加入其中。
  7. 建立核取記號類型的 Block 物件,並使用 ILayoutBlocks::AddNew 方法將其加入版面配置區塊集合 (ILayout::Blocks) (使用 BT_Checkmark 常數和已建立的 Region 物件作為輸入參數) 。
  8. 取得 CheckmarkBlock 物件 (使用 IBlock::GetAsCheckmarkBlock 方法) ,並將其 CheckmarkType 屬性設為 CMT_Custom。
務必正確設定核取記號的類型和區域,才能獲得正確的辨識結果。
  1. 訓練 FineReader Engine 識別此類核取記號:呼叫 FRPage 物件的 LearnCheckmarks 方法。
  2. 這樣一來,您在訓練前建立的 CheckmarkBlock 物件之 TrainingData 屬性會包含自訂核取記號類型的資訊。這項資訊之後可用於識別其他相同類型的核取記號。您可以使用 CheckmarkTrainingData 物件的 SaveToMemory 方法 (僅限 Windows) 或 SaveToFile 方法,將其儲存至檔案或記憶體。
  3. 根據包含此類核取記號的影像建立 FRDocument 物件,在頁面上指定核取記號區塊,並將核取記號類型設為 CMT_Custom。此程序如步驟 2 到 5 所述。
  4. 使用訓練期間取得的 CheckmarkTrainingData 物件,初始化每個 CheckmarkBlock 物件的 TrainingData 屬性。例如,您可以使用 CopyFrom 方法複製該物件,或使用 CheckmarkTrainingData 物件的 LoadFromMemory 方法 (僅限 Windows) 或 LoadFromFile 方法,從檔案或記憶體載入該物件。
  5. 呼叫 FRDocument 或 FRPage 物件的任一識別方法,例如 IFRDocument::Recognize 方法。
  6. 如果您對識別結果不滿意,CheckmarkBlock 物件的 BlackThresholdSuspiciousDistance 屬性可讓您進一步微調設定。訓練完成後,這些屬性的預設值會改為在大多數情況下預期可正常運作的值。當您為核取記號區塊載入 CheckmarkTrainingData 物件時,這些屬性的值也會一併載入。您可以嘗試變更這些屬性的值,然後重新識別核取記號 (重複步驟 10) ;找到最佳組態後,再次儲存 CheckmarkTrainingData 物件,並使用新物件來識別您的自訂類型核取記號。

另請參閱

CheckmarkBlock CheckmarkGroup 使用 Layout 與區塊