Train to recognize additional symbols
Train user patterns
To train a custom symbol pattern, you need a symbol image. You should also set the smallSymbolHeight and BaseLine properties to correct values. Otherwise, the trained pattern fails to function properly.
smallSymbolHeightspecifies the height of small characters in pixels on the source image. By default, the value is0.BaseLinecontains the distance from the baseline to the top edge of the cropped image of the character. The baseline is the line on which the characters are located. The top edge of the image is determined by the character orientation. By default, the value is0.
Example:
In the currency image below, BaseLine=31, smallSymbolHeight=22.
Sample code
.....
private void processWithEngine() {
try {
displayMessage( "Training user pattern..." );
// Setup FREngine
setupFREngine();
//create pattern
ITrainingImagesCollection imagesCollection = engine.CreateTrainingImagesCollection();
ITrainingImage image = loadImage("temp_images/costa_rica_currency.bmp", 31, 22);
imagesCollection.Add(image);
String filename = "costa_rica_currency.ptn";
engine.CreateEmptyUserPattern(filename);
engine.TrainUserPattern(filename, imagesCollection, "₡", 0, TextTypeEnum.TT_Normal);
image.Release();
imagesCollection.Release();
} catch( Exception ex ) {
displayMessage( ex.getMessage() );
}
}
private ITrainingImage loadImage(String filename, int baseLine, int smallSymbolHeight){
ITrainingImage image = engine.CreateTrainingImage();
image.setBaseLine(baseLine);
image.setsmallSymbolHeight(smallSymbolHeight);
IImageDocument imageDoc = engine.OpenImageFile(filename, null, null, null);
IImage bwImage = imageDoc.getBlackWhiteImage();
IRegion region = engine.CreateRegion();
region.AddRect(0, 0, bwImage.getWidth(), bwImage.getHeight());
image.SetImageData(imageDoc, region);
region.Release();
imageDoc.Release();
return image;
}
.....
Prevent memory leaks
ABBYY FineReader Engine provides Java support through Java Native Interface (JNI). JNI allows running native code from Java using a special wrapper in C++.
In this case, pay attention to releasing the objects created with the engine methods.
Example:
IFRDocument document = engine.CreateFRDocument();
...
FRPages pages = document.getPages();
for(int i=0; i < pages.getCount(); i++) {
FRPage page = pages.getElement(i);
ILayout layout = page.getLayout();
ILayoutBlocks blocks = layout.getBlocks();
.....
.....
.....
page.Release();
layout.Release();
blocks.Release();
}
pages.Release();
.....
ITextExportParams txtParams = engine.CreateTextExportParams();
.....
txtParams.Release();
.....
document.Release();
To make sure all objects are releasing correctly, enable the debug mode:
engine.StartLogging("filename.log", true);
Then, check the log file to make sure the following message is not there:
Not all objects were released before DeinitializeEngine()