Extracts the connected groups of pixels from a bitmap using various options.
#include "l_bitmap.h"
L_LTIMGCOR_API L_INT L_ExtractObjectsBitmap(pBitmap, pOptions, pData)
Pointer to the bitmap handle that references the bitmap to be processed.
Extraction options. This value cannot be null.
Pointer to be updated with the extracted objects.
Value | Meaning |
---|---|
SUCCESS | The function was successful. |
< 1 | An error occurred. Refer to Return Codes. |
Win32, x64, Linux.
This example shows how to use the various object extraction functions.
L_INT ExtractObjectsBitmapExample(L_VOID)
{
L_INT nRet = SUCCESS;
BITMAPHANDLE InputBitmap = { 0 };
BITMAPHANDLE OutputBitmap = { 0 };
pEXOBJ_DATA pData = NULL;
EXOBJ_OPTIONS ExtractOptions = { 0 };
EXOBJ_FILTER_OPTIONS FilterOptions = { 0 };
EXOBJ_CONTENTBOUND ContentBound = { 0 };
EXOBJ_CONTENTBOUND_OPTIONS ContentBoundOptions = { 0 };
EXOBJ_REGION_OPTIONS RegionOptions = { 0 };
pEXOBJ_OBJECT* pObjectArray = NULL; // Temporary array for L_ExtractObjects_CalcRegion
pEXOBJ_OBJECTLIST pObjectList = NULL; // Temporary variable for iterating
// Load the original image
nRet = L_LoadBitmap(MAKE_IMAGE_PATH(TEXT("demoicr2.tif")), &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;
// Extract the objects
nRet = L_ExtractObjectsBitmap(&InputBitmap, &ExtractOptions, &pData);
if (nRet != SUCCESS)
goto cleanup;
// Log the number of objects from the first list
pObjectList = pData->pHead->pObjects;
printf(TEXT("Number of objects (before filtering): %u\n"), pObjectList->uCount);
// Log the number of points around the first object (braces for scope)
{
pEXOBJ_OUTLINE_POINT pIter;
L_INT iCount;
for (pIter = pObjectList->pHead->pOutline->pHead, iCount = 0; pIter != NULL; pIter = pIter->pNext, iCount++)
{
// Nothing to do, just incrementing iCount
}
printf(TEXT("First object's outline length: %d\n"), iCount);
}
// Setup the filter options
FilterOptions.uStructSize = sizeof(EXOBJ_FILTER_OPTIONS);
FilterOptions.nLargeObjectThreshold = -1; // No upper limit on size.
FilterOptions.nSmallObjectThreshold = 10; // Remove objects smaller than 10x10 pixels
// Filter the objects
nRet = L_ExtractObjects_FilterList(pData, pObjectList, &FilterOptions);
if (nRet != SUCCESS)
goto cleanup;
// Log the number of objects again
printf(TEXT("Number of objects (after filtering): %u\n"), pObjectList->uCount);
// Setup the content bound options
ContentBound.uStructSize = sizeof(EXOBJ_CONTENTBOUND);
L_Rect_Make(&ContentBound.rcInput, 192, 260, 323, 146);
ContentBoundOptions.uStructSize = sizeof(EXOBJ_CONTENTBOUND_OPTIONS);
ContentBoundOptions.pObjectsOfInterest = NULL; // Passing NULL to use every object in pData
ContentBoundOptions.uObjectsOfInterestCount = 0; // Passing 0 to use every object in pData
// Calculate the content bounds
nRet = L_ExtractObjects_CalcContentBound(pData, &ContentBound, 1, &ContentBoundOptions);
if (nRet != SUCCESS)
goto cleanup;
// Allocate a new array to hold the objects
pObjectArray = (pEXOBJ_OBJECT*)malloc(pObjectList->uCount * sizeof(pEXOBJ_OBJECT));
if (pObjectArray == NULL)
{
nRet = ERROR_NO_MEMORY;
goto cleanup;
}
// Convert the linked list to an array (braces for scope)
{
pEXOBJ_OBJECT pIter;
L_INT iIndex;
for (pIter = pObjectList->pHead, iIndex = 0; pIter != NULL; pIter = pIter->pNext, iIndex++)
pObjectArray[iIndex] = pIter;
}
// 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, pObjectList->uCount, &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;
// Fill the output image with white
nRet = L_FillBitmap(&OutputBitmap, RGB(255, 255, 255));
if (nRet != SUCCESS)
goto cleanup;
// Draw the content bound rects for the first word. Red for the input, green for the output.
nRet = L_SetBitmapRgnRect(&OutputBitmap, NULL, &ContentBound.rcInput, L_RGN_SET);
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FillBitmap(&OutputBitmap, RGB(255, 0, 0));
if (nRet != SUCCESS)
goto cleanup;
nRet = L_SetBitmapRgnRect(&OutputBitmap, NULL, &ContentBound.rcContent, L_RGN_SET);
if (nRet != SUCCESS)
goto cleanup;
nRet = L_FillBitmap(&OutputBitmap, RGB(0, 255, 0));
if (nRet != SUCCESS)
goto cleanup;
// Populate the output image with each object's region (braces for scope)
{
pEXOBJ_OBJECT pObjectIter;
for (pObjectIter = pObjectList->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 black
nRet = L_FillBitmap(&OutputBitmap, RGB(0, 0, 0));
if (nRet != SUCCESS)
goto cleanup;
}
}
}
// Clear the output image's region
nRet = L_FreeBitmapRgn(&OutputBitmap);
if (nRet != SUCCESS)
goto cleanup;
// Save the output image
nRet = L_SaveBitmap(MAKE_IMAGE_PATH(TEXT("ExtractObjects.png")), &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