L_ExtractObjectsBitmap

Summary

Extracts the connected groups of pixels from a bitmap using various options.

Syntax

#include "l_bitmap.h"

L_LTIMGCOR_API L_INT L_ExtractObjectsBitmap(pBitmap, pOptions, pData)

Parameters

pBITMAPHANDLE pBitmap

Pointer to the bitmap handle that references the bitmap to be processed.

pEXOBJ_OPTIONS pOptions

Extraction options. This value cannot be null.

pEXOBJ_DATA *pData

Pointer to be updated with the extracted objects.

Returns

Value Meaning
SUCCESS The function was successful.
< 1 An error occurred. Refer to Return Codes.

Required DLLs and Libraries

Platforms

Win32, x64, Linux.

Example

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 Version 22.0.2023.7.11
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.

LEADTOOLS Raster Imaging C API Help
Products | Support | Contact Us | Intellectual Property Notices
© 1991-2023 LEAD Technologies, Inc. All Rights Reserved.