typedef struct EXOBJ_OPTIONS
{
L_UINT64 uStructSize;
L_UINT uFlags;
L_RECT * pROI;
L_INT nSmallNoiseThreshold;
L_INT nLargeNoiseThreshold;
L_UINT uContainerMinCount;
L_DOUBLE dTableMaxBorderPercent;
L_INT nTableSizeThreshold;
EXOBJ_COLORINFO * pColorInfo;
L_UINT uColorInfoCount;
L_INT nMaxObjectCount;
} EXOBJ_OPTIONS, * pEXOBJ_OPTIONS;
Provides the options for extracting the objects.
Size of this structure in bytes, for versioning. Use the sizeof(EXOBJ_OPTIONS) operator to calculate this value.
Flags must be a combination of the following values:
Value | Meaning |
---|---|
EXOBJ_8_CONNECTIVITY | [0x0001] Pass to enable 8-way connectivity (diagonals), otherwise 4-way (only NSEW) |
EXOBJ_OUTLINE | [0x0002] Extract pixels along each object's outline |
EXOBJ_DETECT_CHILDREN | [0x0004] Detect the children for each object, and output as a tree of nested objects |
EXOBJ_REPORT_IGNORED | [0x0008] Return ignored noise/containers in their respective lists |
EXOBJ_IGNORE_SMALL_NOISE | [0x0010] Ignore small noise during extraction (refer to nSmallNoiseThreshold) |
EXOBJ_IGNORE_LARGE_NOISE | [0x0020] Ignore large noise during extraction (refer to nLargeNoiseThreshold) |
EXOBJ_IGNORE_CONTAINERS | [0x0040] (Requires EXOBJ_DETECT_CHILDREN) Ignore containers during extraction (refer to uContainerMinCount) |
EXOBJ_CHECK_CONTAINER_SUBCHILDREN | [0x0080] (Requires EXOBJ_IGNORE_CONTAINERS) Check the number of children in a container by recursing to lower objects (not just immediate children) |
EXOBJ_CHECK_FOR_TABLES | [0x0100] (Requires EXOBJ_CHECK_CONTAINER_SUBCHILDREN) When filtering out a container, attempt to preserve the cell containers as children (refer to dTableMaxBorderPercent) |
EXOBJ_USE_MULTICOLORS | [0x0200] Extract objects for each specified color level (instead of just 1 BPP) |
EXOBJ_SORT_TOPLEFT | [0x0400] Sort the object lists in each EXOBJ_RESULT structure (sub-lists not sorted) |
EXOBJ_FLATTEN | [0x0800] (Requires EXOBJ_DETECT_CHILDREN) Flatten the final lists to store the children of an object immediately after the parent, rather than in a tree structure. |
Optional region of interest for extraction.
The maximum pixel size of noise that will be considered too small.
The minimum pixel size of noise that will be considered too large.
The minimum number of sub-objects within a container before ignoring.
The maximum percentage of black pixels (estimated by the area of bounding rectangles) for a container to be considered a table.
The minimum pixel size for a container to be considered a table.
Optional array of color information structures.
The number of items in pColorInfo.
The maximum number of objects to return (or 0 for all objects).
If EXOBJ_IGNORE_LARGE_NOISE
and EXOBJ_IGNORE_SMALL_NOISE
are both specified, iSmallNoiseThreshold
must be smaller than iLargeNoiseThreshold
.
If EXOBJ_USE_MULTICOLORS
is specified, pColorInfo
is NULL, and uColorInfoCount
is 0, then the colors are pulled from BITMAPHANDLE.pPalette.
EXOBJ_SORT_TOPLEFT
is applied after EXOBJ_FLATTEN
and will remove the parent-child ordering in the final lists.
Containers (even if ignored) and sub-children will count towards the iMaxObjectCount
threshold, while small/large noise will not.
The structure is used by:
This example shows how to perform multi-color extraction using L_ExtractObjectsBitmap.
L_INT ExObjOptionsExample(L_VOID)
{
L_INT nRet = SUCCESS;
BITMAPHANDLE InputBitmap = { 0 };
BITMAPHANDLE OutputBitmap = { 0 };
pEXOBJ_DATA pData = NULL;
EXOBJ_OPTIONS ExtractOptions = { 0 };
EXOBJ_COLORINFO ColorInfo[3] = { 0 };
L_TCHAR ColorNames[3][20] = { 0 };
EXOBJ_REGION_OPTIONS RegionOptions = { 0 };
pEXOBJ_OBJECT *pObjectArray = NULL; // Temporary array for L_ExtractObjects_CalcRegion
L_UINT uObjectArrayCount = 0;
// Load the original image
nRet = L_LoadBitmap(MAKE_IMAGE_PATH(TEXT("unwarp1.jpg")), &InputBitmap, sizeof(BITMAPHANDLE), 0, ORDER_BGRORGRAY, NULL, NULL);
if (nRet != SUCCESS)
goto cleanup;
// Setup the extraction options
ExtractOptions.uStructSize = sizeof(EXOBJ_OPTIONS);
ExtractOptions.uFlags = EXOBJ_8_CONNECTIVITY | EXOBJ_DETECT_CHILDREN | EXOBJ_OUTLINE | EXOBJ_IGNORE_SMALL_NOISE | EXOBJ_USE_MULTICOLORS;
ExtractOptions.nSmallNoiseThreshold = 5; // Filter out noise smaller than 5x5 pixels
ColorInfo[0].uStructSize = ColorInfo[1].uStructSize = ColorInfo[2].uStructSize = sizeof(EXOBJ_COLORINFO);
ColorInfo[0].uThreshold = ColorInfo[1].uThreshold = ColorInfo[2].uThreshold = 50;
strcpy_s(ColorNames[0], TEXT("DarkGray"));
ColorInfo[0].crColor = RGB(30, 30, 30);
strcpy_s(ColorNames[1], TEXT("DarkGreen"));
ColorInfo[1].crColor = RGB(41, 108, 70);
strcpy_s(ColorNames[2], TEXT("LightRed"));
ColorInfo[2].crColor = RGB(200, 68, 65);
ExtractOptions.pColorInfo = ColorInfo;
ExtractOptions.uColorInfoCount = 3;
// Extract the objects
nRet = L_ExtractObjectsBitmap(&InputBitmap, &ExtractOptions, &pData);
if (nRet != SUCCESS)
goto cleanup;
// Determine the total number of objects (braces for scope)
{
pEXOBJ_RESULT pResultIter;
for (pResultIter = pData->pHead, uObjectArrayCount = 0; pResultIter != NULL; pResultIter = pResultIter->pNext)
{
uObjectArrayCount += pResultIter->pObjects->uCount;
}
}
// Allocate a new array to hold the objects
pObjectArray = (pEXOBJ_OBJECT*)malloc(uObjectArrayCount * sizeof(pEXOBJ_OBJECT));
if (pObjectArray == NULL)
{
nRet = ERROR_NO_MEMORY;
goto cleanup;
}
// Convert the linked list to an array (braces for scope)
{
pEXOBJ_RESULT pResultIter;
L_INT nIndex;
for (pResultIter = pData->pHead, nIndex = 0; pResultIter != NULL; pResultIter = pResultIter->pNext)
{
pEXOBJ_OBJECT pObjectIter;
for (pObjectIter = pResultIter->pObjects->pHead; pObjectIter != NULL; pObjectIter = pObjectIter->pNext, nIndex++)
pObjectArray[nIndex] = pObjectIter;
}
}
// Setup the region options
RegionOptions.uStructSize = sizeof(EXOBJ_REGION_OPTIONS);
RegionOptions.uFlags = EXOBJ_REGION_HORIZONTAL;
// Calculate each object's region
nRet = L_ExtractObjects_CalcRegion(pData, pObjectArray, uObjectArrayCount, &RegionOptions);
if (nRet != SUCCESS)
goto cleanup;
// Create an output image
nRet = L_CreateBitmap(&OutputBitmap, sizeof(BITMAPHANDLE), TYPE_CONV, InputBitmap.Width, InputBitmap.Height, 24, ORDER_BGR, NULL, TOP_LEFT, NULL, 0);
if (nRet != SUCCESS)
goto cleanup;
// Extract each color to a separate image (braces for scope)
{
pEXOBJ_RESULT pResultIter;
EXOBJ_COLORINFO *pColorIter;
L_INT nNameIndex;
for (pResultIter = pData->pHead, pColorIter = ColorInfo, nNameIndex = 0; pResultIter != NULL; pResultIter = pResultIter->pNext, pColorIter++, nNameIndex++)
{
// Fill the output image with white
nRet = L_FillBitmap(&OutputBitmap, RGB(255, 255, 255));
if (nRet != SUCCESS)
goto cleanup;
// Populate the output image with each object's region (braces for scope)
{
pEXOBJ_OBJECT pObjectIter;
for (pObjectIter = pResultIter->pObjects->pHead; pObjectIter != NULL; pObjectIter = pObjectIter->pNext)
{
pEXOBJ_SEGMENT pSegmentIter;
for (pSegmentIter = pObjectIter->pRegionHorizontal->pHead; pSegmentIter != NULL; pSegmentIter = pSegmentIter->pNext)
{
// Update the region to the current segment
nRet = L_SetBitmapRgnRect(&OutputBitmap, NULL, &pSegmentIter->rcBounds, L_RGN_SET);
if (nRet != SUCCESS)
goto cleanup;
// Fill the region with the current color
nRet = L_FillBitmap(&OutputBitmap, pColorIter->crColor);
if (nRet != SUCCESS)
goto cleanup;
}
}
}
// Clear the output image's region
nRet = L_FreeBitmapRgn(&OutputBitmap);
if (nRet != SUCCESS)
goto cleanup;
// Save the output image (braces for scope)
{
L_TCHAR szOutputFile[MAX_PATH] = { 0 };
sprintf_s(szOutputFile, MAKE_IMAGE_PATH(TEXT("ExtractObjectsMultiColors_%s.png")), ColorNames[nNameIndex]);
nRet = L_SaveBitmap(szOutputFile, &OutputBitmap, FILE_PNG, 0, 0, NULL);
if (nRet != SUCCESS)
goto cleanup;
}
}
}
cleanup:
// Free the loaded images
if (InputBitmap.Flags.Allocated)
L_FreeBitmap(&InputBitmap);
if (OutputBitmap.Flags.Allocated)
L_FreeBitmap(&OutputBitmap);
// Free the results
if (pData != NULL)
L_ExtractObjects_FreeData(&pData);
// Free the array
if (pObjectArray != NULL)
free(pObjectArray);
return nRet;
}
Help Collections
Raster .NET | C API | C++ Class Library | HTML5 JavaScript
Document .NET | C API | C++ Class Library | HTML5 JavaScript
Medical .NET | C API | C++ Class Library | HTML5 JavaScript
Medical Web Viewer .NET
Multimedia
Direct Show .NET | C API | Filters
Media Foundation .NET | C API | Transforms
Supported Platforms
.NET, Java, Android, and iOS/macOS Assemblies
Imaging, Medical, and Document
C API/C++ Class Libraries
Imaging, Medical, and Document
HTML5 JavaScript Libraries
Imaging, Medical, and Document