메인 콘텐츠로 건너뛰기
C# 샘플은 Windows용 FRE에서만 적용됩니다.
ABBYY FineReader Engine 12는 체크 표시에 대해 두 가지 블록 유형, 즉 체크 표시와 체크 표시 그룹을 지원합니다. 체크 표시 그룹 블록은 체크 표시 블록의 모음입니다. 이러한 블록 유형에는 BlockTypeEnum 열거형에 соответств하는 상수 BT_Checkmark와 BT_CheckmarkGroup이 있습니다. CheckmarkBlockCheckmarkGroup 객체를 통해 이러한 유형의 블록에 액세스할 수 있습니다. 이 객체들을 얻으려면 Block 객체의 해당 메서드를 사용해야 합니다.
체크 표시를 인식하려면 OMR 모듈을 지원하는 ABBYY FineReader Engine 라이선스가 있어야 합니다.
개별 체크 표시와 체크 표시 그룹을 모두 인식할 수 있습니다. 체크 상자 하나는 CheckmarkBlock 객체 하나에 해당합니다. 가능한 체크 상자 상태는 checked, not checked, corrected입니다. 이는 CheckmarkCheckStateEnum에 해당합니다. corrected 체크 표시는 사용자가 체크 상자에 표시한 후 그 표시를 지운 체크 표시를 말합니다.

이미지에서 체크 표시 감지하기

레이아웃 분석 중에 이미지에서 체크 표시를 감지할 수 있습니다. 체크 표시 감지를 사용하려면 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_Circle 및 CMT_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::Recognize, IFRPage::RecognizeBlocks, IFRDocument::Recognize, IFRDocument::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::Recognize, IFRPage::RecognizeBlocks, IFRDocument::Recognize, IFRDocument::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 엔진이 이 유형의 체크 표시를 인식하도록 학습시킵니다. FRPage 객체의 LearnCheckmarks 메서드를 호출합니다.
  2. 그러면 학습 전에 생성한 CheckmarkBlock 객체의 TrainingData 속성에 사용자 지정 체크 표시 유형에 대한 정보가 저장됩니다. 이제 이 정보는 같은 유형의 다른 체크 표시를 인식하는 데 사용할 수 있습니다. CheckmarkTrainingData 객체의 SaveToMemory 메서드(Windows만 해당) 또는 SaveToFile 메서드를 사용하여 이 정보를 파일이나 메모리에 저장할 수 있습니다.
  3. 이 유형의 체크 표시가 포함된 이미지에서 FRDocument 객체를 생성하고, 페이지에서 체크 표시 블록을 지정한 다음 체크 표시 유형을 CMT_Custom으로 설정합니다. 이 절차는 2단계부터 5단계에 설명되어 있습니다.
  4. 각 CheckmarkBlock 객체의 TrainingData 속성을 학습 중에 얻은 CheckmarkTrainingData 객체로 초기화합니다. 예를 들어, CopyFrom 메서드를 사용해 객체를 복사하거나, CheckmarkTrainingData 객체의 LoadFromMemory 메서드(Windows만 해당) 또는 LoadFromFile 메서드를 사용해 파일이나 메모리에서 로드할 수 있습니다.
  5. FRDocument 또는 FRPage 객체의 인식 메서드 중 하나를 호출합니다. 예를 들어 IFRDocument::Recognize 메서드가 있습니다.
  6. 인식 결과가 만족스럽지 않으면 CheckmarkBlock 객체의 BlackThresholdSuspiciousDistance 속성을 사용해 설정을 추가로 조정할 수 있습니다. 학습 후에는 이러한 속성의 기본값이 대부분의 경우에 적절하게 작동할 것으로 예상되는 값으로 대체됩니다. 체크 표시 블록에 대해 CheckmarkTrainingData 객체를 로드하면 이러한 속성의 값도 함께 로드됩니다. 이 속성들의 값을 변경한 후 체크 표시를 다시 인식하도록(10단계 반복) 테스트해 볼 수 있으며, 최적의 구성을 찾으면 CheckmarkTrainingData 객체를 다시 저장하고 새 객체를 사용해 사용자 지정 유형의 체크 표시를 인식할 수 있습니다.

참고 항목

CheckmarkBlock CheckmarkGroup Layout 및 블록 작업