Performs auto decomposition of the page to find the text and graphics zones using predefined parameters.
#include "ltocr.h"
L_LTOCR_API L_INT EXT_FUNCTION L_OcrPage_AutoZone(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. |
Performs auto decomposition of the page to find the text and graphics zones using predefined parameters.
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.
The zones found by this method are added to an internal zones list inside the page. Any previously added zones will be removed from zones list first.
This method finds the zone coordinates (L_OcrZone.Bounds) and type (L_OcrZone.ZoneType). The type of the zone determines its role in the page layout and can be classified into three different groups:
Note: If this L_OcrPage is an empty page, in other words, when the OCR engine performs automatic page decomposing with the L_OcrPage_AutoZone method and could not find any zones in it, the L_OcrPage_Recognize method will fail. It is recommended you call L_OcrPage_AutoZone and then check if there is at least one zone found by the engine (using L_OcrPage_GetZoneCount). If the count is zero, do not call L_OcrPage_Recognize.
Note on L_OcrPage_AutoZone/L_OcrPage_Recognize and the page bitmap: 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 bitmap representation of the bitmap 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 ShowZones(L_TCHAR* message, L_OcrPage ocrPage)
{
L_UINT count = 0;
L_OcrPage_GetZoneCount(ocrPage, &count);
if(count < 1)
{
std::cout << "No Zone information exists to output.\n";
return;
}
std::wcout << message << L":\n" << "----------------------------------\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_AutoZoneExample()
{
L_INT retCode = -1;
BITMAPHANDLE bitmap = { 0 };
L_OcrEngine ocrEngine = NULL;
L_OcrPage ocrPage = NULL;
L_OcrZone ocrZone = { 0 };
L_OcrWriteXmlOptions xmlWriteOptions = { 0 };
// Create an image with some text in it
L_CreateBitmap(&bitmap, sizeof(BITMAPHANDLE), TYPE_CONV, 320, 200, 24, ORDER_BGR, NULL, TOP_LEFT, NULL, 0);
// Create a device context to write with
L_HDC LeadDC = L_CreateLeadDC(&bitmap);
L_INT StartGDIX = 0, /* Drawing coordinates */
StartGDIY = 0,
EndGDIX = BITMAPWIDTH(&bitmap),
EndGDIY = BITMAPHEIGHT(&bitmap);
if(LeadDC != NULL)
{
// Correct viewer coordinates if necessary
if (bitmap.ViewPerspective != TOP_LEFT)
{
L_PointToBitmap ( &bitmap, TOP_LEFT, & StartGDIX, & StartGDIY );
L_PointToBitmap ( &bitmap, TOP_LEFT, & EndGDIX, & EndGDIY );
}
SelectObject(LeadDC, GetStockObject(WHITE_PEN));
SelectObject(LeadDC, GetStockObject(NULL_BRUSH));
RECT drawArea;
SetRect(&drawArea, StartGDIX, StartGDIY, EndGDIX, EndGDIY);
// Make the image white
FillRect(LeadDC, &drawArea, CreateSolidBrush(RGB(255,255,255)));
// Now write some text
SetRect(&drawArea, 0, 0, 100, 20);
int numChars = 11;
DrawText(LeadDC, TEXT("Normal line"), numChars, &drawArea, DT_TOP | DT_LEFT);
// Write a second line
SetRect(&drawArea, 0, 80, 120, 100);
numChars = 15;
DrawText(LeadDC, TEXT("Monospaced line"), numChars, &drawArea, DT_TOP | DT_LEFT);
}
// We don't need this context anymore, so free it
L_DeleteLeadDC(LeadDC);
// Create an instance of the OCR engine
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)
{
// Add image to an OcrPage
L_OcrPage_FromBitmap(ocrEngine, &ocrPage, &bitmap, L_OcrBitmapSharingMode_AutoFree, NULL, NULL);
// Transfer ownership to OCR page
bitmap.Flags.Allocated = 0;
// Show the zones, there should be no zones yet
ShowZones(L_TEXT("Right after the page was created"), ocrPage);
// Perform default AutoZoning on the page
L_OcrPage_AutoZone(ocrPage, NULL, NULL);
// Show the zones, there should be two zones, one for each line
ShowZones(L_TEXT("AutoZone with default parameters"), ocrPage);
// // Update the first zone manually
ocrZone.StructSize = sizeof(L_OcrZone);
L_OcrPage_GetZoneAt(ocrPage, 0, &ocrZone);
// Set it to be a text zone
ocrZone.ZoneType = L_OcrZoneType_Text;
// Update the zone in the page
L_OcrPage_SetZoneAt(ocrPage, 0, &ocrZone);
// Show the zones
ShowZones(L_TEXT("\n\nAfter updating the type of the first zone"), ocrPage);
// Save the zones to a file and then clear them
xmlWriteOptions.StructSize = sizeof(L_OcrWriteXmlOptions);
xmlWriteOptions.Formatted = true;
xmlWriteOptions.Encoding = L_OcrXmlEncoding_UTF8;
wcscpy_s(xmlWriteOptions.Indent, L_TEXT(" "));
// Output created zones to a file
L_OcrPage_SaveZonesFile(ocrPage, MAKE_IMAGE_PATH(L_TEXT("MyZones.xml")), 1, &xmlWriteOptions);
// Remove prior created zones
L_OcrPage_ClearZones(ocrPage);
// Show the zones, there should be no zones since we just cleared them
ShowZones(L_TEXT("\n\nAfter calling save and clear"), ocrPage);
// Re-load the zones
retCode = L_OcrPage_LoadZonesFile(ocrPage, MAKE_IMAGE_PATH(L_TEXT("MyZones.xml")), 1);
if(retCode != SUCCESS)
return retCode;
// Show the zone info again
ShowZones(L_TEXT("\n\nAfter re-loading the zones"), ocrPage);
}
//CLEANUP
if(bitmap.Flags.Allocated)
L_FreeBitmap(&bitmap);
if(ocrPage != NULL)
L_OcrPage_Destroy(ocrPage);
if(ocrEngine != NULL)
L_OcrEngine_Destroy(ocrEngine);
return SUCCESS;
}