Mcol
This program uses the color module to perform color segmentation, color identification, color separation and color to grayscale conversion.
Language: C++
Functions used: MappAlloc, MappFree, MbufAlloc2d, MbufAllocColor, MbufChild2d, MbufChildColor2d, MbufClear, MbufCopy, MbufDiskInquire, MbufFree, MbufInquire, MbufLoad, MbufPut2d, McolAlloc, McolAllocResult, McolControl, McolDefine, McolDraw, McolFree, McolGetResult, McolInquire, McolMatch, McolPreprocess, McolProject, McolSetMethod, MdispAlloc, MdispControl, MdispFree, MdispInquire, MdispSelect, MgraArcFill, MgraFont, MgraRect, MgraRectFill, MgraText, MimConvert, MmodAllocResult, MmodDraw, MmodFind, MmodFree, MmodGetResult, MmodPreprocess, MmodRestore, MsysAlloc, MsysFree
Categories: Overview, General, Industries, Food and Beverage, Electronics, Packaging, Applications, Inspecting/Proofing/Verifying, Identifying, Finding/Locating, Modules, Buffer, Display, Graphics, Image Processing, Geometric Model Finder, Color Analysis, What's New, AIL 10.0 SP4, Older
///////////////////////////////////////////////////////////////////////////////
// Aurora Imaging Library
// Filename: MCol.cpp
//
// Description: This program contains 4 examples using the Color module.
//
// The first example performs color segmentation of an image
// by classifying each pixel with one out of 6 color samples.
// The ratio of each color in the image is then calculated.
//
// The second example performs color matching of circular regions
// in objects located with model finder.
//
// The third example performs color separation in order to
// separate 2 types of ink on a piece of paper.
//
// The fourth example performs a color to grayscale conversion
// using the principal component projection functionality.
//
// (C) 1992-2026 Zebra Technologies Corp. and/or its affiliates
// All Rights Reserved
///////////////////////////////////////////////////////////////////////////////
#include <AIL.h>
// Display image margin
#define DISPLAY_CENTER_MARGIN_X 5
#define DISPLAY_CENTER_MARGIN_Y 5
// Color patch sizes
#define COLOR_PATCH_SIZEX 30
#define COLOR_PATCH_SIZEY 40
// Example functions declarations.
void ColorSegmentationExample(AIL_ID AilSystem, AIL_ID AilDisplay);
void ColorMatchingExample(AIL_ID AilSystem, AIL_ID AilDisplay);
void ColorSeparationExample(AIL_ID AilSystem, AIL_ID AilDisplay);
void RGBtoGrayscaleExample(AIL_ID AilSystem, AIL_ID AilDisplay);
// Utility function
void DrawSampleColors(AIL_ID DestImage,
const AIL_INT pSamplesColors[][3],
AIL_CONST_TEXT_PTR *pSampleNames,
AIL_INT NumSamples,
AIL_INT XSpacing,
AIL_INT YOffset);
//*****************************************************************************
// Main.
//*****************************************************************************
int MosMain(void)
{
AIL_ID AilApplication, // Application identifier.
AilSystem, // System identifier.
AilDisplay; // Display identifier.
// Allocate defaults.
MappAllocDefault(M_DEFAULT, &AilApplication, &AilSystem, &AilDisplay, M_NULL, M_NULL);
// Run the color segmentation example.
ColorSegmentationExample(AilSystem, AilDisplay);
// Run the color matching example.
ColorMatchingExample(AilSystem, AilDisplay);
// Run the color projection example.
ColorSeparationExample(AilSystem, AilDisplay);
// Run the RGB to grayscale conversion example.
RGBtoGrayscaleExample(AilSystem, AilDisplay);
// Free defaults.
MappFreeDefault(AilApplication, AilSystem, AilDisplay, M_NULL, M_NULL);
return 0;
}
//****************************************************************************
// Color Segmentation using color samples.
//****************************************************************************
// Image filenames
#define CANDY_SAMPLE_IMAGE_FILE M_IMAGE_PATH AIL_TEXT("CandySamples.mim")
#define CANDY_TARGET_IMAGE_FILE M_IMAGE_PATH AIL_TEXT("Candy.mim")
// Number of samples
#define NUM_SAMPLES 6
// Draw spacing and offset
#define CANDY_SAMPLES_XSPACING 35
#define CANDY_SAMPLES_YOFFSET 145
// Match parameters
#define MATCH_MODE M_MIN_DIST_VOTE // Minimal distance vote mode.
#define DISTANCE_TYPE M_MAHALANOBIS // Mahalanobis distance.
#define TOLERANCE_MODE M_SAMPLE_STDDEV // Standard deviation tolerance mode.
#define TOLERANCE_VALUE 6.0 // Mahalanobis tolerance value.
#define RED_TOLERANCE_VALUE 6.0
#define YELLOW_TOLERANCE_VALUE 12.0
#define PINK_TOLERANCE_VALUE 5.0
void ColorSegmentationExample(AIL_ID AilSystem, AIL_ID AilDisplay)
{
AIL_ID SourceChild = M_NULL, // Source image buffer identifier.
DestChild = M_NULL, // Dest image buffer identifier.
MatchContext = M_NULL, // Color matching context identifier.
MatchResult = M_NULL, // Color matching result identifier.
DisplayImage = M_NULL; // Display image buffer identifier.
AIL_INT SourceSizeX, SourceSizeY, // Source image sizes.
SampleIndex, SpacesIndex; // Indices.
AIL_DOUBLE MatchScore; // Color matching score.
// Blank spaces to align the samples names evenly.
AIL_CONST_TEXT_PTR Spaces[4] = { AIL_TEXT(""),
AIL_TEXT(" "),
AIL_TEXT(" "),
AIL_TEXT(" ") };
// Color samples names.
AIL_CONST_TEXT_PTR SampleNames[NUM_SAMPLES] = { AIL_TEXT("Green"),
AIL_TEXT("Red"),
AIL_TEXT("Yellow"),
AIL_TEXT("Purple"),
AIL_TEXT("Blue"),
AIL_TEXT("Pink") };
// Color samples position: {OffsetX, OffsetY}
const AIL_DOUBLE SamplesROI[NUM_SAMPLES][2] = { { 58, 143},
{136, 148},
{217, 144},
{295, 142},
{367, 143},
{442, 147} };
// Color samples size.
const AIL_DOUBLE SampleSizeX = 36, SampleSizeY = 32;
// Array for match sample colors.
AIL_INT SampleMatchColor[NUM_SAMPLES][3];
MosPrintf(AIL_TEXT("\nCOLOR SEGMENTATION:\n"));
MosPrintf( AIL_TEXT("-------------------\n"));
// Allocate the parent display image.
MbufDiskInquire(CANDY_SAMPLE_IMAGE_FILE, M_SIZE_X, &SourceSizeX);
MbufDiskInquire(CANDY_SAMPLE_IMAGE_FILE, M_SIZE_Y, &SourceSizeY);
MbufAllocColor(AilSystem, 3, 2*SourceSizeX + DISPLAY_CENTER_MARGIN_X, SourceSizeY,
8+M_UNSIGNED, M_IMAGE+M_DISP+M_PROC, &DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
// Create a source and dest child in the display image.
MbufChild2d(DisplayImage, 0, 0, SourceSizeX, SourceSizeY, &SourceChild);
MbufChild2d(DisplayImage, SourceSizeX + DISPLAY_CENTER_MARGIN_X, 0,
SourceSizeX, SourceSizeY, &DestChild);
// Load the source image into the source child.
MbufLoad(CANDY_SAMPLE_IMAGE_FILE, SourceChild);
// Allocate a color matching context.
McolAlloc(AilSystem, M_COLOR_MATCHING, M_RGB, M_DEFAULT, M_DEFAULT, &MatchContext);
// Define each color sample in the context.
for(AIL_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);
}
// Set the color matching parameters.
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);
// Adjust tolerances for the red, yellow and pink samples.
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);
// Preprocess the context.
McolPreprocess(MatchContext, M_DEFAULT);
// Fill the samples colors array.
for(AIL_INT i=0; i<NUM_SAMPLES; i++)
{
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_0 + M_TYPE_AIL_INT, &SampleMatchColor[i][0]);
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_1 + M_TYPE_AIL_INT, &SampleMatchColor[i][1]);
McolInquire(MatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_2 + M_TYPE_AIL_INT, &SampleMatchColor[i][2]);
}
// Draw the samples.
DrawSampleColors(DestChild, SampleMatchColor, SampleNames, NUM_SAMPLES,
CANDY_SAMPLES_XSPACING, CANDY_SAMPLES_YOFFSET);
// Select the image buffer for display.
MdispSelect(AilDisplay, DisplayImage);
// Pause to show the original image.
MosPrintf(AIL_TEXT("Color samples are defined for each possible candy color.\n"));
MosPrintf(AIL_TEXT("Press any key to do color matching.\n\n"));
MosGetch();
// Load the target image.
MbufClear(DisplayImage, M_COLOR_BLACK);
MbufLoad(CANDY_TARGET_IMAGE_FILE, SourceChild);
// Allocate a color matching result buffer.
McolAllocResult(AilSystem, M_COLOR_MATCHING_RESULT, M_DEFAULT, &MatchResult);
// Enable controls to draw the labeled color image.
McolControl(MatchContext, M_CONTEXT, M_GENERATE_PIXEL_MATCH, M_ENABLE);
McolControl(MatchContext, M_CONTEXT, M_GENERATE_SAMPLE_COLOR_LUT, M_ENABLE);
// Match with target image.
McolMatch(MatchContext, SourceChild, M_DEFAULT, M_NULL, MatchResult, M_DEFAULT);
// Retrieve and display results.
MosPrintf(AIL_TEXT("Each pixel of the mixture is matched ")
AIL_TEXT("with one of the color samples.\n"));
MosPrintf(AIL_TEXT("\nColor segmentation results:\n"));
MosPrintf(AIL_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(AIL_TEXT("Ratio of %s%s sample = %5.2f%%\n"), SampleNames[SampleIndex],
Spaces[SpacesIndex], MatchScore);
}
MosPrintf(AIL_TEXT("\nResults reveal the low proportion of Blue candy.\n"));
// Draw the colored label image in the destination child.
McolDraw(M_DEFAULT, MatchResult, DestChild, M_DRAW_PIXEL_MATCH_USING_COLOR,
M_ALL, M_ALL, M_DEFAULT);
// Pause to show the result image.
MosPrintf(AIL_TEXT("\nPress any key to end.\n\n"));
MosGetch();
// Free all allocations.
MbufFree(DestChild);
MbufFree(SourceChild);
MbufFree(DisplayImage);
McolFree(MatchResult);
McolFree(MatchContext);
}
//*****************************************************************************
// Color matching in labeled regions.
//*****************************************************************************
// Image filenames
#define FUSE_SAMPLES_IMAGE M_IMAGE_PATH AIL_TEXT("FuseSamples.mim")
#define FUSE_TARGET_IMAGE M_IMAGE_PATH AIL_TEXT("Fuse.mim")
// Model Finder context filename
#define FINDER_CONTEXT M_IMAGE_PATH AIL_TEXT("FuseModel.mmf")
// Number of fuse sample objects
#define NUM_FUSES 4
// Draw spacing and offset
#define FUSE_SAMPLES_XSPACING 40
#define FUSE_SAMPLES_YOFFSET 145
void ColorMatchingExample(AIL_ID AilSystem, AIL_ID AilDisplay)
{
AIL_ID DisplayImage = M_NULL, // Display image buffer identifier.
SourceChild = M_NULL, // Source image buffer identifier.
DestChild = M_NULL, // Dest image buffer identifier.
ColMatchContext = M_NULL, // Color matching context identifier.
ColMatchResult = M_NULL, // Color matching result identifier.
ModelImage = M_NULL, // Model image buffer identifier.
AreaImage = M_NULL, // Area image buffer identifier.
OverlayID = M_NULL, // Overlay image buffer identifier.
OverlaySourceChild = M_NULL, // Overlay source child identifier.
OverlayDestChild = M_NULL, // Overlay dest child identifier.
FuseFinderCtx = M_NULL, // Model finder context identifier.
FuseFinderRes = M_NULL; // Model finder result identifier.
// Image sizes
AIL_INT SizeX, SizeY;
// Color sample names
AIL_CONST_TEXT_PTR SampleNames[NUM_FUSES] =
{AIL_TEXT("Green"), AIL_TEXT(" Blue"), AIL_TEXT(" Red"), AIL_TEXT("Yellow")};
// Sample ROIs coordinates: OffsetX, OffsetY, SizeX, SizeY
const AIL_INT SampleROIs[NUM_FUSES][4] = {{ 54, 139, 28, 14},
{172, 137, 30, 23},
{296, 135, 31, 23},
{417, 134, 27, 22}};
// Array of match sample colors.
AIL_INT SampleMatchColor[NUM_FUSES][3];
MosPrintf(AIL_TEXT("\nCOLOR IDENTIFICATION:\n"));
MosPrintf( AIL_TEXT("---------------------\n"));
// Allocate the parent display image.
MbufDiskInquire(FUSE_TARGET_IMAGE, M_SIZE_X, &SizeX);
MbufDiskInquire(FUSE_TARGET_IMAGE, M_SIZE_Y, &SizeY);
MbufAllocColor(AilSystem,
3,
2*SizeX + DISPLAY_CENTER_MARGIN_X,
SizeY, 8+M_UNSIGNED,
M_IMAGE+M_DISP+M_PROC,
&DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
// Allocate the model, area and label images.
MbufAlloc2d(AilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &ModelImage);
MbufAlloc2d(AilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &AreaImage);
// Create a source and destination child in the display image.
MbufChild2d(DisplayImage, 0, 0, SizeX, SizeY, &SourceChild);
MbufChild2d(DisplayImage, SizeX + DISPLAY_CENTER_MARGIN_X, 0, SizeX, SizeY, &DestChild);
// Load the sample source image.
MbufLoad(FUSE_SAMPLES_IMAGE, SourceChild);
// Display the image buffer.
MdispSelect(AilDisplay, DisplayImage);
// Prepare the overlay.
MdispControl(AilDisplay, M_OVERLAY, M_ENABLE);
MdispControl(AilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
MdispInquire(AilDisplay, M_OVERLAY_ID, &OverlayID);
MbufChild2d(OverlayID, 0, 0, SizeX, SizeY, &OverlaySourceChild);
MbufChild2d(OverlayID, SizeX + DISPLAY_CENTER_MARGIN_X, 0,
SizeX, SizeY, &OverlayDestChild);
// Prepare the model finder context and result.
MmodRestore(FINDER_CONTEXT, AilSystem, M_DEFAULT, &FuseFinderCtx);
MmodPreprocess(FuseFinderCtx, M_DEFAULT);
MmodAllocResult(AilSystem, M_DEFAULT, &FuseFinderRes);
// Allocate a color match context and result.
McolAlloc(AilSystem, M_COLOR_MATCHING, M_RGB, M_DEFAULT, M_DEFAULT, &ColMatchContext);
McolAllocResult(AilSystem, M_COLOR_MATCHING_RESULT, M_DEFAULT, &ColMatchResult);
// Define the color samples in the context.
for(AIL_INT i = 0; i < NUM_FUSES; i++)
{
McolDefine(ColMatchContext, SourceChild, M_SAMPLE_LABEL(i+1), M_IMAGE,
(AIL_DOUBLE)SampleROIs[i][0],
(AIL_DOUBLE)SampleROIs[i][1],
(AIL_DOUBLE)SampleROIs[i][2],
(AIL_DOUBLE)SampleROIs[i][3]);
}
// Preprocess the context.
McolPreprocess(ColMatchContext, M_DEFAULT);
// Fill the samples colors array.
for(AIL_INT i=0; i<NUM_FUSES; i++)
{
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_0 + M_TYPE_AIL_INT, &SampleMatchColor[i][0]);
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_1 + M_TYPE_AIL_INT, &SampleMatchColor[i][1]);
McolInquire(ColMatchContext, M_SAMPLE_LABEL(i+1),
M_MATCH_SAMPLE_COLOR_BAND_2 + M_TYPE_AIL_INT, &SampleMatchColor[i][2]);
}
// Draw the color samples.
DrawSampleColors(DestChild, SampleMatchColor, SampleNames,
NUM_FUSES, FUSE_SAMPLES_XSPACING, FUSE_SAMPLES_YOFFSET);
// Draw the sample ROIs in the source image overlay.
MgraControl(M_DEFAULT, M_COLOR, M_COLOR_RED);
for(AIL_INT SampleIndex = 0; SampleIndex < NUM_FUSES; SampleIndex++)
{
AIL_INT XEnd = SampleROIs[SampleIndex][0] + SampleROIs[SampleIndex][2] - 1;
AIL_INT YEnd = SampleROIs[SampleIndex][1] + SampleROIs[SampleIndex][3] - 1;
MgraRect(M_DEFAULT, OverlaySourceChild, SampleROIs[SampleIndex][0],
SampleROIs[SampleIndex][1],
XEnd, YEnd);
}
// Pause to show the source image.
MosPrintf(AIL_TEXT("Colors are defined using one color sample region per fuse.\n"));
MosPrintf(AIL_TEXT("Press any key to process the target image.\n"));
MosGetch();
// Clear the overlay.
MdispControl(AilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
// Disable the display update.
MdispControl(AilDisplay, M_UPDATE, M_DISABLE);
// Load the target image into the source child.
MbufLoad(FUSE_TARGET_IMAGE, SourceChild);
// Get the grayscale model image and copy it into the display dest child.
MimConvert(SourceChild, ModelImage, M_RGB_TO_L);
MbufCopy(ModelImage, DestChild);
// Find the Model.
MmodFind(FuseFinderCtx, ModelImage, FuseFinderRes);
// Draw the blob image: labeled circular areas centered at each found fuse occurrence.
AIL_INT Number=0;
MmodGetResult(FuseFinderRes, M_DEFAULT, M_NUMBER+M_TYPE_AIL_INT, &Number);
MbufClear(AreaImage, 0);
for(AIL_INT ii=0; ii<Number; ii++)
{
AIL_DOUBLE X, Y;
// Get the position
MmodGetResult(FuseFinderRes, ii, M_POSITION_X, &X);
MmodGetResult(FuseFinderRes, ii, M_POSITION_Y, &Y);
// Set the label color
MgraControl(M_DEFAULT, M_COLOR, (AIL_DOUBLE) ii+1);
// Draw the filled circle
MgraArcFill(M_DEFAULT, AreaImage, X, Y, 20, 20, 0, 360);
}
// Enable controls to draw the labeled color image.
McolControl(ColMatchContext, M_CONTEXT, M_SAVE_AREA_IMAGE, M_ENABLE);
McolControl(ColMatchContext, M_CONTEXT, M_GENERATE_SAMPLE_COLOR_LUT, M_ENABLE);
// Perform the color matching.
McolMatch(ColMatchContext, SourceChild, M_DEFAULT, AreaImage, ColMatchResult, M_DEFAULT);
// Draw the label image into the overlay child.
McolDraw(M_DEFAULT, ColMatchResult, OverlayDestChild,
M_DRAW_AREA_MATCH_USING_COLOR, M_ALL, M_ALL, M_DEFAULT);
// Draw the model position over the colored areas.
MgraControl(M_DEFAULT, M_COLOR, M_COLOR_BLUE);
MmodDraw(M_DEFAULT, FuseFinderRes, OverlayDestChild, M_DRAW_BOX+M_DRAW_POSITION,
M_ALL, M_DEFAULT);
// Enable the display update.
MdispControl(AilDisplay, M_UPDATE, M_ENABLE);
// Pause to show the resulting image.
MosPrintf(AIL_TEXT("\nFuses are located using the Model Finder tool.\n"));
MosPrintf(AIL_TEXT("The color of each target area is identified.\n"));
MosPrintf(AIL_TEXT("Press any key to end.\n\n"));
MosGetch();
// Free all allocations.
MmodFree(FuseFinderRes);
MmodFree(FuseFinderCtx);
MbufFree(AreaImage);
MbufFree(ModelImage);
MbufFree(SourceChild);
MbufFree(DestChild);
MbufFree(OverlaySourceChild);
MbufFree(OverlayDestChild);
MbufFree(DisplayImage);
McolFree(ColMatchContext);
McolFree(ColMatchResult);
}
//*****************************************************************************
// Perform color separation of colored inks on a piece of paper.
//*****************************************************************************
// Source image
#define WRITING_IMAGE_FILE M_IMAGE_PATH AIL_TEXT("stamp.mim")
// Color triplets
#define BACKGROUND_COLOR {245, 234, 206}
#define WRITING_COLOR {141, 174, 174}
#define STAMP_COLOR {226, 150, 118}
// Drawing spacing
#define PATCHES_XSPACING 70
void ColorSeparationExample(AIL_ID AilSystem, AIL_ID AilDisplay)
{
AIL_ID DisplayImage = M_NULL, // Display image buffer identifier.
SourceChild = M_NULL, // Source image buffer identifier.
DestChild = M_NULL, // Destination image buffer identifier.
Child = M_NULL, // Child buffer identifier.
ColorsArray = M_NULL; // Array buffer identifier.
// Source image sizes.
AIL_INT SourceSizeX, SourceSizeY;
// Color samples' names
AIL_CONST_TEXT_PTR ColorNames[3] =
{ AIL_TEXT("BACKGROUND"), AIL_TEXT("WRITING"), AIL_TEXT("STAMP") };
// Array with color patches to draw.
AIL_INT Colors[3][3] = { BACKGROUND_COLOR, WRITING_COLOR, STAMP_COLOR };
// Samples' color coordinates
AIL_UINT8 BackgroundColor[3] = BACKGROUND_COLOR;
AIL_UINT8 SelectedColor[3] = WRITING_COLOR;
AIL_UINT8 RejectedColor[3] = STAMP_COLOR;
MosPrintf(AIL_TEXT("\nCOLOR SEPARATION:\n"));
MosPrintf( AIL_TEXT("-----------------\n"));
// Allocate an array buffer and fill it with the color coordinates.
MbufAlloc2d(AilSystem, 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);
// Allocate the parent display image.
MbufDiskInquire(WRITING_IMAGE_FILE, M_SIZE_X, &SourceSizeX);
MbufDiskInquire(WRITING_IMAGE_FILE, M_SIZE_Y, &SourceSizeY);
MbufAllocColor(AilSystem,
3,
2*SourceSizeX + DISPLAY_CENTER_MARGIN_X,
SourceSizeY,
8+M_UNSIGNED,
M_IMAGE+M_DISP+M_PROC,
&DisplayImage);
MbufClear(DisplayImage, M_COLOR_BLACK);
// Clear the overlay.
MdispControl(AilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
// Create a source and dest child in the display image
MbufChild2d(DisplayImage, 0, 0, SourceSizeX, SourceSizeY, &SourceChild);
MbufChild2d(DisplayImage, SourceSizeX + DISPLAY_CENTER_MARGIN_X,
0, SourceSizeX, SourceSizeY, &DestChild);
// Load the source image into the display image source child.
MbufLoad(WRITING_IMAGE_FILE, SourceChild);
// Draw the color patches.
DrawSampleColors(DestChild, Colors, ColorNames, 3, PATCHES_XSPACING, -1);
// Display the image.
MdispSelect(AilDisplay, DisplayImage);
// Pause to show the source image and color patches.
MosPrintf(AIL_TEXT("The writing will be separated from the ")
AIL_TEXT("stamp using the following triplets:\n"));
MosPrintf(AIL_TEXT("the background color: beige [%d, %d, %d],\n"),
(int)BackgroundColor[0], (int)BackgroundColor[1], (int)BackgroundColor[2]);
MosPrintf(AIL_TEXT("the writing color : green [%d, %d, %d],\n"),
(int)SelectedColor[0], (int)SelectedColor[1], (int)SelectedColor[2]);
MosPrintf(AIL_TEXT("the stamp color : red [%d, %d, %d].\n\n"),
(int)RejectedColor[0], (int)RejectedColor[1], (int)RejectedColor[2]);
MosPrintf(AIL_TEXT("Press any key to extract the writing.\n\n"));
MosGetch();
// Perform the color projection.
McolProject(SourceChild, ColorsArray, DestChild, M_NULL,
M_COLOR_SEPARATION, M_DEFAULT, M_NULL);
// Wait for a key.
MosPrintf(AIL_TEXT("Press any key to extract the stamp.\n\n"));
MosGetch();
// Switch the order of the selected vs rejected colors in the color array.
MbufPut2d(ColorsArray, 0, 2, 3, 1, SelectedColor);
MbufPut2d(ColorsArray, 0, 1, 3, 1, RejectedColor);
// Perform the color projection.
McolProject(SourceChild, ColorsArray, DestChild, M_NULL,
M_COLOR_SEPARATION, M_DEFAULT, M_NULL);
// Wait for a key.
MosPrintf(AIL_TEXT("Press any key to end.\n\n"));
MosGetch();
// Free all allocations.
MbufFree(ColorsArray);
MbufFree(SourceChild);
MbufFree(DestChild);
MbufFree(DisplayImage);
};
//*****************************************************************************
// Perform RGB to grayscale conversion
//*****************************************************************************
// Source image
#define RGB_IMAGE_FILE M_IMAGE_PATH AIL_TEXT("BinderClip.mim")
void RGBtoGrayscaleExample(AIL_ID AilSystem, AIL_ID AilDisplay)
{
MosPrintf(AIL_TEXT("\nCONVERSION FROM RGB TO GRAYSCALE:\n"));
MosPrintf(AIL_TEXT("---------------------------------\n"));
MosPrintf(AIL_TEXT("The example compares principal component projection to "));
MosPrintf(AIL_TEXT("luminance based\nconversion.\n\n"));
AIL_ID DisplayImage = M_NULL, // Display image buffer identifier.
SourceChild = M_NULL, // Source image child buffer identifier.
LuminanceChild = M_NULL, // Luminance image child buffer identifier.
PCPchild = M_NULL, // PCP image child buffer identifier.
LuminanceResult = M_NULL, // Luminance result identifier.
PCPresult = M_NULL, // PCP result identifier.
Mask = M_NULL, // Mask identifier to perform PCP.
ChildMask = M_NULL; // Child mask identifier to perform PCP.
// Inquire size and type of the source image.
AIL_INT SourceSizeX = MbufDiskInquire(RGB_IMAGE_FILE, M_SIZE_X, M_NULL);
AIL_INT SourceSizeY = MbufDiskInquire(RGB_IMAGE_FILE, M_SIZE_Y, M_NULL);
AIL_INT Type = MbufDiskInquire(RGB_IMAGE_FILE, M_TYPE, M_NULL);
// Allocate buffer to display the input image and the results.
MbufAllocColor(AilSystem, 3, SourceSizeX, 3 * SourceSizeY + 2 * DISPLAY_CENTER_MARGIN_Y,
Type, M_IMAGE + M_PROC + M_DISP, &DisplayImage);
MbufClear(DisplayImage, 0);
// Create a source child in the display image.
MbufChildColor2d(DisplayImage, M_ALL_BANDS, 0, 0, SourceSizeX, SourceSizeY, &SourceChild);
// Create a destination child in the display image for luminance based conversion.
MbufChildColor2d(DisplayImage, M_ALL_BANDS, 0, SourceSizeY + DISPLAY_CENTER_MARGIN_Y,
SourceSizeX, SourceSizeY, &LuminanceChild);
// Create a destination child in the display image for principal component projection.
MbufChildColor2d(DisplayImage, M_ALL_BANDS, 0, 2 * SourceSizeY + 2 * DISPLAY_CENTER_MARGIN_Y,
SourceSizeX, SourceSizeY, &PCPchild);
// Load the source image into the display image source child.
MbufLoad(RGB_IMAGE_FILE, SourceChild);
MdispSelect(AilDisplay, DisplayImage);
// Extract luminance channel from source image and copy the result in the display image.
MbufAlloc2d(AilSystem, SourceSizeX, SourceSizeY, Type, M_IMAGE + M_PROC, &LuminanceResult);
MimConvert(SourceChild, LuminanceResult, M_RGB_TO_L);
MbufCopy(LuminanceResult, LuminanceChild);
MosPrintf(AIL_TEXT("Color image converted to grayscale using luminance based ")
AIL_TEXT("conversion\ntechnique.\n\n"));
MosPrintf(AIL_TEXT("Press any key to convert the image using principal ")
AIL_TEXT("component projection\ntechnique.\n\n"));
MosGetch();
// Create a mask to identify important colors in the source image.
MbufAlloc2d(M_DEFAULT_HOST, SourceSizeX, SourceSizeY, 8 + M_UNSIGNED, M_IMAGE + M_PROC,
&Mask);
MbufClear(Mask, 0);
// Define regions of interest (pixel colors with which to perform the color projection).
AIL_INT OffsetX = 105,
OffsetY = 45,
MaskSizeX = 60,
MaskSizeY = 20;
MbufChild2d(Mask, OffsetX, OffsetY, MaskSizeX, MaskSizeY, &ChildMask);
MbufClear(ChildMask, M_SOURCE_LABEL);
MbufFree(ChildMask);
OffsetX = 220,
MbufChild2d(Mask, OffsetX, OffsetY, MaskSizeX, MaskSizeY, &ChildMask);
MbufClear(ChildMask, M_SOURCE_LABEL);
MbufFree(ChildMask);
OffsetX = 335,
MbufChild2d(Mask, OffsetX, OffsetY, MaskSizeX, MaskSizeY, &ChildMask);
MbufClear(ChildMask, M_SOURCE_LABEL);
// Perform principal component projection and copy the result in the display image.
MbufAlloc2d(AilSystem, SourceSizeX, SourceSizeY, Type, M_IMAGE + M_PROC, &PCPresult);
McolProject(SourceChild, Mask, PCPresult, M_NULL,
M_PRINCIPAL_COMPONENT_PROJECTION, M_DEFAULT, M_NULL);
MbufCopy(PCPresult, PCPchild);
MosPrintf(AIL_TEXT("Color image converted to grayscale using principal ")
AIL_TEXT("component projection\ntechnique.\n"));
MosPrintf(AIL_TEXT("Press any key to end.\n\n"));
MosGetch();
// Free all allocations.
MbufFree(ChildMask);
MbufFree(Mask);
MbufFree(PCPresult);
MbufFree(LuminanceResult);
MbufFree(PCPchild);
MbufFree(LuminanceChild);
MbufFree(SourceChild);
MbufFree(DisplayImage);
}
//***************************************************************************
// Draw the samples as color patches.
void DrawSampleColors(AIL_ID DestImage,
const AIL_INT pSamplesColors[][3],
AIL_CONST_TEXT_PTR *pSampleNames,
AIL_INT NumSamples,
AIL_INT XSpacing,
AIL_INT YOffset)
{
AIL_INT DestSizeX = MbufInquire(DestImage, M_SIZE_X, M_NULL);
AIL_INT DestSizeY = MbufInquire(DestImage, M_SIZE_Y, M_NULL);
AIL_DOUBLE OffsetX = (DestSizeX - (NumSamples * COLOR_PATCH_SIZEX) -
((NumSamples - 1) * XSpacing)) /2.0;
AIL_DOUBLE OffsetY = YOffset > 0 ? YOffset : (DestSizeY - COLOR_PATCH_SIZEY)/2.0;
AIL_DOUBLE TextOffsetX;
MgraFont(M_DEFAULT, M_FONT_DEFAULT_SMALL);
for(AIL_INT SampleIndex = 0; SampleIndex < NumSamples; SampleIndex++)
{
MgraControl(M_DEFAULT, M_COLOR, 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);
MgraControl(M_DEFAULT, M_COLOR, 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);
}
}