#include "ltocr.h"
L_LTOCR_API L_INT EXT_FUNCTION L_OcrPage_Recognize(page, callback, userData)
Recognizes the OCR data found on this L_OcrPage.
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.
Required DLLs and Libraries
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 engineL_INT retCode = L_OcrEngineManager_CreateEngine(L_OcrEngineType_Advantage, &ocrEngine);if(retCode != SUCCESS)return retCode;// Start the engine using default parametersstd::cout << "Starting up the engine...\n";retCode = L_OcrEngine_Startup(ocrEngine, NULL, OCR_ADVANTAGE_RUNTIME_DIR);if(retCode != SUCCESS)goto CLEANUP;// Load an image to processretCode = 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 pageretCode = 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 anymorebitmap.Flags.Allocated = 0;// Auto-recognize the zones in the pageretCode = 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 informationstd::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;elsepaletteEntries = 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 informationShowZonesInfo(ocrPage);// Recognize it and save it as PDFretCode = L_OcrPage_Recognize(ocrPage, NULL, NULL);if(retCode != SUCCESS)goto CLEANUP;// Get the document managerretCode = L_OcrEngine_GetDocumentManager(ocrEngine, &ocrDocumentManager);if(retCode != SUCCESS)goto CLEANUP;// Create an OCR documentretCode = L_OcrDocumentManager_CreateDocument(ocrDocumentManager, &ocrDocument, L_OcrCreateDocumentOptions_AutoDeleteFile, NULL);if(retCode != SUCCESS)goto CLEANUP;// In Document File Mode, add OcrPage to OcrDocument after recognitionretCode = 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;}