#include <mil.h>
#define EXAMPLE_IMAGE_PATH M_IMAGE_PATH MIL_TEXT("Preprocessing/")
#define IMAGE_FILE EXAMPLE_IMAGE_PATH MIL_TEXT("TouchingObjectsBin.mim")
void MorphoylogyExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2);
void WatershedExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2);
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();
}
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay1,
MilDisplay2,
MilImage;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL, M_NULL, M_NULL);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay1);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay2);
MbufRestore(IMAGE_FILE, MilSystem, &MilImage);
MdispControl(MilDisplay1, M_TITLE, M_PTR_TO_DOUBLE(MIL_TEXT("Original image")));
MdispSelect(MilDisplay1, MilImage);
PrintHeader();
MorphoylogyExample(MilSystem, MilImage, MilDisplay2);
WatershedExample(MilSystem, MilImage, MilDisplay2);
MbufFree(MilImage);
MdispFree(MilDisplay1);
MdispFree(MilDisplay2);
MappFreeDefault(MilApplication, MilSystem, M_NULL, M_NULL, M_NULL);
return 0;
}
#define ERODE_ITERATION_NB 7
#define THICK_ITERATION_NB 12
void MorphoylogyExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2)
{
MIL_ID MilBinImage;
MIL_INT SizeX,
SizeY;
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);
MimErode(MilImage, MilBinImage, ERODE_ITERATION_NB, M_BINARY);
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();
MimThick(MilBinImage, MilBinImage, THICK_ITERATION_NB, M_BINARY);
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();
MimArith(MilImage, MilBinImage, MilBinImage, M_AND);
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);
}
#define MIN_VARIATION 10
void WatershedExample(MIL_ID MilSystem, MIL_ID MilImage, MIL_ID MilDisplay2)
{
MIL_ID MilGrayImage;
MIL_INT SizeX,
SizeY;
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);
MimDistance(MilImage, MilGrayImage, M_CHAMFER_3_4);
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();
MimWatershed(MilGrayImage, M_NULL, MilGrayImage, MIN_VARIATION, M_WATERSHED+M_MAXIMA_FILL);
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();
MimArith(MilImage, MilGrayImage, MilGrayImage, M_AND);
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();
MbufFree(MilGrayImage);
}