#include <mil.h>
#define IMAGE_FILE M_IMAGE_PATH MIL_TEXT("/BlobAnalysis/ElongatedCells.mim")
#define PIXEL_SIZE_X 0.15
#define PIXEL_SIZE_Y 0.17
#define LOW_THRESHOLD_VALUE 165L
#define HIGH_THRESHOLD_VALUE 230L
#define MINIMUM_AREA 4.59
#define MAXIMUM_AREA 10.2
#define MINIMUM_FERET_ELONGATION 2.00
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilImage,
MilImageToDisplay,
MilGraphicList,
MilDestImage,
MilBinLowImage,
MilBinHighImage,
MilBinImage,
MilBlobResult,
MilBlobFeatureList;
MIL_INT SizeX,
SizeY,
NumberOfBlobs;
MIL_DOUBLE *AreaArray,
*CogXArray,
*CogYArray,
*ElongationArray;
MIL_INT i;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
MbufRestore(IMAGE_FILE, MilSystem, &MilImage);
MbufInquire(MilImage, M_SIZE_X, &SizeX);
MbufInquire(MilImage, M_SIZE_Y, &SizeY);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC, &MilDestImage);
MbufAlloc2d(MilSystem, SizeX, SizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC, &MilBinLowImage);
MbufAlloc2d(MilSystem, SizeX, SizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC, &MilBinHighImage);
MbufAlloc2d(MilSystem, SizeX, SizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC, &MilBinImage);
MbufAllocColor(MilSystem, 3, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &MilImageToDisplay);
MbufCopy(MilImage, MilImageToDisplay);
MgraAllocList(MilSystem, M_DEFAULT, &MilGraphicList);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicList);
MdispSelect(MilDisplay, MilImageToDisplay);
MosPrintf(MIL_TEXT("\nOBJECT ANALYSIS USING BLOB RECONSTRUCTION\n"));
MosPrintf(MIL_TEXT("-----------------------------------------\n\n"));
MosPrintf(MIL_TEXT("This program identifies the isolated cells in an image.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MimConvolve(MilImage, MilDestImage, M_DERICHE_FILTER(M_SMOOTH, 50));
MbufCopy(MilDestImage, MilImageToDisplay);
MosPrintf(MIL_TEXT("The image is smoothed to reduce noise.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MimBinarize(MilDestImage, MilBinLowImage, M_FIXED+M_GREATER, LOW_THRESHOLD_VALUE, M_NULL);
MimBinarize(MilDestImage, MilBinHighImage, M_FIXED+M_GREATER, HIGH_THRESHOLD_VALUE, M_NULL);
MbufClear(MilImageToDisplay, 0L);
MbufClearCond(MilImageToDisplay, 255, 0, 0, MilBinLowImage, M_NOT_EQUAL, 0);
MbufClearCond(MilImageToDisplay, 0, 255, 0, MilBinHighImage, M_NOT_EQUAL, 0);
MosPrintf(MIL_TEXT("The blobs that are segmented using a low threshold value are displayed in red.\n"));
MosPrintf(MIL_TEXT("The cells are well segmented, however there is also the presence noise.\n\n"));
MosPrintf(MIL_TEXT("The blobs that are segmented using a high threshold value are displayed in green.\n"));
MosPrintf(MIL_TEXT("The cells are well identified, and there is no noise. However the cells are not well\n"));
MosPrintf(MIL_TEXT("segmented.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MblobReconstruct(MilBinLowImage, MilBinHighImage, MilBinImage, M_RECONSTRUCT_FROM_SEED, M_BINARY);
MbufClearCond(MilImageToDisplay, 0, 0, 255, MilBinImage, M_NOT_EQUAL, 0);
MosPrintf(MIL_TEXT("The blobs segmented using a low threshold that are touching the blobs segmented\n"));
MosPrintf(MIL_TEXT("using a high threshold and displayed in blue.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
McalUniform(MilBinImage, 0, 0, PIXEL_SIZE_X, PIXEL_SIZE_Y, 0, M_DEFAULT);
MblobAllocFeatureList(MilSystem, &MilBlobFeatureList);
MblobSelectFeature(MilBlobFeatureList, M_AREA);
MblobSelectFeature(MilBlobFeatureList, M_CENTER_OF_GRAVITY);
MblobSelectFeature(MilBlobFeatureList, M_FERET_ELONGATION);
MblobAllocResult(MilSystem, &MilBlobResult);
MblobCalculate(MilBinImage, M_NULL, MilBlobFeatureList, MilBlobResult);
MblobControl(MilBlobResult, M_INPUT_SELECT_UNITS, M_WORLD);
MbufCopy(MilImage, MilImageToDisplay);
MgraColor(M_DEFAULT, M_COLOR_RED);
MblobDraw(M_DEFAULT, MilBlobResult, MilGraphicList, M_DRAW_BLOBS, M_DEFAULT, M_DEFAULT);
MblobSelect(MilBlobResult, M_EXCLUDE, M_AREA, M_OUT_RANGE, MINIMUM_AREA, MAXIMUM_AREA);
MblobSelect(MilBlobResult, M_EXCLUDE, M_FERET_ELONGATION, M_LESS, MINIMUM_FERET_ELONGATION, M_NULL);
MblobGetNumber(MilBlobResult, &NumberOfBlobs);
MgraColor(M_DEFAULT, M_COLOR_BLUE);
MblobDraw(M_DEFAULT, MilBlobResult, MilGraphicList, M_DRAW_BLOBS, M_INCLUDED_BLOBS, M_DEFAULT);
MgraColor(M_DEFAULT, M_COLOR_YELLOW);
MblobDraw(M_DEFAULT, MilBlobResult, MilGraphicList, M_DRAW_CENTER_OF_GRAVITY, M_INCLUDED_BLOBS, M_DEFAULT);
MgraColor(M_DEFAULT, M_COLOR_GREEN);
MgraControl(M_DEFAULT, M_BACKGROUND_MODE, M_TRANSPARENT);
MgraFont(M_DEFAULT, MIL_FONT_NAME(M_FONT_DEFAULT_TTF));
MgraControl(M_DEFAULT, M_FONT_SIZE, 12);
MosPrintf(MIL_TEXT("The reconstructed blobs are analyzed to detect only isolated\n"));
MosPrintf(MIL_TEXT("cells (in blue) using their area and elongation measures.\n\n"));
if (NumberOfBlobs>0)
{
MosPrintf(MIL_TEXT("Number of detected cells: %d\n\n"), NumberOfBlobs);
AreaArray = new MIL_DOUBLE[NumberOfBlobs];
CogXArray = new MIL_DOUBLE[NumberOfBlobs];
CogYArray = new MIL_DOUBLE[NumberOfBlobs];
ElongationArray = new MIL_DOUBLE[NumberOfBlobs];
MblobControl(MilBlobResult, M_RESULT_OUTPUT_UNITS, M_PIXEL);
MblobGetResult(MilBlobResult, M_CENTER_OF_GRAVITY_X + M_TYPE_MIL_DOUBLE, CogXArray);
MblobGetResult(MilBlobResult, M_CENTER_OF_GRAVITY_Y + M_TYPE_MIL_DOUBLE, CogYArray);
MblobControl(MilBlobResult, M_RESULT_OUTPUT_UNITS, M_WORLD);
MblobGetResult(MilBlobResult, M_AREA + M_TYPE_MIL_DOUBLE, AreaArray);
MblobGetResult(MilBlobResult, M_FERET_ELONGATION + M_TYPE_MIL_DOUBLE, ElongationArray);
MIL_TEXT_CHAR TextIndex[16];
for(i=0; i < NumberOfBlobs; i++)
{
MosSprintf(TextIndex, 3, MIL_TEXT("%d"), i);
MgraText(M_DEFAULT, MilGraphicList, CogXArray[i]+2, CogYArray[i]-14, TextIndex);
MosPrintf(MIL_TEXT("Blob #%ld:\t[area = %.2f mm^2] [elongation = %.2f]\n"), i, AreaArray[i], ElongationArray[i]);
}
delete []AreaArray;
delete []CogXArray;
delete []CogYArray;
delete []ElongationArray;
}
MosPrintf(MIL_TEXT("Press <Enter> to terminate.\n\n"));
MosGetch();
MgraFree(MilGraphicList);
MblobFree(MilBlobResult);
MblobFree(MilBlobFeatureList);
MbufFree(MilBinLowImage);
MbufFree(MilBinHighImage);
MbufFree(MilBinImage);
MbufFree(MilDestImage);
MbufFree(MilImage);
MbufFree(MilImageToDisplay);
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
return 0;
}