#include <mil.h>
#define DISPLAY_CENTER_MARGIN_X 5
#define COLOR_PATCH_SIZEX 30
#define COLOR_PATCH_SIZEY 40
void ColorSegmentationExample(MIL_ID MilSystem, MIL_ID MilDisplay);
void ColorMatchingExample(MIL_ID MilSystem, MIL_ID MilDisplay);
void ColorSeparationExample(MIL_ID MilSystem, MIL_ID MilDisplay);
void DrawSampleColors(MIL_ID DestImage,
const MIL_INT pSamplesColors[][3],
MIL_CONST_TEXT_PTR *pSampleNames,
MIL_INT NumSamples,
MIL_INT XSpacing,
MIL_INT YOffset);
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
ColorSegmentationExample(MilSystem, MilDisplay);
ColorMatchingExample(MilSystem, MilDisplay);
ColorSeparationExample(MilSystem, MilDisplay);
MappFreeDefault(MilApplication, MilSystem, MilDisplay, M_NULL, M_NULL);
return 0;
}
#define CANDY_SAMPLE_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("CandySamples.mim")
#define CANDY_TARGET_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("Candy.mim")
#define NUM_SAMPLES 6
#define CANDY_SAMPLES_XSPACING 35
#define CANDY_SAMPLES_YOFFSET 145
#define MATCH_MODE M_MIN_DIST_VOTE
#define DISTANCE_TYPE M_MAHALANOBIS
#define TOLERANCE_MODE M_SAMPLE_STDDEV
#define TOLERANCE_VALUE 6.0
#define RED_TOLERANCE_VALUE 6.0
#define YELLOW_TOLERANCE_VALUE 12.0
#define PINK_TOLERANCE_VALUE 5.0
void ColorSegmentationExample(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID SourceChild = M_NULL,
DestChild = M_NULL,
MatchContext = M_NULL,
MatchResult = M_NULL,
DisplayImage = M_NULL;
MIL_INT SourceSizeX, SourceSizeY,
SampleIndex, SpacesIndex;
MIL_DOUBLE MatchScore;
MIL_CONST_TEXT_PTR Spaces[4] = { MIL_TEXT(""),
MIL_TEXT(" "),
MIL_TEXT(" "),
MIL_TEXT(" ") };
MIL_CONST_TEXT_PTR SampleNames[NUM_SAMPLES] = { MIL_TEXT("Green"),
MIL_TEXT("Red"),
MIL_TEXT("Yellow"),
MIL_TEXT("Purple"),
MIL_TEXT("Blue"),
MIL_TEXT("Pink") };
const MIL_DOUBLE SamplesROI[NUM_SAMPLES][2] = { { 58, 143},
{136, 148},
{217, 144},
{295, 142},
{367, 143},
{442, 147} };
const MIL_DOUBLE SampleSizeX = 36, SampleSizeY = 32;
MIL_INT SampleMatchColor[NUM_SAMPLES][3];
MosPrintf(MIL_TEXT("\nCOLOR SEGMENTATION:\n"));
MosPrintf( MIL_TEXT("-------------------\n"));
MbufDiskInquire(CANDY_SAMPLE_IMAGE_FILE, M_SIZE_X, &SourceSizeX);
MbufDiskInquire(CANDY_SAMPLE_IMAGE_FILE, M_SIZE_Y, &SourceSizeY);
MbufAllocColor(MilSystem, 3, 2*SourceSizeX + DISPLAY_CENTER_MARGIN_X, SourceSizeY,
8+M_UNSIGNED, M_IMAGE+M_DISP+M_PROC, &DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
MbufChild2d(DisplayImage, 0, 0, SourceSizeX, SourceSizeY, &SourceChild);
MbufChild2d(DisplayImage, SourceSizeX + DISPLAY_CENTER_MARGIN_X, 0, \
SourceSizeX, SourceSizeY, &DestChild);
MbufLoad(CANDY_SAMPLE_IMAGE_FILE, SourceChild);
McolAlloc(MilSystem, M_COLOR_MATCHING, M_RGB, M_DEFAULT, M_DEFAULT, &MatchContext);
for(MIL_INT i=0; i<NUM_SAMPLES; i++)
{
McolDefine(MatchContext, SourceChild, M_SAMPLE_LABEL(i+1), M_IMAGE,
SamplesROI[i][0], SamplesROI[i][1], SampleSizeX, SampleSizeY);
}
McolSetMethod(MatchContext, MATCH_MODE, DISTANCE_TYPE, M_DEFAULT, M_DEFAULT);
McolControl(MatchContext, M_CONTEXT, M_DISTANCE_TOLERANCE_MODE, TOLERANCE_MODE);
McolControl(MatchContext, M_ALL, M_DISTANCE_TOLERANCE, TOLERANCE_VALUE);
McolControl(MatchContext, M_SAMPLE_INDEX(1), M_DISTANCE_TOLERANCE,
RED_TOLERANCE_VALUE);
McolControl(MatchContext, M_SAMPLE_INDEX(2), M_DISTANCE_TOLERANCE,
YELLOW_TOLERANCE_VALUE);
McolControl(MatchContext, M_SAMPLE_INDEX(5), M_DISTANCE_TOLERANCE,
PINK_TOLERANCE_VALUE);
McolPreprocess(MatchContext, M_DEFAULT);
for(MIL_INT i=0; i<NUM_SAMPLES; i++)
{
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_0 + M_TYPE_MIL_INT, &SampleMatchColor[i][0]);
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_1 + M_TYPE_MIL_INT, &SampleMatchColor[i][1]);
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_2 + M_TYPE_MIL_INT, &SampleMatchColor[i][2]);
}
DrawSampleColors(DestChild, SampleMatchColor, SampleNames, NUM_SAMPLES,
CANDY_SAMPLES_XSPACING, CANDY_SAMPLES_YOFFSET);
MdispSelect(MilDisplay, DisplayImage);
MosPrintf(MIL_TEXT("Color samples are defined for each possible candy color.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to do color matching.\n\n"));
MosGetch();
MbufClear(DisplayImage, M_COLOR_BLACK);
MbufLoad(CANDY_TARGET_IMAGE_FILE, SourceChild);
McolAllocResult(MilSystem, M_COLOR_MATCHING_RESULT, M_DEFAULT, &MatchResult);
McolControl(MatchContext, M_CONTEXT, M_GENERATE_PIXEL_MATCH, M_ENABLE);
McolControl(MatchContext, M_CONTEXT, M_GENERATE_SAMPLE_COLOR_LUT, M_ENABLE);
McolMatch(MatchContext, SourceChild, M_DEFAULT, M_NULL, MatchResult, M_DEFAULT);
MosPrintf(MIL_TEXT("Each pixel of the mixture is matched ")
MIL_TEXT("with one of the color samples.\n"));
MosPrintf(MIL_TEXT("\nColor segmentation results:\n"));
MosPrintf(MIL_TEXT("---------------------------\n"));
for(SampleIndex=0; SampleIndex<NUM_SAMPLES; SampleIndex++)
{
McolGetResult(MatchResult, M_DEFAULT, M_SAMPLE_INDEX(SampleIndex),
M_SCORE, &MatchScore);
SpacesIndex = 6 - MosStrlen(SampleNames[SampleIndex]);
MosPrintf(MIL_TEXT("Ratio of %s%s sample = %5.2f%%\n"), SampleNames[SampleIndex],
Spaces[SpacesIndex], MatchScore);
}
MosPrintf(MIL_TEXT("\nResults reveal the low proportion of Blue candy.\n"));
McolDraw(M_DEFAULT, MatchResult, DestChild, M_DRAW_PIXEL_MATCH_USING_COLOR,
M_ALL, M_ALL, M_DEFAULT);
MosPrintf(MIL_TEXT("\nPress <Enter> to end.\n\n"));
MosGetch();
MbufFree(DestChild);
MbufFree(SourceChild);
MbufFree(DisplayImage);
McolFree(MatchResult);
McolFree(MatchContext);
}
#define FUSE_SAMPLES_IMAGE M_IMAGE_PATH MIL_TEXT("FuseSamples.mim")
#define FUSE_TARGET_IMAGE M_IMAGE_PATH MIL_TEXT("Fuse.mim")
#define FINDER_CONTEXT M_IMAGE_PATH MIL_TEXT("FuseModel.mmf")
#define NUM_FUSES 4
#define FUSE_SAMPLES_XSPACING 40
#define FUSE_SAMPLES_YOFFSET 145
void ColorMatchingExample(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID DisplayImage = M_NULL,
SourceChild = M_NULL,
DestChild = M_NULL,
ColMatchContext = M_NULL,
ColMatchResult = M_NULL,
ModelImage = M_NULL,
AreaImage = M_NULL,
OverlayID = M_NULL,
OverlaySourceChild = M_NULL,
OverlayDestChild = M_NULL,
FuseFinderCtx = M_NULL,
FuseFinderRes = M_NULL;
MIL_INT SizeX, SizeY;
MIL_CONST_TEXT_PTR SampleNames[NUM_FUSES] =
{MIL_TEXT("Green"), MIL_TEXT(" Blue"), MIL_TEXT(" Red"), MIL_TEXT("Yellow")};
const MIL_INT SampleROIs[NUM_FUSES][4] = {{ 54, 139, 28, 14},
{172, 137, 30, 23},
{296, 135, 31, 23},
{417, 134, 27, 22}};
MIL_INT SampleMatchColor[NUM_FUSES][3];
MosPrintf(MIL_TEXT("\nCOLOR IDENTIFICATION:\n"));
MosPrintf( MIL_TEXT("---------------------\n"));
MbufDiskInquire(FUSE_TARGET_IMAGE, M_SIZE_X, &SizeX);
MbufDiskInquire(FUSE_TARGET_IMAGE, M_SIZE_Y, &SizeY);
MbufAllocColor(MilSystem,
3,
2*SizeX + DISPLAY_CENTER_MARGIN_X,
SizeY, 8+M_UNSIGNED,
M_IMAGE+M_DISP+M_PROC,
&DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &ModelImage);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &AreaImage);
MbufChild2d(DisplayImage, 0, 0, SizeX, SizeY, &SourceChild);
MbufChild2d(DisplayImage, SizeX + DISPLAY_CENTER_MARGIN_X, 0, SizeX, SizeY, &DestChild);
MbufLoad(FUSE_SAMPLES_IMAGE, SourceChild);
MdispSelect(MilDisplay, DisplayImage);
MdispControl(MilDisplay, M_OVERLAY, M_ENABLE);
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MdispInquire(MilDisplay, M_OVERLAY_ID, &OverlayID);
MbufChild2d(OverlayID, 0, 0, SizeX, SizeY, &OverlaySourceChild);
MbufChild2d(OverlayID, SizeX + DISPLAY_CENTER_MARGIN_X, 0,
SizeX, SizeY, &OverlayDestChild);
MmodRestore(FINDER_CONTEXT, MilSystem, M_DEFAULT, &FuseFinderCtx);
MmodPreprocess(FuseFinderCtx, M_DEFAULT);
MmodAllocResult(MilSystem, M_DEFAULT, &FuseFinderRes);
McolAlloc(MilSystem, M_COLOR_MATCHING, M_RGB, M_DEFAULT, M_DEFAULT, &ColMatchContext);
McolAllocResult(MilSystem, M_COLOR_MATCHING_RESULT, M_DEFAULT, &ColMatchResult);
for(MIL_INT i = 0; i < NUM_FUSES; i++)
{
McolDefine(ColMatchContext, SourceChild, M_SAMPLE_LABEL(i+1), M_IMAGE,
(MIL_DOUBLE)SampleROIs[i][0],
(MIL_DOUBLE)SampleROIs[i][1],
(MIL_DOUBLE)SampleROIs[i][2],
(MIL_DOUBLE)SampleROIs[i][3]);
}
McolPreprocess(ColMatchContext, M_DEFAULT);
for(MIL_INT i=0; i<NUM_FUSES; i++)
{
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_0 + M_TYPE_MIL_INT, &SampleMatchColor[i][0]);
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_1 + M_TYPE_MIL_INT, &SampleMatchColor[i][1]);
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_2 + M_TYPE_MIL_INT, &SampleMatchColor[i][2]);
}
DrawSampleColors(DestChild, SampleMatchColor, SampleNames,
NUM_FUSES, FUSE_SAMPLES_XSPACING, FUSE_SAMPLES_YOFFSET);
MgraColor(M_DEFAULT, M_COLOR_RED);
for(MIL_INT SampleIndex = 0; SampleIndex < NUM_FUSES; SampleIndex++)
{
MIL_INT XEnd = SampleROIs[SampleIndex][0] + SampleROIs[SampleIndex][2] - 1;
MIL_INT YEnd = SampleROIs[SampleIndex][1] + SampleROIs[SampleIndex][3] - 1;
MgraRect(M_DEFAULT, OverlaySourceChild, SampleROIs[SampleIndex][0],
SampleROIs[SampleIndex][1],
XEnd, YEnd);
}
MosPrintf(MIL_TEXT("Colors are defined using one color sample region per fuse.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to process the target image.\n"));
MosGetch();
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MdispControl(MilDisplay, M_UPDATE, M_DISABLE);
MbufLoad(FUSE_TARGET_IMAGE, SourceChild);
MimConvert(SourceChild, ModelImage, M_RGB_TO_L);
MbufCopy(ModelImage, DestChild);
MmodFind(FuseFinderCtx, ModelImage, FuseFinderRes);
MIL_INT Number=0;
MmodGetResult(FuseFinderRes, M_DEFAULT, M_NUMBER+M_TYPE_MIL_INT, &Number);
MbufClear(AreaImage, 0);
for(MIL_INT ii=0; ii<Number; ii++)
{
MIL_DOUBLE X, Y;
MmodGetResult(FuseFinderRes, ii, M_POSITION_X, &X);
MmodGetResult(FuseFinderRes, ii, M_POSITION_Y, &Y);
MgraColor(M_DEFAULT, (MIL_DOUBLE) ii+1);
MgraArcFill(M_DEFAULT, AreaImage, X, Y, 20, 20, 0, 360);
}
McolControl(ColMatchContext, M_CONTEXT, M_SAVE_AREA_IMAGE, M_ENABLE);
McolControl(ColMatchContext, M_CONTEXT, M_GENERATE_SAMPLE_COLOR_LUT, M_ENABLE);
McolMatch(ColMatchContext, SourceChild, M_DEFAULT, AreaImage, ColMatchResult, M_DEFAULT);
McolDraw(M_DEFAULT, ColMatchResult, OverlayDestChild,
M_DRAW_AREA_MATCH_USING_COLOR, M_ALL, M_ALL, M_DEFAULT);
MgraColor(M_DEFAULT, M_COLOR_BLUE);
MmodDraw(M_DEFAULT, FuseFinderRes, OverlayDestChild, M_DRAW_BOX+M_DRAW_POSITION,
M_ALL, M_DEFAULT);
MdispControl(MilDisplay, M_UPDATE, M_ENABLE);
MosPrintf(MIL_TEXT("\nFuses are located using the Model Finder tool.\n"));
MosPrintf(MIL_TEXT("The color of each target area is identified.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n"));
MosGetch();
MmodFree(FuseFinderRes);
MmodFree(FuseFinderCtx);
MbufFree(AreaImage);
MbufFree(ModelImage);
MbufFree(SourceChild);
MbufFree(DestChild);
MbufFree(OverlaySourceChild);
MbufFree(OverlayDestChild);
MbufFree(DisplayImage);
McolFree(ColMatchContext);
McolFree(ColMatchResult);
}
#define WRITING_IMAGE_FILE M_IMAGE_PATH MIL_TEXT("stamp.mim")
#define BACKGROUND_COLOR {245, 234, 206}
#define WRITING_COLOR {141, 174, 174}
#define STAMP_COLOR {226, 150, 118}
#define PATCHES_XSPACING 70
void ColorSeparationExample(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID DisplayImage = M_NULL,
SourceChild = M_NULL,
DestChild = M_NULL,
Child = M_NULL,
ColorsArray = M_NULL;
MIL_INT SourceSizeX, SourceSizeY;
MIL_CONST_TEXT_PTR ColorNames[3] =
{ MIL_TEXT("BACKGROUND"), MIL_TEXT("WRITING"), MIL_TEXT("STAMP") };
MIL_INT Colors[3][3] = { BACKGROUND_COLOR, WRITING_COLOR, STAMP_COLOR };
MIL_UINT8 BackgroundColor[3] = BACKGROUND_COLOR;
MIL_UINT8 SelectedColor[3] = WRITING_COLOR;
MIL_UINT8 RejectedColor[3] = STAMP_COLOR;
MosPrintf(MIL_TEXT("\nCOLOR SEPARATION:\n"));
MosPrintf( MIL_TEXT("-----------------\n"));
MbufAlloc2d(MilSystem, 3, 3, 8+M_UNSIGNED, M_ARRAY, &ColorsArray);
MbufPut2d(ColorsArray, 0, 0, 3, 1, BackgroundColor);
MbufPut2d(ColorsArray, 0, 1, 3, 1, SelectedColor);
MbufPut2d(ColorsArray, 0, 2, 3, 1, RejectedColor);
MbufDiskInquire(WRITING_IMAGE_FILE, M_SIZE_X, &SourceSizeX);
MbufDiskInquire(WRITING_IMAGE_FILE, M_SIZE_Y, &SourceSizeY);
MbufAllocColor(MilSystem,
3,
2*SourceSizeX + DISPLAY_CENTER_MARGIN_X,
SourceSizeY,
8+M_UNSIGNED,
M_IMAGE+M_DISP+M_PROC,
&DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MbufChild2d(DisplayImage, 0, 0, SourceSizeX, SourceSizeY, &SourceChild);
MbufChild2d(DisplayImage, SourceSizeX + DISPLAY_CENTER_MARGIN_X,
0, SourceSizeX, SourceSizeY, &DestChild);
MbufLoad(WRITING_IMAGE_FILE, SourceChild);
DrawSampleColors(DestChild, Colors, ColorNames, 3, PATCHES_XSPACING, -1);
MdispSelect(MilDisplay, DisplayImage);
MosPrintf(MIL_TEXT("The writing will be separated from the ")
MIL_TEXT("stamp using the following triplets:\n"));
MosPrintf(MIL_TEXT("the background color: beige [%d, %d, %d],\n"),
(int)BackgroundColor[0], (int)BackgroundColor[1], (int)BackgroundColor[2]);
MosPrintf(MIL_TEXT("the writing color : green [%d, %d, %d],\n"),
(int)SelectedColor[0], (int)SelectedColor[1], (int)SelectedColor[2]);
MosPrintf(MIL_TEXT("the stamp color : red [%d, %d, %d].\n\n"),
(int)RejectedColor[0], (int)RejectedColor[1], (int)RejectedColor[2]);
MosPrintf(MIL_TEXT("Press <Enter> to extract the writing.\n\n"));
MosGetch();
McolProject(SourceChild, ColorsArray, DestChild, M_NULL,
M_COLOR_SEPARATION, M_DEFAULT, M_NULL);
MosPrintf(MIL_TEXT("Press <Enter> to extract the stamp.\n\n"));
MosGetch();
MbufPut2d(ColorsArray, 0, 2, 3, 1, SelectedColor);
MbufPut2d(ColorsArray, 0, 1, 3, 1, RejectedColor);
McolProject(SourceChild, ColorsArray, DestChild, M_NULL,
M_COLOR_SEPARATION, M_DEFAULT, M_NULL);
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
MbufFree(ColorsArray);
MbufFree(SourceChild);
MbufFree(DestChild);
MbufFree(DisplayImage);
};
void DrawSampleColors(MIL_ID DestImage,
const MIL_INT pSamplesColors[][3],
MIL_CONST_TEXT_PTR *pSampleNames,
MIL_INT NumSamples,
MIL_INT XSpacing,
MIL_INT YOffset)
{
MIL_INT DestSizeX = MbufInquire(DestImage, M_SIZE_X, M_NULL);
MIL_INT DestSizeY = MbufInquire(DestImage, M_SIZE_Y, M_NULL);
MIL_DOUBLE OffsetX = (DestSizeX - (NumSamples * COLOR_PATCH_SIZEX) -
((NumSamples - 1) * XSpacing)) /2.0;
MIL_DOUBLE OffsetY = YOffset > 0 ? YOffset : (DestSizeY - COLOR_PATCH_SIZEY)/2.0;
MIL_DOUBLE TextOffsetX;
MgraFont(M_DEFAULT, M_FONT_DEFAULT_SMALL);
for(MIL_INT SampleIndex = 0; SampleIndex < NumSamples; SampleIndex++)
{
MgraColor(M_DEFAULT, M_RGB888(pSamplesColors[SampleIndex][0],
pSamplesColors[SampleIndex][1], pSamplesColors[SampleIndex][2]));
MgraRectFill(M_DEFAULT, DestImage, OffsetX, OffsetY, OffsetX + COLOR_PATCH_SIZEX,
OffsetY + COLOR_PATCH_SIZEY);
MgraColor(M_DEFAULT, M_COLOR_YELLOW);
TextOffsetX = OffsetX + COLOR_PATCH_SIZEX / 2.0 - 4.0 *
MosStrlen(pSampleNames[SampleIndex]) + 0.5;
MgraText(M_DEFAULT, DestImage, TextOffsetX, OffsetY-20, pSampleNames[SampleIndex]);
OffsetX += (COLOR_PATCH_SIZEX + XSpacing);
}
}