/*****************************************************************************/ /* * File name: MImSegment.c * * Synopsis: This program uses the watershed and the edge detection functions * to remove the background of an image with a non-linear lighting. * Then, the watershed and the distance functions are used to separate * the touching objects. */ #include #include /* Source image specifications. */ #define IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Pills.mim") /* Minimal distance and gradient variations for the watershed calculation. */ #define WATERSHED_MINIMAL_GRADIENT_VARIATION 45 #define WATERSHED_MINIMAL_DISTANCE_VARIATION 2 /* Position used to fetch the label of the background. */ #define M_PIXEL_FETCH_POSITION_X 2 #define M_PIXEL_FETCH_POSITION_Y 2 /* Main function. */ void main(void) { MIL_ID MilApplication, /* Application identifier. */ MilSystem, /* System identifier. */ MilDisplay, /* Display identifier. */ MilImage, /* Image buffer identifier. */ MilImageWatershed; /* Image buffer identifier. */ long lFetchedValue = 0; /* Label of the background. */ /* Allocate defaults. */ MappAllocDefault(M_SETUP, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL); /* Restore the source image into two automatically allocated * image buffers and select one of them to the display. */ MbufRestore(IMAGE_FILE, MilSystem, &MilImageWatershed); MbufRestore(IMAGE_FILE, MilSystem, &MilImage); MdispSelect(MilDisplay, MilImage); /* Pause to show the original image. */ printf("\nSEGMENTATION:\n"); printf("-------------\n\n"); printf("An edge detection followed by a watershed will be used to remove\n"); printf("the background.\nPress to continue.\n\n"); getch(); /* Perform a edge detection on the original image. */ MimEdgeDetect(MilImageWatershed, MilImageWatershed, M_NULL, M_SOBEL, M_REGULAR_EDGE_DETECT, M_NULL); /* Find the basins of the edge detected image that have a minimal gray scale * variation of WATERSHED_MINIMAL_GRADIENT_VARIATION. */ MimWatershed(MilImageWatershed, M_NULL, MilImageWatershed, WATERSHED_MINIMAL_GRADIENT_VARIATION, M_MINIMA_FILL+M_BASIN); /* Fetch the label of the background, clip it to zero and clip the other labels to * the maximum value of the buffer. */ MbufGet2d(MilImageWatershed, M_PIXEL_FETCH_POSITION_X, M_PIXEL_FETCH_POSITION_Y, 1, 1, &lFetchedValue); MimClip(MilImageWatershed, MilImageWatershed, M_EQUAL, lFetchedValue, 0, 0, 0); MimClip(MilImageWatershed, MilImage, M_NOT_EQUAL, 0, 0, 0xFF, 0); /* Pause to show the binarized image. */ printf("A distance transformation followed by a watershed will be used \n"); printf("to separate the touching pills.\n"); printf("Press to continue.\n\n"); getch(); /* Perform a distance transformation on the binarized image. */ MimDistance(MilImage, MilImageWatershed, M_CHAMFER_3_4); /* Find the watersheds of the image. */ MimWatershed(MilImageWatershed, M_NULL, MilImageWatershed, WATERSHED_MINIMAL_DISTANCE_VARIATION, M_STRAIGHT_WATERSHED+M_MAXIMA_FILL+M_SKIP_LAST_LEVEL); /* AND the watershed image with the binarized image to separate the touching pills. */ MimArith(MilImageWatershed, MilImage, MilImage, M_AND); /* Pause to show the segmented image. */ printf("Here are the segmented pills.\n"); printf("Press to end.\n\n"); getch(); /* Free all allocations. */ MbufFree(MilImageWatershed); MbufFree(MilImage); MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL); }