> ## Documentation Index
> Fetch the complete documentation index at: https://docs.abbyy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Recognizing Checkmarks

> Recognize single checkmarks and checkmark groups with ABBYY FineReader Engine using the BT_Checkmark / BT_CheckmarkGroup block types and the OMR license module.

<Note>
  C# samples are applicable only to FRE for Windows.
</Note>

ABBYY FineReader Engine 12 supports two block types for checkmarks: checkmark and checkmark group. A checkmark group block is a collection of checkmark blocks. These block types have the corresponding constants BT\_Checkmark and BT\_CheckmarkGroup in the [BlockTypeEnum](/fine-reader/engine/api-reference/enumerations/blocktypeenum) enumeration. The [CheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock) and [CheckmarkGroup](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup) objects provide access to the blocks of these types. To receive these objects, you should use the corresponding methods of the [Block](/fine-reader/engine/api-reference/layout-related-objects/block) object.

<Warning>
  To recognize checkmarks, you must have an ABBYY FineReader Engine license that supports the [OMR](/fine-reader/engine/licensing/modules#omr) module.
</Warning>

You can recognize single checkmarks as well as checkmark groups.

One check box corresponds to one CheckmarkBlock object. Possible check box statuses: checked, not checked, corrected. They correspond to [CheckmarkCheckStateEnum](/fine-reader/engine/api-reference/enumerations/checkmarkcheckstateenum). A corrected checkmark is a checkmark that was put in the check box and then was crossed out by the user.

## Detecting checkmarks on the image

Checkmarks can be detected on the image during layout analysis. To enable checkmarks detection, set the [IPageAnalysisParams::DetectCheckmarks](/fine-reader/engine/api-reference/parameter-objects/preprocessing-analysis-recognition-and-synthesis-parameters/pageanalysisparams#detectcheckmarks) property to TRUE.

After analysis completes, the layout will contain a [CheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock) object for each checkmark that was found on the image. They will not be grouped into [CheckmarkGroup](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup)'s. The checkmark type will be detected automatically.

After you call a method that performs recognition (for example, [IFRDocument::Recognize](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognize-method)), or if you use a single method for complete processing (for example, [IFRDocument::Process](/fine-reader/engine/api-reference/document-related-objects/frdocument/process-method)), the checkmark recognition results will be filled in.

<Accordion title="C# code">
  ```csharp theme={null}
  FREngine.IEngine engine;
  FREngine.IFRDocument frdoc;
  // We presume that the document has been created and images have been added to the document
  // Create DocumentProcessingParams and set parameters
  FREngine.IDocumentProcessingParams dpp = engine.CreateDocumentProcessingParams();
  FREngine.IPageProcessingParams ppp = dpp.PageProcessingParams;
  ppp.PageAnalysisParams.DetectCheckmarks = true;
  // Use the parameters for processing
  frDoc.Process( dpp );
  ```
</Accordion>

If you are not satisfied with the results of automatic checkmark detection or need to recognize checkmark groups or custom checkmarks, specify the checkmark regions manually. The following sections describe different scenarios:

* [Recognizing a group of checkmarks](/fine-reader/engine/guided-tour/advanced-techniques/recognizing-checkmarks#group)
* [Recognizing a single checkmark](/fine-reader/engine/guided-tour/advanced-techniques/recognizing-checkmarks#single)
* [Learning to recognize checkmarks of custom type](/fine-reader/engine/guided-tour/advanced-techniques/recognizing-checkmarks#custom)

## Recognizing a group of checkmarks

For a checkmark group, you can specify a minimum and a maximum number of checked check boxes in the group ([MinimumCheckedInGroup](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup#minimumcheckedingroup) and [MaximumCheckedInGroup](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup#maximumcheckedingroup), respectively). These values can be set through the CheckmarkGroup object and will be used during recognition.

All the checkmarks within a checkmark group must have the same values for the [IsCorrectionEnabled](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#iscorrectionenabled) and [CheckmarkType](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#checkmarktype) properties.

The state of the checkmark is calculated according to the percentage of black pixels in the region. It is the smallest for the unchecked checkmark, greater for the checked checkmark, and the largest for the corrected checkmark. Therefore for the right recognition result, it is essential to:

* set the checkmark type correctly because the CMT\_Circle and CMT\_Square type checkmarks have a black frame, which needs to be taken into account when calculating the percentage;
* specify the exact region of the checkmark because the percentage of black would be calculated across the whole region, and if some irrelevant areas are included in the region, the estimate may deteriorate.

To recognize a checkmark group:

1. Create a [FRDocument](/fine-reader/engine/api-reference/document-related-objects/frdocument) object from an image with a checkmark group. For example, you can use the [CreateFRDocumentFromImage](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createfrdocumentfromimage-method) method of the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object.

2. Obtain the page with the image of the checkmarks from the collection of pages of the document ([IFRDocument::Pages](/fine-reader/engine/api-reference/document-related-objects/frdocument#pages)) — use the properties and methods of the [FRPages](/fine-reader/engine/api-reference/document-related-objects/frpages) collection.

3. Obtain the [Layout](/fine-reader/engine/api-reference/layout-related-objects/layout) object which corresponds to this page via the [IFRPage::Layout](/fine-reader/engine/api-reference/document-related-objects/frpage#layout) property.

4. For each checkmark group:

5. Create a [Region](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region) object using the [IEngine::CreateRegion](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createlessobjectgreater-methods) method and add rectangles to it using the [IRegion::AddRect](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region/addrect-method) method.

6. Create a [Block](/fine-reader/engine/api-reference/layout-related-objects/block) object of the checkmark group type and add it into the collection of layout blocks (ILayout::Blocks) by using the [ILayoutBlocks::AddNew](/fine-reader/engine/api-reference/layout-related-objects/layoutblocks/addnew-method) method (use the BT\_CheckmarkGroup constant and the created Region object as input parameters. The method also requires the block index in the layout as the third input parameter).

7. Obtain the CheckmarkGroup object (use the [IBlock::GetAsCheckmarkGroup](/fine-reader/engine/api-reference/layout-related-objects/block/getascheckmarkgroup-method) method).

<Warning>
  It is essential to set the type and the region of the checkmark correctly for the right recognition result.
</Warning>

5. For each checkmark in the group:

6. Create the Region object using the IEngine::CreateRegion method and add rectangles to it using the IRegion::AddRect method.

7. Create a new checkmark block in the group by using the [ICheckmarkGroup::AddNew](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup/addnew-method) method (use the created Region object as an input parameter).

8. Obtain the CheckmarkBlock object (use the [IBlock::GetAsCheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/block/getascheckmarkblock-method) method) and set the required parameters (CheckmarkType, IsCorrectionEnabled).

9. Set necessary parameters of the checkmark group (MinimumCheckedInGroup, MaximumCheckedInGroup).

10. To recognize the checkmarks, use any of the available methods that perform recognition, such as [IFRPage::Recognize](/fine-reader/engine/api-reference/document-related-objects/frpage/recognize-method), [IFRPage::RecognizeBlocks](/fine-reader/engine/api-reference/document-related-objects/frpage/recognizeblocks-method), [IFRDocument::Recognize](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognize-method), [IFRDocument::RecognizePages](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognizepages-method), etc.

<Accordion title="C# code">
  ```csharp theme={null}
  ...
  // Obtain a Layout object
  FREngine.IFRDocument document = Engine.CreateFRDocumentFromImage("D:\\Sample.tiff", null);
  FREngine.ILayout layout = document.Pages[0].Layout;
  // Set block region
  FREngine.IRegion region = Engine.CreateRegion();
  region.AddRect(0, 0, 100, 50);
  // Create a block of the checkmark group type and add it to the layout at the end of the collection
  FREngine.IBlock block = layout.Blocks.AddNew(FREngine.BlockTypeEnum.BT_CheckmarkGroup, region, layout.Blocks.Count);
  FREngine.ICheckmarkGroup checkmarkGroup = block.GetAsCheckmarkGroup();
  // Create blocks of the checkmark type
  // and add them to the checkmark group
  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);
  }
  ...
  ```
</Accordion>

## Recognizing a single checkmark

1. Create a [FRDocument](/fine-reader/engine/api-reference/document-related-objects/frdocument) object from an image with a checkmark. For example, you can use the [CreateFRDocumentFromImage](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createfrdocumentfromimage-method) method of the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object.
2. Obtain the page with the image of the checkmarks from the collection of pages of the document ([IFRDocument::Pages](/fine-reader/engine/api-reference/document-related-objects/frdocument#pages)) — use the properties and methods of the [FRPages](/fine-reader/engine/api-reference/document-related-objects/frpages) collection.
3. Obtain the [Layout](/fine-reader/engine/api-reference/layout-related-objects/layout) object which corresponds to this page via the [IFRPage::Layout](/fine-reader/engine/api-reference/document-related-objects/frpage#layout) property.
4. Create the [Region](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region) object using the [IEngine::CreateRegion](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createlessobjectgreater-methods) method and add rectangles to it using the [IRegion::AddRect](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region/addrect-method) method.
5. Create a [Block](/fine-reader/engine/api-reference/layout-related-objects/block) object of checkmark type and add it into the collection of layout blocks (ILayout::Blocks) by using the [ILayoutBlocks::AddNew](/fine-reader/engine/api-reference/layout-related-objects/layoutblocks/addnew-method) method (use the BT\_Checkmark constant and the created Region object as input parameters).
6. Receive the CheckmarkBlock object (use the [IBlock::GetAsCheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/block/getascheckmarkblock-method) method) and set the required parameters (CheckmarkType, IsCorrectionEnabled).

<Warning>
  It is essential to set the type and the region of the checkmark correctly for the right recognition result.
</Warning>

7. To recognize the checkmark, use any of the available recognition methods, such as [IFRPage::Recognize](/fine-reader/engine/api-reference/document-related-objects/frpage/recognize-method), [IFRPage::RecognizeBlocks](/fine-reader/engine/api-reference/document-related-objects/frpage/recognizeblocks-method), [IFRDocument::Recognize](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognize-method), [IFRDocument::RecognizePages](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognizepages-method), etc.

<Accordion title="C# code">
  ```csharp theme={null}
  ...
  // Obtain a Layout object
  FREngine.IFRDocument document = Engine.CreateFRDocumentFromImage("D:\\Sample.tiff", null);
  FREngine.ILayout layout = document.Pages[0].Layout;
  // Set block region
  FREngine.IRegion region = Engine.CreateRegion();
  region.AddRect(0, 0, 100, 50);
  // Create a block of the checkmark type and add into the layout at the end of the collection
  FREngine.IBlock block = layout.Blocks.AddNew(FREngine.BlockTypeEnum.BT_Checkmark, region, layout.Blocks.Count);
  FREngine.ICheckmarkBlock checkmark = block.GetAsCheckmarkBlock();
  ...
  ```
</Accordion>

## Learning to recognize checkmarks of custom type

ABBYY FineReader Engine can recognize checkmarks of the standard form: checkmarks in squares, checkmarks against an empty background, and checkmarks in circles (see the [CheckmarkTypeEnum](/fine-reader/engine/api-reference/enumerations/checkmarktypeenum) constants). As you can see in the description of CheckmarkTypeEnum enumeration constants, there is one more checkmark type that can be recognized — CMT\_Custom. It is intended for checkmarks of non-standard type. If the images you are going to recognize contain checkmarks of non-standard type, you can train FineReader Engine to recognize this type of checkmarks.

To recognize checkmarks of non-standard type:

1. Find an image with some unchecked checkmarks of the type which you want to recognize. It can be an image of an empty form that contains the checkmarks.

2. Create a [FRDocument](/fine-reader/engine/api-reference/document-related-objects/frdocument) object from this image. For example, you can use the [CreateFRDocumentFromImage](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createfrdocumentfromimage-method) method of the [Engine](/fine-reader/engine/api-reference/engine-object-iengine-interface) object.

3. Obtain the page with the image of the checkmarks from the collection of pages of the document ([IFRDocument::Pages](/fine-reader/engine/api-reference/document-related-objects/frdocument#pages)) — use the properties and methods of the [FRPages](/fine-reader/engine/api-reference/document-related-objects/frpages) collection.

4. Obtain the [Layout](/fine-reader/engine/api-reference/layout-related-objects/layout) object which corresponds to this page via the [IFRPage::Layout](/fine-reader/engine/api-reference/document-related-objects/frpage#layout) property.

5. Specify the region and type of each checkmark block on the page:

6. Create the [Region](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region) object using the [IEngine::CreateRegion](/fine-reader/engine/api-reference/engine-object-iengine-interface/creation-methods/createlessobjectgreater-methods) method and add rectangles of a checkmark region to it using the [IRegion::AddRect](/fine-reader/engine/api-reference/supplementary-objects-and-methods/region/addrect-method) method.

7. Create a [Block](/fine-reader/engine/api-reference/layout-related-objects/block) object of checkmark type and add it into the collection of layout blocks (ILayout::Blocks) by using the [ILayoutBlocks::AddNew](/fine-reader/engine/api-reference/layout-related-objects/layoutblocks/addnew-method) method (use the BT\_Checkmark constant and the created Region object as input parameters).

8. Obtain the CheckmarkBlock object (use the [IBlock::GetAsCheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/block/getascheckmarkblock-method) method) and set its [CheckmarkType](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#checkmarktype) property to CMT\_Custom.

<Warning>
  It is essential to set the type and the region of the checkmark correctly for the right recognition result.
</Warning>

6. Train FineReader Engine to recognize this type of checkmarks: call the [LearnCheckmarks](/fine-reader/engine/api-reference/document-related-objects/frpage/learncheckmarks-method) method of the FRPage object.
7. As a result, the [TrainingData](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#trainingdata) property of the CheckmarkBlock object which you have created before training will contain information on the custom checkmark type. This information now can be used for recognition of other checkmarks of the same type. You can save it to file or memory using the [SaveToMemory](/fine-reader/engine/api-reference/supplementary-objects-and-methods/savetomemory-method) method (Windows only) or the [SaveToFile](/fine-reader/engine/api-reference/supplementary-objects-and-methods/savetofile-method) method of the [CheckmarkTrainingData](/fine-reader/engine/api-reference/layout-related-objects/checkmarktrainingdata) object.
8. Create FRDocument objects from the images which contain the checkmarks of this type, specify blocks of checkmarks on the pages, and set checkmark type to CMT\_Custom. The procedure is described in steps 2 through 5.
9. Initialize the TrainingData property of each CheckmarkBlock object with the CheckmarkTrainingData object obtained during training. For example, you can copy the object using the [CopyFrom](/fine-reader/engine/visual-components-reference/supplementary-objects/spellwordcollection/copyfrom-method) method or load it from file or memory using the [LoadFromMemory](/fine-reader/engine/api-reference/supplementary-objects-and-methods/loadfrommemory-method) method (Windows only) or the [LoadFromFile](/fine-reader/engine/api-reference/supplementary-objects-and-methods/loadfromfile-method) method of the CheckmarkTrainingData object.
10. Call any of the recognition methods of the FRDocument or FRPage object, e.g., [IFRDocument::Recognize](/fine-reader/engine/api-reference/document-related-objects/frdocument/recognize-method) method.
11. The [BlackThreshold](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#blackthreshold) and [SuspiciousDistance](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock#suspiciousdistance) properties of the CheckmarkBlock object enable you to further tune the settings if you are not satisfied with the recognition results. After training, the default values of these properties are replaced with the values that can be expected to work in most cases. When you load the CheckmarkTrainingData object for a checkmark block, the values of these properties are also loaded. You can experiment with changing the values of these properties and re-recognizing the checkmarks (repeating step 10), and when you have found the best configuration, save the CheckmarkTrainingData object again and use the new object to recognize the checkmarks of your custom type.

## See also

[CheckmarkBlock](/fine-reader/engine/api-reference/layout-related-objects/checkmarkblock)

[CheckmarkGroup](/fine-reader/engine/api-reference/layout-related-objects/checkmarkgroup)

[Working with Layout and Blocks](/fine-reader/engine/guided-tour/advanced-techniques/working-with-layout-and-blocks)
