#include <mil.h>
#define SIMPLESTAT_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Rotwafer.mim")
#define CUMULATIVESTAT_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("LargeWafer.mim")
#define WINDOWSTAT_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Preprocessing/DefectiveFabric.tif")
#define MIN_STANDARD_DEVIATION 10
void BasicStats(MIL_ID MilSystem, MIL_ID MillDisplay);
void CumulativeStats(MIL_ID MilSystem, MIL_ID MillDisplay);
void MovingWindowStats(MIL_ID MilSystem, MIL_ID MillDisplay);
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("VariousStatistics\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This example demonstrates how to calculate various statistics using MIL.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: application, buffer, display, graphics,\n")
MIL_TEXT("image processing, pattern matching, system.\n\n"));
}
int MosMain()
{
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilGraphicList;
PrintHeader();
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
MgraAllocList(MilSystem, M_DEFAULT, &MilGraphicList);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicList);
MosPrintf(MIL_TEXT("Example 1 - Basic statistics with conditions.\n"));
MosPrintf(MIL_TEXT("---------------------------------------------\n\n"));
BasicStats(MilSystem, MilDisplay);
MosPrintf(MIL_TEXT("Example 2 - Using cumulative statistics to define a better model.\n"));
MosPrintf(MIL_TEXT("-----------------------------------------------------------------\n\n"));
CumulativeStats(MilSystem, MilDisplay);
MosPrintf(MIL_TEXT("Example 3 - Texture statistics applied to defect detection.\n"));
MosPrintf(MIL_TEXT("-----------------------------------------------------------\n\n"));
MovingWindowStats(MilSystem, MilDisplay);
MgraFree(MilGraphicList);
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
return 0;
}
void BasicStats(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID MilImage = MbufRestore(SIMPLESTAT_IMAGE_FILE, MilSystem, M_NULL);
MdispSelect(MilDisplay, MilImage);
MIL_ID MilStatContext = MimAlloc(MilSystem, M_STATISTICS_CONTEXT, M_DEFAULT, M_NULL);
MIL_ID MilStatResult = MimAllocResult(MilSystem, M_DEFAULT, M_STATISTICS_RESULT, M_NULL);
MimControl(MilStatContext, M_STAT_MIN, M_ENABLE);
MimControl(MilStatContext, M_STAT_MAX, M_ENABLE);
MimStatCalculate(MilStatContext, MilImage, MilStatResult, M_DEFAULT);
MIL_DOUBLE StatMinVal, StatMaxVal, StatMeanVal;
MimGetResult(MilStatResult, M_STAT_MIN, &StatMinVal);
MimGetResult(MilStatResult, M_STAT_MAX, &StatMaxVal);
MimControl(MilStatContext, M_STAT_MIN, M_DISABLE);
MimControl(MilStatContext, M_STAT_MAX, M_DISABLE);
MimControl(MilStatContext, M_STAT_MEAN, M_ENABLE);
MimControl(MilStatContext, M_CONDITION, M_IN_RANGE);
MimControl(MilStatContext, M_COND_LOW, StatMinVal +1);
MimControl(MilStatContext, M_COND_HIGH, StatMaxVal -1);
MimStatCalculate(MilStatContext, MilImage, MilStatResult, M_DEFAULT);
MimGetResult(MilStatResult, M_STAT_MEAN, &StatMeanVal);
MosPrintf(MIL_TEXT("Global image statistics:\n")
MIL_TEXT("------------------------\n"));
MosPrintf(MIL_TEXT("The minimum pixel value is %.2f.\n"), StatMinVal);
MosPrintf(MIL_TEXT("The maximum pixel value is %.2f.\n"), StatMaxVal);
MosPrintf(MIL_TEXT("Excluding the extreme values, the image's average pixel value is %.2f.\n"), StatMeanVal);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MimFree(MilStatResult);
MimFree(MilStatContext);
MbufFree(MilImage);
}
#define CUMULATIVESTAT_MODEL_OFF_X 36
#define CUMULATIVESTAT_MODEL_OFF_Y 66
#define CUMULATIVESTAT_MODEL_SIZE_X 350
#define CUMULATIVESTAT_MODEL_SIZE_Y 350
#define MAX_OCCURRENCE_NUM 10
void CumulativeStats(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID MilGraphicList,
MilImage,
MilChildImage,
MilStatImage,
MilStatCumulativeContext,
MilStatCumulativeResult;
MIL_INT NumResults, i;
MIL_DOUBLE AnnotationColor = M_COLOR_GREEN,
MaskColor = M_COLOR_RED,
ScoreArray[MAX_OCCURRENCE_NUM]={0},
PosXArray[MAX_OCCURRENCE_NUM] ={0},
PosYArray[MAX_OCCURRENCE_NUM] ={0};
MbufRestore(CUMULATIVESTAT_IMAGE_FILE, MilSystem, &MilImage);
MdispSelect(MilDisplay, MilImage);
MdispInquire(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, &MilGraphicList);
MIL_ID MilPatContxt = MpatAlloc(MilSystem, M_NORMALIZED, M_DEFAULT, M_NULL);
MosPrintf(MIL_TEXT("Define the pattern matching model using the top-left occurrence.\n\n"));
MpatDefine(MilPatContxt, M_REGULAR_MODEL, MilImage, CUMULATIVESTAT_MODEL_OFF_X, CUMULATIVESTAT_MODEL_OFF_Y, CUMULATIVESTAT_MODEL_SIZE_X, CUMULATIVESTAT_MODEL_SIZE_Y, M_DEFAULT);
MpatControl(MilPatContxt, M_DEFAULT, M_NUMBER, M_ALL);
MpatControl(MilPatContxt, M_DEFAULT, M_REFERENCE_X, 0);
MpatControl(MilPatContxt, M_DEFAULT, M_REFERENCE_Y, 0);
MpatPreprocess(MilPatContxt, M_DEFAULT, MilImage);
MgraColor(M_DEFAULT, AnnotationColor);
MpatDraw(M_DEFAULT, MilPatContxt, MilGraphicList, M_DRAW_BOX, M_DEFAULT, M_ORIGINAL);
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("Find other model occurrences.\n"));
MIL_ID MilPatResult = MpatAllocResult(MilSystem, M_DEFAULT, M_NULL);
MpatFind(MilPatContxt, MilImage, MilPatResult);
MpatGetResult(MilPatResult, M_GENERAL, M_NUMBER+M_TYPE_MIL_INT, &NumResults);
MpatGetResult(MilPatResult, M_DEFAULT, M_POSITION_X, PosXArray);
MpatGetResult(MilPatResult, M_DEFAULT, M_POSITION_Y, PosYArray);
MpatGetResult(MilPatResult, M_DEFAULT, M_SCORE, ScoreArray);
MgraColor(M_DEFAULT, AnnotationColor);
MpatDraw(M_DEFAULT, MilPatResult, MilGraphicList, M_DRAW_BOX,M_DEFAULT, M_DEFAULT);
MosPrintf(MIL_TEXT("- %d occurrences found\n\n"), NumResults);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("Calculate the average and the deviation statistic images using the\n%d occurrences.\n"), NumResults);
MbufAlloc2d(MilSystem, CUMULATIVESTAT_MODEL_SIZE_X, CUMULATIVESTAT_MODEL_SIZE_Y, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &MilStatImage);
MilStatCumulativeContext = MimAlloc(MilSystem, M_STATISTICS_CUMULATIVE_CONTEXT, M_DEFAULT, M_NULL);
MilStatCumulativeResult = MimAllocResult(MilSystem, M_DEFAULT, M_STATISTICS_RESULT, M_NULL);
MimControl(MilStatCumulativeContext, M_STAT_MEAN, M_ENABLE);
MimControl(MilStatCumulativeContext, M_STAT_STANDARD_DEVIATION, M_ENABLE);
MimControl(MilStatCumulativeContext, M_SOURCE_SIZE_X, CUMULATIVESTAT_MODEL_SIZE_X);
MimControl(MilStatCumulativeContext, M_SOURCE_SIZE_Y, CUMULATIVESTAT_MODEL_SIZE_Y);
MimStatCalculate(MilStatCumulativeContext, M_NULL, MilStatCumulativeResult, M_PREPROCESS);
MbufChild2d(MilImage, 0, 0, CUMULATIVESTAT_MODEL_SIZE_X, CUMULATIVESTAT_MODEL_SIZE_Y, &MilChildImage);
for(i =0; i<NumResults; i++)
{
MbufChildMove(MilChildImage, (MIL_INT)PosXArray[i], (MIL_INT)PosYArray[i], CUMULATIVESTAT_MODEL_SIZE_X, CUMULATIVESTAT_MODEL_SIZE_Y, M_DEFAULT);
MimStatCalculate(MilStatCumulativeContext, MilChildImage, MilStatCumulativeResult, M_DEFAULT);
}
MosPrintf(MIL_TEXT("A new model is defined using the average image.\n")
MIL_TEXT("Unstable pixels are identified using a threshold operation on the standard\n")
MIL_TEXT(" deviation image. The resulting image is used to mask out model pixels.\n\n"));
MimDraw(M_DEFAULT, MilStatCumulativeResult, M_NULL, MilStatImage, M_DRAW_STAT_RESULT, M_STAT_MEAN, M_NULL, M_DEFAULT);
MpatDefine(MilPatContxt, M_DELETE, M_NULL, M_ALL, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MpatDefine(MilPatContxt, M_REGULAR_MODEL, MilStatImage, 0, 0, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MpatControl(MilPatContxt, M_DEFAULT, M_NUMBER, M_ALL);
MpatControl(MilPatContxt, M_DEFAULT, M_REFERENCE_X, 0);
MpatControl(MilPatContxt, M_DEFAULT, M_REFERENCE_Y, 0);
MimDraw(M_DEFAULT, MilStatCumulativeResult, M_NULL, MilStatImage, M_DRAW_STAT_RESULT, M_STAT_STANDARD_DEVIATION, M_NULL, M_DEFAULT);
MimBinarize(MilStatImage, MilStatImage, M_FIXED + M_GREATER, MIN_STANDARD_DEVIATION, M_NULL);
MpatMask(MilPatContxt, M_DEFAULT, MilStatImage, M_DONT_CARE, M_DEFAULT);
MpatPreprocess(MilPatContxt, M_DEFAULT, MilImage);
MIL_ID MilDisplayStat = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL);
MbufClear(MilStatImage, 0);
MdispSelect(MilDisplayStat, MilStatImage);
MIL_ID MilOverlay = MdispInquire(MilDisplayStat, M_OVERLAY_ID, M_NULL);
MdispControl(MilDisplayStat, M_WINDOW_INITIAL_POSITION_X, MbufInquire(MilImage, M_SIZE_X, M_NULL) + 15);
MgraColor(M_DEFAULT, MaskColor);
MpatDraw(M_DEFAULT, MilPatContxt, MilStatImage, M_DRAW_IMAGE, M_DEFAULT, M_DEFAULT);
MpatDraw(M_DEFAULT, MilPatContxt, MilOverlay, M_DRAW_DONT_CARE, M_DEFAULT, M_DEFAULT);
MosPrintf(MIL_TEXT("\nThe new model and its mask (in red) are displayed.\n\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MdispSelect(MilDisplayStat, M_NULL);
MosPrintf(MIL_TEXT("Find occurrences using the improved model:\n\n"));
MpatFind(MilPatContxt, MilImage, MilPatResult);
MpatGetResult(MilPatResult, M_DEFAULT, M_POSITION_X, PosXArray);
MpatGetResult(MilPatResult, M_DEFAULT, M_POSITION_Y, PosYArray);
MpatGetResult(MilPatResult, M_DEFAULT, M_SCORE, ScoreArray);
MgraClear(M_DEFAULT, MilGraphicList);
MgraColor(M_DEFAULT, M_COLOR_BLUE);
MpatDraw(M_DEFAULT, MilPatResult, MilGraphicList, M_DRAW_BOX,M_DEFAULT, M_DEFAULT);
for(i =0; i<NumResults; i++)
MosPrintf(MIL_TEXT("%.2f at (%.2f, %.2f)\n"), ScoreArray[i], PosXArray[i], PosYArray[i]);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MgraClear(M_DEFAULT, MilGraphicList);
MdispFree(MilDisplayStat);
MbufFree(MilStatImage);
MbufFree(MilChildImage);
MbufFree(MilImage);
MimFree(MilStatCumulativeResult);
MimFree(MilStatCumulativeContext);
MpatFree(MilPatResult);
MpatFree(MilPatContxt);
}
#define WINDOW_SIZE_X 12
#define WINDOW_SIZE_Y 12
#define WINDOW_STEP_X 12
#define WINDOW_STEP_Y 12
#define MAX_NB_EVENTS 20
void MovingWindowStats(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID MilGraphicList;
MdispInquire(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, &MilGraphicList);
MIL_ID MilImage = MbufRestore(WINDOWSTAT_IMAGE_FILE, MilSystem, M_NULL);
MdispSelect(MilDisplay, MilImage);
MIL_INT SizeX = MbufInquire(MilImage, M_SIZE_X, M_NULL);
MIL_INT SizeY = MbufInquire(MilImage, M_SIZE_Y, M_NULL);
MIL_ID MilDisplayStat = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL);
MdispControl(MilDisplayStat, M_WINDOW_INITIAL_POSITION_X, SizeX+15);
MIL_ID MilStatContext = MimAlloc(MilSystem, M_STATISTICS_CONTEXT, M_DEFAULT, M_NULL);
MIL_ID MilStatResult = MimAllocResult(MilSystem, M_DEFAULT, M_STATISTICS_RESULT, M_NULL);
MimControl(MilStatContext, M_TILE_SIZE_X, WINDOW_SIZE_X);
MimControl(MilStatContext, M_TILE_SIZE_Y, WINDOW_SIZE_Y);
MimControl(MilStatContext, M_GLCM_PAIR_OFFSET_X, 2);
MimControl(MilStatContext, M_STEP_SIZE_X, WINDOW_STEP_X);
MimControl(MilStatContext, M_STEP_SIZE_Y, WINDOW_STEP_Y);
MimControl(MilStatContext, M_STAT_GLCM_HOMOGENEITY, M_ENABLE);
MimStatCalculate(MilStatContext, MilImage, MilStatResult, M_DEFAULT);
MIL_ID MilFloatImage = MbufAlloc2d(MilSystem, SizeX/WINDOW_STEP_X, SizeY/WINDOW_STEP_Y, 32+M_FLOAT, M_IMAGE+M_PROC+M_DISP, M_NULL);
MimDraw(M_DEFAULT, MilStatResult, M_NULL, MilFloatImage, M_DRAW_STAT_RESULT, M_STAT_GLCM_HOMOGENEITY, M_NULL, M_DEFAULT);
MdispZoom(MilDisplayStat, WINDOW_STEP_X, WINDOW_STEP_Y);
MdispControl(MilDisplayStat, M_VIEW_MODE, M_AUTO_SCALE);
MdispControl(MilDisplayStat, M_SCALE_DISPLAY, M_ENABLE);
MdispSelect(MilDisplayStat, MilFloatImage);
MosPrintf(MIL_TEXT("A source image of a textured object is restored and displayed.\n"));
MosPrintf(MIL_TEXT("The homogeneity windowed statistic is calculated and displayed.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MimControl(MilStatContext, M_STAT_GLCM_HOMOGENEITY, M_DISABLE);
MimControl(MilStatContext, M_TILE_SIZE_X, M_DEFAULT);
MimControl(MilStatContext, M_TILE_SIZE_Y, M_DEFAULT);
MimControl(MilStatContext, M_STEP_SIZE_X, M_DEFAULT);
MimControl(MilStatContext, M_STEP_SIZE_Y, M_DEFAULT);
MimControl(MilStatContext, M_STAT_MEAN, M_ENABLE);
MimControl(MilStatContext, M_STAT_STANDARD_DEVIATION, M_ENABLE);
MimStatCalculate(MilStatContext, MilFloatImage, MilStatResult, M_DEFAULT);
MosPrintf(MIL_TEXT("A threshold is applied to the homogeneity statistic based on its deviation\nto the mean."));
MIL_DOUBLE Mean, Sigma, Threshold;
MimGetResult(MilStatResult, M_STAT_MEAN, &Mean);
MimGetResult(MilStatResult, M_STAT_STANDARD_DEVIATION, &Sigma);
Threshold = Mean + 3*Sigma;
MosPrintf(MIL_TEXT(" The result is then analyzed using MimLocateEvent() function to\n")
MIL_TEXT("determine the presence of defects.\n\n"));
MIL_INT MilEventResult = MimAllocResult(MilSystem, MAX_NB_EVENTS, M_EVENT_LIST, M_NULL),
NbEvents;
MimLocateEvent(MilFloatImage, MilEventResult, M_GREATER_OR_EQUAL, Threshold, M_NULL);
MimGetResult(MilEventResult, M_NB_EVENT, &NbEvents);
MIL_INT* EventXPtr = new MIL_INT[MAX_NB_EVENTS];
MIL_INT* EventYPtr = new MIL_INT[MAX_NB_EVENTS];
MimGetResult(MilEventResult, M_POSITION_X + M_TYPE_MIL_INT, EventXPtr);
MimGetResult(MilEventResult, M_POSITION_Y + M_TYPE_MIL_INT, EventYPtr);
MgraColor(M_DEFAULT, M_COLOR_RED);
for(MIL_INT i=0; i<NbEvents; i++)
MgraRect(M_DEFAULT, MilGraphicList, EventXPtr[i]*WINDOW_SIZE_X, EventYPtr[i]*WINDOW_SIZE_Y, EventXPtr[i]*WINDOW_SIZE_X+WINDOW_SIZE_X, EventYPtr[i]*WINDOW_SIZE_Y+WINDOW_SIZE_Y);
MosPrintf(MIL_TEXT("The resulting defects, if any, are displayed.\n\n"));
delete [] EventYPtr;
delete [] EventXPtr;
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
MimFree(MilEventResult);
MdispFree(MilDisplayStat);
MbufFree(MilFloatImage);
MimFree(MilStatResult);
MimFree(MilStatContext);
MbufFree(MilImage);
}