Recognizes the OCR data found on this L_OcrPage.
#include "ltocr.h"
L_LTOCR_API L_INT EXT_FUNCTION L_OcrPage_Recognize(page, callback, userData)
Handle to the OCR page.
Optional callback to show operation progress.
Optional user data to pass to the callback function.
Value | Meaning |
---|---|
SUCCESS | The function was successful. |
< 1 | An error occurred. Refer to Return Codes. |
Perform image pre-processing by calling the L_OcrPage_AutoPreprocess method prior to calling L_OcrPage_Recognize.
If the page zones of this L_OcrPage is empty (i.e. there are no zones defined), then the page-layout decomposition process will be activated automatically in order to create a zone list for the bitmap before recognition. Hence, L_OcrPage_AutoZone will be implicitly called.
This method uses the checking subsystem (IOcrSpellCheckManager) to either flag suspicious characters or words, or to allow auto-correction during the recognition process.
After having recognized all the zones on the page, L_OcrPage_Recognize stores the necessary information about the recognized characters internally. You can later use the L_OcrDocument to save the data to a file using the many formats supported by this L_OcrEngine such as Text, PDF or Microsoft Word.
To recognize a multipage document you can iterate through the pages of the L_OcrDocument object and call Recognize on each page in case the OCR document is of memory-based type, otherwise you have to recognize the page before you add it to the L_OcrDocument.
You can use the L_OcrProgressCallback to show the operation progress or to abort it. For more information and an example, refer to L_OcrProgressCallback.
Since the format of the recognized data file is not documented, you can use L_OcrPage_GetRecognizedCharacters and L_OcrPage_SetRecognizedCharacters to examine or modify the data. Any changes you make to the recognition data will be saved in the result document when you save L_OcrDocument.
After the page is successfully recognized, if you tried and called L_OcrPage_IsRecognized method then it should update its 'value' parameter with L_TRUE.
Use L_OcrPage_Unrecognize to clear the recognition data stored in a page.
If you are only interested in the recognition data as text (in other words, you are not planning to save the result document to disk), then you can use the L_OcrPage_GetText method and obtain the result data as a string. A common technique in OCR is to perform form processing by adding a zone manually around the required "field" and calling L_OcrPage_GetText to get the string value of the field.
Since the recognition algorithm may use the checking subsystem, you must set up the L_OcrSpellCheckManager prior to calling L_OcrPage_Recognize.
To get the accuracy and timing data of the latest successful recognition process use L_OcrPage_GetRecognizeStatistics after calling L_OcrPage_Recognize.
Note on AutoZone/Recognize and the page image: In certain cases, L_OcrPage_AutoZone and L_OcrPage_Recognize will perform image processing on the page that might result in the page being manipulated. For example, if you add a zone of type table, the engine might automatically deskew the page if required. This result in the image representation of the image to be different after L_OcrPage_AutoZone or L_OcrPage_Recognize is called. If your application has a requirement to view the bitmap of the page, then call L_OcrPage_GetBitmap after L_OcrPage_AutoZone or L_OcrPage_Recognize to get the latest version of the bitmap representation of the page in case it has changed. The LEADTOOLS OCR Module - LEAD Engine demo for C API do exactly that.
void ShowZonesInfo(L_OcrPage ocrPage)
{
L_UINT count = 0;
L_OcrPage_GetZoneCount(ocrPage, &count);
if(count < 1)
std::cout << "No Zone information exists to output.";
std::cout << "Zones:\n";
for(L_UINT index = 0; index < count; index++)
{
L_OcrZone ocrZone;
ocrZone.StructSize = sizeof(L_OcrZone);
L_OcrPage_GetZoneAt(ocrPage, index, &ocrZone);
std::cout << "Zone index: " << index << std::endl;
std::cout << " Id " << ocrZone.Id << std::endl;
std::cout << " Bounds (" << ocrZone.Bounds.left << ","
<< ocrZone.Bounds.top << ","
<< ocrZone.Bounds.right << ","
<< ocrZone.Bounds.bottom << ")\n";
std::cout << " ZoneType " << ocrZone.ZoneType << std::endl;
std::cout << " CharacterFilters: " << ocrZone.CharacterFilters << std::endl;
std::cout << "----------------------------------\n";
}
}
L_INT L_OcrPage_RecognizeExample()
{
L_OcrEngine ocrEngine = NULL;
L_OcrDocumentManager ocrDocumentManager = NULL;
L_OcrDocument ocrDocument = NULL;
BITMAPHANDLE bitmap = { 0 },
tempBitmap = { 0 };
L_OcrPage ocrPage = NULL;
L_BOOL recognized = false;
// Create an instance of the engine
L_INT retCode = L_OcrEngineManager_CreateEngine(L_OcrEngineType_LEAD, &ocrEngine);
if(retCode != SUCCESS)
return retCode;
// Start the engine using default parameters
std::cout << "Starting up the engine...\n";
retCode = L_OcrEngine_Startup(ocrEngine, NULL, OCR_LEAD_RUNTIME_DIR);
if(retCode != SUCCESS)
goto CLEANUP;
// Load an image to process
retCode = L_LoadBitmap(MAKE_IMAGE_PATH(L_TEXT("Ocr1.tif")), &bitmap, sizeof(BITMAPHANDLE), 0, ORDER_RGB, NULL, NULL);
if(retCode != SUCCESS)
goto CLEANUP;
// Add an image to OCR page. Transfer ownership of the bitmap to the page
retCode = L_OcrPage_FromBitmap(ocrEngine, &ocrPage, &bitmap, L_OcrBitmapSharingMode_AutoFree, NULL, NULL);
if(retCode != SUCCESS)
goto CLEANUP;
// At this point, we have a valid page and bitmap ownership has transfered, so, we do not need to free the bitmap anymore
bitmap.Flags.Allocated = 0;
// Auto-recognize the zones in the page
retCode = L_OcrPage_AutoZone(ocrPage, NULL, NULL);
if(retCode != SUCCESS)
goto CLEANUP;
retCode = L_OcrPage_GetBitmap(ocrPage, L_OcrPageBitmapType_Original, &tempBitmap, sizeof(BITMAPHANDLE));
if(retCode != SUCCESS)
goto CLEANUP;
// Show its information
std::cout << "Size: " << tempBitmap.Width << " by " << tempBitmap.Height <<" pixels\n";
std::cout << "Resolution: " << tempBitmap.XResolution << "by " << tempBitmap.YResolution << " dots/inch\n";
std::cout << "Bits/Pixel: " << tempBitmap.BitsPerPixel << ", Bytes/Line: " << tempBitmap.BytesPerLine << std::endl;
L_RGBQUAD* palette = tempBitmap.pPalette;
int paletteEntries;
if (&palette != NULL)
paletteEntries = sizeof(palette) / 3;
else
paletteEntries = 0;
std::cout << "Number of entries in the palette: " << paletteEntries << std::endl;
std::cout << "Original format of this page: " << tempBitmap.OriginalFormat << std::endl;
retCode = L_OcrPage_IsRecognized(ocrPage, &recognized);
if(retCode != SUCCESS)
goto CLEANUP;
std::cout << "Has this page been recognized? : " << recognized << std::endl;
// Output zone information
ShowZonesInfo(ocrPage);
// Recognize it and save it as PDF
retCode = L_OcrPage_Recognize(ocrPage, NULL, NULL);
if(retCode != SUCCESS)
goto CLEANUP;
// Get the document manager
retCode = L_OcrEngine_GetDocumentManager(ocrEngine, &ocrDocumentManager);
if(retCode != SUCCESS)
goto CLEANUP;
// Create an OCR document
retCode = L_OcrDocumentManager_CreateDocument(ocrDocumentManager, &ocrDocument, L_OcrCreateDocumentOptions_AutoDeleteFile, NULL);
if(retCode != SUCCESS)
goto CLEANUP;
// In Document File Mode, add OcrPage to OcrDocument after recognition
retCode = L_OcrDocument_AddPage(ocrDocument, ocrPage);
if(retCode != SUCCESS)
goto CLEANUP;
retCode = L_OcrDocument_Save(ocrDocument, MAKE_IMAGE_PATH(L_TEXT("Ocr1.pdf")), DOCUMENTFORMAT_PDF, NULL, NULL);
CLEANUP:
if(bitmap.Flags.Allocated)
L_FreeBitmap(&bitmap);
if(ocrPage != NULL)
L_OcrPage_Destroy(ocrPage);
if(ocrDocument != NULL)
L_OcrDocument_Destroy(ocrDocument);
if(ocrEngine != NULL)
L_OcrEngine_Destroy(ocrEngine);
return retCode;
}