Click here to show toolbars of the Web Online Help System: show toolbars |
//********************************************************************************************/ // // File name: ObjectSeparation.cpp // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This example shows two techniques to separate touching objects in a binary image: // // 1- using binary morphological operations. // // 2- using the watershed operation. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved #include <mil.h> // Example image path. #define EXAMPLE_IMAGE_PATH M_IMAGE_PATH MIL_TEXT("Preprocessing/") // Source image file name. #define IMAGE_FILE EXAMPLE_IMAGE_PATH MIL_TEXT("TouchingObjectsBin.mim") // Example functions declarations. void MorphoylogyExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2); void WatershedExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2); //***************************************************************************** // Example description. //***************************************************************************** void PrintHeader() { MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n") MIL_TEXT("ObjectSeparation\n\n") MIL_TEXT("[SYNOPSIS]\n") MIL_TEXT("This example shows two techniques to separate touching objects\n") MIL_TEXT("in a binary image:\n") MIL_TEXT("1- using binary morphological operations.\n") MIL_TEXT("2- using the watershed operation.\n\n") MIL_TEXT("[MODULES USED]\n") MIL_TEXT("Modules used: application, system, display, buffer,\n") MIL_TEXT("image processing.\n\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } //***************************************************************************** // Main. //***************************************************************************** int MosMain(void) { MIL_ID MilApplication, // Application identifier. MilSystem, // System identifier. MilDisplay1, // Display1 identifier. MilDisplay2, // Display2 identifier. MilImage; // Image buffer identifier. // Allocate defaults. MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL); // Allocate two displays. MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay1); MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay2); // Restore source image into image buffer. MbufRestore(IMAGE_FILE, MilSystem, &MilImage); // Set the title of the first display. MdispControl(MilDisplay1, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Original image"))); // Display the image buffer. MdispSelect(MilDisplay1, MilImage); // Print header. PrintHeader(); // Run the example using Morphology. MorphoylogyExample(MilSystem, MilImage, MilDisplay2); // Run the example using watershed transformation. WatershedExample(MilSystem, MilImage, MilDisplay2); // Free allocated resources. MbufFree(MilImage); MdispFree(MilDisplay1); MdispFree(MilDisplay2); MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL); return 0; } // Eroding iteration number #define ERODE_ITERATION_NB 7 // Thickening iteration number #define THICK_ITERATION_NB 12 void MorphoylogyExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2) { MIL_ID MilBinImage; // Image buffer identifier. MIL_INT SizeX, // Size X of the source buffer. SizeY; // Size Y of the source buffer. // Allocate processing image buffers. MbufInquire(MilImage, M_SIZE_X, &SizeX); MbufInquire(MilImage, M_SIZE_Y, &SizeY); MbufAlloc2d(MilSystem, SizeX, SizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &MilBinImage); // Apply an erosion operation. MimErode(MilImage, MilBinImage, ERODE_ITERATION_NB, M_BINARY); // Display the erosion result. MdispControl(MilDisplay2, M_WINDOW_INITIAL_POSITION_X, SizeX+20); MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Erosion result"))); MdispSelect(MilDisplay2, MilBinImage); MosPrintf(MIL_TEXT("----------------------------------------------------\n")); MosPrintf(MIL_TEXT("1- Separation using binary morphological operations.\n\n")); MosPrintf(MIL_TEXT("First, a large erosion operation is applied to ensure breaking\n")); MosPrintf(MIL_TEXT("the links between touching objects.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n")); MosGetch(); // Apply a large thickening operation. MimThick(MilBinImage, MilBinImage, THICK_ITERATION_NB, M_BINARY); // Display the thickening result. MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Thickening result"))); MosPrintf(MIL_TEXT("Next, a large thickening operation is applied.\n")); MosPrintf(MIL_TEXT("Note that it is important that the resulting objects get\n")); MosPrintf(MIL_TEXT("larger than the original objects.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n")); MosGetch(); // Apply a logical AND operation. MimArith(MilImage, MilBinImage, MilBinImage, M_AND); // Display the final separated objects. MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Separated Objects"))); MdispSelect(MilDisplay2, MilBinImage); MosPrintf(MIL_TEXT("Finally, the thickening result is combined with the original image\n")); MosPrintf(MIL_TEXT("using a logical AND operation to split the touching objects.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n")); MosGetch(); MbufFree(MilBinImage); } // The minimum variation of gray-level of a catchment basin. #define MIN_VARIATION 10 void WatershedExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2) { MIL_ID MilGrayImage; // Image buffer identifier. MIL_INT SizeX, // Size X of the source buffer. SizeY; // Size Y of the source buffer. // Allocate processing image buffers. MbufInquire(MilImage, M_SIZE_X, &SizeX); MbufInquire(MilImage, M_SIZE_Y, &SizeY); MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &MilGrayImage); // Calculate the distance transformation. MimDistance(MilImage, MilGrayImage, M_CHAMFER_3_4); // Display the distance transformation result. MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Distance transformation result"))); MdispControl(MilDisplay2, M_VIEW_MODE, M_AUTO_SCALE); MdispSelect(MilDisplay2, MilGrayImage); MosPrintf(MIL_TEXT("--------------------------------------------\n")); MosPrintf(MIL_TEXT("2- Separation using the watershed operation.\n\n")); MosPrintf(MIL_TEXT("First, the distance transformation of the image is calculated.\n")); MosPrintf(MIL_TEXT("Note that the result is remapped for display purposes.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n")); MosGetch(); //Apply a watershed transformation. MimWatershed(MilGrayImage, M_NULL, MilGrayImage, MIN_VARIATION, M_WATERSHED+M_MAXIMA_FILL); // Display the Watershed transformation result. MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Lines of separation"))); MosPrintf(MIL_TEXT("Next, a watershed transformation is applied to the distance\n")); MosPrintf(MIL_TEXT("transformation result to obtain lines of separation.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n")); MosGetch(); // Apply a logical AND operation. MimArith(MilImage, MilGrayImage, MilGrayImage, M_AND); // Display the final separated objects. MdispControl(MilDisplay2, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Separated Objects"))); MosPrintf(MIL_TEXT("Finally, the lines of separation are combined with the original\n")); MosPrintf(MIL_TEXT("image using a logical AND operation to split the touching objects.\n")); MosPrintf(MIL_TEXT("\nPress <Enter> to end.\n\n")); MosGetch(); // Free allocated resources. MbufFree(MilGrayImage); }