Click here to show toolbars of the Web Online Help System: show toolbars |
//*************************************************************************************** // // File name: defectdetectionexample.cpp // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: This file contains the implementation of the CDefectDetectionExamplMngr class // that handles all the aspects of the defect detection example except the // processing part. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved #include <mil.h> #include "defectdetectionprocfunc.h" #include "defectdetectionexample.h" //***************************************************************************** // Constants. //***************************************************************************** static const MIL_INT WINDOW_TITLE_HEIGHT = 60; static const MIL_INT IMAGE_SEPARATION_X = 30; static const MIL_INT TARGET_IMAGE_SEPARATION_Y = 30; static const MIL_DOUBLE MODEL_OFFSET_X = M_DEFAULT; static const MIL_DOUBLE MODEL_OFFSET_Y = M_DEFAULT; static const MIL_DOUBLE MODEL_SIZE_X = M_DEFAULT; static const MIL_DOUBLE MODEL_SIZE_Y = M_DEFAULT; static const MIL_INT HIST_BORDER = WINDOW_TITLE_HEIGHT; static const MIL_INT DEFECT_SIZE = 5; static const MIL_INT CLEAN_MORPH_SIZE = 1; static const MIL_DOUBLE GRADIENT_MASK_SMOOTHNESS = 50; static const MIL_DOUBLE TRIANGLE_LOWER_CUTOFF = 2; static const MIL_DOUBLE TRIANGLE_UPPER_CUTOFF = 255; static const MIL_DOUBLE BIN_CUMULATIVE_VALUE = 95.0; static const MIL_DOUBLE FIXED_DIFF_THRESHOLD = 10; static const MIL_DOUBLE NORMAL_VARIATIONS = 20; //***************************************************************************** // Constructor. Allocates MIL application, system and display. //***************************************************************************** CDefectDetectionExampleMngr::CDefectDetectionExampleMngr(MIL_CONST_TEXT_PTR SystemDescriptor) : m_MilApplication (M_NULL), m_MilSystem (M_NULL), m_MilDisplay (M_NULL), m_MilDisplayImage (M_NULL), m_MilGraList (M_NULL), m_MilGraContextTemplate (M_NULL), m_MilGraContextTarget (M_NULL), m_MilGraContextWarpedTarget (M_NULL), m_MilGraContextDifference (M_NULL), m_MilGraContextInspection (M_NULL), m_MilHistDisplay (M_NULL), m_MilHistDisplayImage (M_NULL), m_MilHistDispGraphicList (M_NULL), m_MilHistResult (M_NULL), m_MilDispTemplateImage (M_NULL), m_MilTemplateImage (M_NULL), m_MilTargetImage (M_NULL), m_MilWarpedTargetImage (M_NULL), m_MilDifferenceImage (M_NULL), m_MilInspectionImage (M_NULL), m_MilTemplateGradientMask (M_NULL), m_MilTemplateLumImage (M_NULL), m_MilTargetLumImage (M_NULL), m_MilDifferenceGrayImage (M_NULL), m_MilStructElement (M_NULL), m_MilModContext (M_NULL), m_MilModResult (M_NULL), m_MilBlobResult (M_NULL), m_BlobDrawLabel (M_NULL), m_MilBlobContext (M_NULL), m_MilFixturingOffset (M_NULL), m_TemplateSizeX (0), m_TemplateSizeY (0), m_DiffMethod (enAbsoluteDiff), m_BinMethod (enBiModal), m_OverlayTransparentColor (0), m_IsInteractive (false), m_ImageSpacing (IMAGE_SEPARATION_X), m_ModOccDrawStartIndex (0) { // Allocate application. MappAlloc(M_NULL, M_DEFAULT, &m_MilApplication); // Allocate system (SystemDescriptor depends on subclass). MsysAlloc(M_DEFAULT, SystemDescriptor, M_DEFAULT, M_DEFAULT, &m_MilSystem); // Allocate display. Set it to auto scale. MdispAlloc(m_MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &m_MilDisplay); MdispControl(m_MilDisplay, M_SCALE_DISPLAY, M_ENABLE); // Allocate a graphic list and associate it with the display. MgraAllocList(m_MilSystem, M_DEFAULT, &m_MilGraList); MdispControl(m_MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, m_MilGraList); // Allocate the histogram displays. MdispAlloc(m_MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &m_MilHistDisplay); // Allocate the histogram display graphic list and image and initialize the histogram. MbufAlloc2d(m_MilSystem, 256 + 2*HIST_BORDER, 256 + 2*HIST_BORDER, 8+M_UNSIGNED, M_IMAGE+M_DISP, &m_MilHistDisplayImage); MbufClear(m_MilHistDisplayImage, 0); MgraAllocList(m_MilSystem, M_DEFAULT, &m_MilHistDispGraphicList); InitHistogram(); // Associate the graphic list to the display. MdispControl(m_MilHistDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, m_MilHistDispGraphicList); // Allocate an histogram result buffer. MimAllocResult(m_MilSystem, 256, M_HIST_LIST, &m_MilHistResult); // Allocate structuring element. MbufAlloc2d(m_MilSystem, DEFECT_SIZE + 1, DEFECT_SIZE + 1, 32+M_UNSIGNED, M_STRUCT_ELEMENT, &m_MilStructElement); MbufClear(m_MilStructElement, 0); // Allocate Model Finder. MmodAlloc(m_MilSystem, M_GEOMETRIC, M_DEFAULT, &m_MilModContext); MmodAllocResult(m_MilSystem, M_DEFAULT, &m_MilModResult); // Allocate Blob. MblobAllocResult(m_MilSystem, M_DEFAULT, M_DEFAULT, &m_MilBlobResult); MblobAlloc(m_MilSystem, M_DEFAULT, M_DEFAULT, &m_MilBlobContext);; // Allocate a calibration fixture. McalAlloc(m_MilSystem, M_FIXTURING_OFFSET, M_DEFAULT, &m_MilFixturingOffset); } //***************************************************************************** // Destructor, free all MIL objects. //***************************************************************************** CDefectDetectionExampleMngr::~CDefectDetectionExampleMngr() { // Free the display images. FreeDisplayImages(); // Free the work images. FreeWorkImages(); // Free the structuring element. if(m_MilStructElement != M_NULL) MbufFree(m_MilStructElement); // Free Model Finder. if(m_MilModContext != M_NULL) { MmodFree(m_MilModContext); MmodFree(m_MilModResult); } // Free Blob. if(m_MilBlobResult != M_NULL) { MblobFree(m_MilBlobResult); MblobFree(m_MilBlobContext); } // Free the calibration fixture. if(m_MilFixturingOffset != M_NULL) McalFree(m_MilFixturingOffset); // Free the histogram. if(m_MilHistResult) MimFree(m_MilHistResult); // Free the histogram graphic list if(m_MilHistDispGraphicList != M_NULL) MgraFree(m_MilHistDispGraphicList); // Free the graphic list. if(m_MilGraList != M_NULL) MgraFree(m_MilGraList); //Free the histogram display selected image if(m_MilHistDisplayImage != M_NULL) MbufFree(m_MilHistDisplayImage); // Free the histogram display. if(m_MilHistDisplay != M_NULL) MdispFree(m_MilHistDisplay); // Free the display. if (m_MilDisplay != M_NULL) MdispFree(m_MilDisplay); // Free the system. if (m_MilSystem != M_NULL) MsysFree(m_MilSystem); // Free the application. if (m_MilApplication != M_NULL) MappFree(m_MilApplication); } //***************************************************************************** // Free the display associated images. //***************************************************************************** void CDefectDetectionExampleMngr::FreeDisplayImages() { if (m_MilDisplayImage != M_NULL) { MbufFree(m_MilDispTemplateImage); MbufFree(m_MilTargetImage); MbufFree(m_MilWarpedTargetImage); MbufFree(m_MilDifferenceImage); MbufFree(m_MilInspectionImage); MbufFree(m_MilTargetLumImage); MgraFree(m_MilGraContextTemplate); MgraFree(m_MilGraContextTarget); MgraFree(m_MilGraContextWarpedTarget); MgraFree(m_MilGraContextDifference); MgraFree(m_MilGraContextInspection); MbufFree(m_MilDisplayImage); } } //***************************************************************************** // Free the work images. //***************************************************************************** void CDefectDetectionExampleMngr::FreeWorkImages() { if (m_MilTemplateGradientMask != M_NULL) { MbufFree(m_MilTemplateGradientMask); MbufFree(m_MilTemplateLumGradientMask); MbufFree(m_MilTemplateLumImage); MbufFree(m_MilDifferenceGrayImage); MbufFree(m_MilTemplateImage); } } //***************************************************************************** // Load the template. Load the image, create a luminance version and defines // a model. //***************************************************************************** bool CDefectDetectionExampleMngr::LoadTemplate(MIL_CONST_TEXT_PTR TemplateImagePath) { bool LoadStatus = false; // Free the work images. FreeWorkImages(); if(TemplateImagePath == M_INTERACTIVE) MosPrintf(MIL_TEXT("Please choose a template image.\n\n")); // Restore the template user image. MappControl(M_ERROR, M_PRINT_DISABLE); MIL_ID MilUserTemplate = MbufRestore(TemplateImagePath, m_MilSystem, M_NULL); MappControl(M_ERROR, M_PRINT_ENABLE); if(MilUserTemplate != M_NULL) { // Get the size of the user template. MbufInquire(MilUserTemplate, M_SIZE_X, &m_TemplateSizeX); MbufInquire(MilUserTemplate, M_SIZE_Y, &m_TemplateSizeY); if (m_TemplateSizeX >= 16 && m_TemplateSizeX <= 1024 && m_TemplateSizeY >= 16 && m_TemplateSizeY <= 1024) { // Allocate the color template image and copy the user image. MbufAllocColor(m_MilSystem, 3, m_TemplateSizeX, m_TemplateSizeY, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &m_MilTemplateImage); MbufCopy(MilUserTemplate, m_MilTemplateImage); // Allocate the work images. MbufAlloc2d(m_MilSystem, m_TemplateSizeX, m_TemplateSizeY, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &m_MilDifferenceGrayImage); // Create the luminance version of the template. CreateLuminanceImage(m_MilTemplateImage, m_TemplateSizeX, m_TemplateSizeY, &m_MilTemplateLumImage); // Create the gradient mask. CreateGradientMaskImage(m_MilTemplateImage, m_MilTemplateLumImage, GRADIENT_MASK_SMOOTHNESS, &m_MilTemplateGradientMask, &m_MilTemplateLumGradientMask); // Define the model from the template image. LoadStatus = DefineModelAndFixture(m_MilTemplateLumImage, m_MilModContext, m_MilFixturingOffset, MODEL_OFFSET_X, MODEL_OFFSET_Y, MODEL_SIZE_X, MODEL_SIZE_Y); } else { MosPrintf(MIL_TEXT("Unable to create model from the template image.\n") MIL_TEXT("The template image sizes must be between 16 and 1024.\n\n")); } // Free the user template. MbufFree(MilUserTemplate); } else MosPrintf(MIL_TEXT("Unable to load template image.\n\n")); return LoadStatus; } //***************************************************************************** // Initialize the example with the target image. Sets the display, creates a // luminance image of the target and calibrates the warped target with a uniform // calibration. //***************************************************************************** bool CDefectDetectionExampleMngr::InitializeExample(MIL_CONST_TEXT_PTR TargetImagePath, DifferenceExtractionMethod DiffMethod, BinarizationMethod BinMethod) { // Initialize the methods use. m_DiffMethod = DiffMethod; m_BinMethod = BinMethod; if(TargetImagePath == M_INTERACTIVE) MosPrintf(MIL_TEXT("Please choose a target image.\n\n")); // Restore the target user image. MappControl(M_ERROR, M_PRINT_DISABLE); MIL_ID MilUserTarget = MbufRestore(TargetImagePath, m_MilSystem, M_NULL); MappControl(M_ERROR, M_PRINT_ENABLE); if(MilUserTarget != M_NULL) { // Get the size of the user target. MIL_INT TargetSizeX = MbufInquire(MilUserTarget, M_SIZE_X, M_NULL); MIL_INT TargetSizeY = MbufInquire(MilUserTarget, M_SIZE_Y, M_NULL); // Reset the display. ResetDisplay(TargetSizeX, TargetSizeY); // Copy the template image in the display. MbufCopy(m_MilTemplateImage, m_MilDispTemplateImage); // Copy the target image. MbufCopy(MilUserTarget, m_MilTargetImage); // Free the user target. MbufFree(MilUserTarget); // Create the luminance version of the target. Free it if it was allocated. CreateLuminanceImage(m_MilTargetImage, TargetSizeX, TargetSizeY, &m_MilTargetLumImage); // Associate a uniform calibration to the warped target image. McalUniform(m_MilWarpedTargetImage, 0, 0, 1, 1, 0, M_DEFAULT); // Show the template coordinate and model information. ShowTargetAndTemplate(TargetImagePath); return true; } else { // Print error message. MosPrintf(MIL_TEXT("Unable to load target image.\n\n")); return false; } } //***************************************************************************** // Main running function of the example. //***************************************************************************** void CDefectDetectionExampleMngr::Run(MIL_CONST_TEXT_PTR CaseInformationText) { // 1. Get the number of occurrences. m_NbOccurences = FindModel(m_MilModContext, m_MilTargetLumImage, m_MilModResult); if(m_NbOccurences > 0) { // Show the occurrences found in the display. ShowAllOccurrences(); for(MIL_INT OccurrenceIdx = 0; OccurrenceIdx < m_NbOccurences; OccurrenceIdx++) { // Clear the inspection image and of the difference image. ClearDefectDetection(); // 2. Align the target on the template based on the Model Finder result AlignImageBasedOnFixture(m_MilTargetImage, m_MilWarpedTargetImage, m_MilFixturingOffset, m_MilModResult, M_RESULT_MOD, OccurrenceIdx); // Show the warped occurrence in the target display. ShowWarpedOccurrence(OccurrenceIdx); // Set the initial methods. DifferenceExtractionMethod DiffMethod = m_DiffMethod; BinarizationMethod BinMethod = m_BinMethod; // Print the case information MosPrintf(MIL_TEXT("%s\n\n"), CaseInformationText); m_ChangeDiff = true; m_ChangeBin = true; do { // Update the extracted differences if necessary. if(m_ChangeDiff) { // 3. Extract the differences. ExtractDifferences(m_MilTemplateImage, m_MilTemplateLumImage, m_MilTemplateGradientMask, m_MilTemplateLumGradientMask, m_MilWarpedTargetImage, m_MilDifferenceGrayImage, m_MilStructElement, DiffMethod); // Update the binarization if we have changed the difference image. m_ChangeBin = true; } // Update the binarization if necessary. if(m_ChangeBin) { // 4. Extract the defects. m_BinValue = ExtractDefects(m_MilDifferenceGrayImage, m_MilBlobResult, m_MilBlobContext, TRIANGLE_LOWER_CUTOFF, TRIANGLE_UPPER_CUTOFF, BIN_CUMULATIVE_VALUE, NORMAL_VARIATIONS, FIXED_DIFF_THRESHOLD, CLEAN_MORPH_SIZE, BinMethod); } // Show the defect detection. ShowDefectDetection(); // Show the histogram. ShowHistogram(); m_ChangeBin = false; m_ChangeDiff = false; }while(AskForMethod(DiffMethod, BinMethod)); //Remove the histogram MdispSelect(m_MilHistDisplay, M_NULL); } } else { MosPrintf(MIL_TEXT("No occurrence of the model were found in the target image\n") MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } } //***************************************************************************** // Resets the display. //***************************************************************************** void CDefectDetectionExampleMngr::ResetDisplay(MIL_INT TargetSizeX, MIL_INT TargetSizeY) { // Compute the offsets and sizes of the different childs. MIL_INT InspectionChildOffsetX = 4 * IMAGE_SEPARATION_X + 3* m_TemplateSizeX; MIL_INT DispSizeX, TargetChildOffsetX; if(InspectionChildOffsetX + m_TemplateSizeX > TargetSizeX + IMAGE_SEPARATION_X) { DispSizeX = InspectionChildOffsetX + m_TemplateSizeX + IMAGE_SEPARATION_X; TargetChildOffsetX = (DispSizeX - TargetSizeX)/2; m_ImageSpacing = IMAGE_SEPARATION_X; } else { DispSizeX = TargetSizeX + 2 * IMAGE_SEPARATION_X; TargetChildOffsetX = IMAGE_SEPARATION_X; m_ImageSpacing = (DispSizeX - 4 * m_TemplateSizeX)/5; } MIL_INT WarpedChildOffsetX = 2 * m_ImageSpacing + m_TemplateSizeX; MIL_INT DifferenceChildOffsetX = WarpedChildOffsetX + m_ImageSpacing + m_TemplateSizeX; InspectionChildOffsetX = DifferenceChildOffsetX + m_ImageSpacing + m_TemplateSizeX; MIL_INT TargetChildOffsetY = 3 * WINDOW_TITLE_HEIGHT + m_TemplateSizeY + TARGET_IMAGE_SEPARATION_Y; MIL_INT DispSizeY = TargetChildOffsetY + TargetSizeY + IMAGE_SEPARATION_X; // Free the displayed images. FreeDisplayImages(); // Clear the graphic list. MgraClear(M_DEFAULT, m_MilGraList); // Allocate the display image. MbufAllocColor(m_MilSystem, 3, DispSizeX, DispSizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC+M_DISP, &m_MilDisplayImage); // Allocate the works images that are childs of the display. MbufChild2d(m_MilDisplayImage, m_ImageSpacing, WINDOW_TITLE_HEIGHT, m_TemplateSizeX, m_TemplateSizeY, &m_MilDispTemplateImage); MbufChild2d(m_MilDisplayImage, TargetChildOffsetX, TargetChildOffsetY, TargetSizeX, TargetSizeY, &m_MilTargetImage); MbufChild2d(m_MilDisplayImage, WarpedChildOffsetX, WINDOW_TITLE_HEIGHT, m_TemplateSizeX, m_TemplateSizeY, &m_MilWarpedTargetImage); MbufChild2d(m_MilDisplayImage, DifferenceChildOffsetX, WINDOW_TITLE_HEIGHT, m_TemplateSizeX, m_TemplateSizeY, &m_MilDifferenceImage); MbufChild2d(m_MilDisplayImage, InspectionChildOffsetX, WINDOW_TITLE_HEIGHT, m_TemplateSizeX, m_TemplateSizeY, &m_MilInspectionImage); // Clear the displayed image. MbufClear(m_MilDisplayImage, 0); // Select the image on the display. MdispSelect(m_MilDisplay, m_MilDisplayImage); // Allocate the graphic contexts of the childs of the overlay. MgraAlloc(m_MilSystem, &m_MilGraContextTemplate); MgraControl(m_MilGraContextTemplate, M_DRAW_OFFSET_X, - (MIL_DOUBLE)m_ImageSpacing); MgraControl(m_MilGraContextTemplate, M_DRAW_OFFSET_Y, - WINDOW_TITLE_HEIGHT); MgraAlloc(m_MilSystem, &m_MilGraContextTarget); MgraControl(m_MilGraContextTarget, M_DRAW_OFFSET_X, - (MIL_DOUBLE)TargetChildOffsetX); MgraControl(m_MilGraContextTarget, M_DRAW_OFFSET_Y, - (MIL_DOUBLE)TargetChildOffsetY); MgraAlloc(m_MilSystem, &m_MilGraContextWarpedTarget); MgraControl(m_MilGraContextWarpedTarget, M_DRAW_OFFSET_X, - (MIL_DOUBLE)WarpedChildOffsetX); MgraControl(m_MilGraContextWarpedTarget, M_DRAW_OFFSET_Y, - WINDOW_TITLE_HEIGHT); MgraAlloc(m_MilSystem, &m_MilGraContextDifference); MgraControl(m_MilGraContextDifference, M_DRAW_OFFSET_X, - (MIL_DOUBLE)DifferenceChildOffsetX); MgraControl(m_MilGraContextDifference, M_DRAW_OFFSET_Y, - WINDOW_TITLE_HEIGHT); MgraAlloc(m_MilSystem, &m_MilGraContextInspection); MgraControl(m_MilGraContextInspection, M_DRAW_OFFSET_X, - (MIL_DOUBLE)InspectionChildOffsetX); MgraControl(m_MilGraContextInspection, M_DRAW_OFFSET_Y, - WINDOW_TITLE_HEIGHT); // Draw the display childs info. DrawDisplayChildInfo(m_MilGraContextTemplate , m_TemplateSizeX, m_TemplateSizeY, MIL_TEXT("Template Image")); DrawDisplayChildInfo(m_MilGraContextTarget , TargetSizeX , TargetSizeY , MIL_TEXT("Target Image")); DrawDisplayChildInfo(m_MilGraContextWarpedTarget, m_TemplateSizeX, m_TemplateSizeY, MIL_TEXT("Warped Target")); DrawDisplayChildInfo(m_MilGraContextDifference , m_TemplateSizeX, m_TemplateSizeY, MIL_TEXT("Difference Image")); DrawDisplayChildInfo(m_MilGraContextInspection , m_TemplateSizeX, m_TemplateSizeY, MIL_TEXT("Inspection Image")); } //***************************************************************************** // Draw display child info. //***************************************************************************** void CDefectDetectionExampleMngr::DrawDisplayChildInfo(MIL_ID MilGraContext, MIL_INT ImageSizeX, MIL_INT ImageSizeY, MIL_CONST_TEXT_PTR ImageName) { // Set the text alignment and color of the graphic contexts. MgraControl(MilGraContext, M_TEXT_ALIGN_HORIZONTAL, M_CENTER); MgraControl(MilGraContext, M_TEXT_ALIGN_VERTICAL, M_BOTTOM); // Draw the names of the images over them. MgraColor(MilGraContext, M_COLOR_CYAN); MgraText(MilGraContext, m_MilGraList, ImageSizeX/2, -WINDOW_TITLE_HEIGHT/2, ImageName); // Draw borders around the childs. MgraColor(MilGraContext, M_COLOR_WHITE); MgraRectAngle(MilGraContext, m_MilGraList, ImageSizeX/2, ImageSizeY/2, ImageSizeX + m_ImageSpacing, ImageSizeY + WINDOW_TITLE_HEIGHT, 0, M_CENTER_AND_DIMENSION); } //***************************************************************************** // Create the luminance version of the source image. //***************************************************************************** void CDefectDetectionExampleMngr::CreateLuminanceImage(MIL_ID MilRGBSrc, MIL_INT SizeX, MIL_INT SizeY, MIL_ID *MilLumImagePtr) { MbufAlloc2d(m_MilSystem, SizeX, SizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC, MilLumImagePtr); MimConvert(MilRGBSrc, *MilLumImagePtr, M_RGB_TO_L); } //***************************************************************************** // Displays the information of the template (model edges, coordinate system // and fixturing offset). //***************************************************************************** void CDefectDetectionExampleMngr::ShowTargetAndTemplate(MIL_CONST_TEXT_PTR TargetImagePath) { // Print intermediate info in the console. MIL_CONST_TEXT_PTR TargetImageName = GetFileName(TargetImagePath); MosPrintf(MIL_TEXT("The target image %s has been loaded \n"), TargetImageName); MosPrintf(MIL_TEXT("and is shown in the display.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); // Show the fixture offset and the coordinate system on the template. MgraColor(m_MilGraContextTemplate, M_COLOR_YELLOW); McalDraw(m_MilGraContextTemplate, m_MilFixturingOffset, m_MilGraList, M_DRAW_FIXTURING_OFFSET, M_DEFAULT, M_DEFAULT); MgraColor(m_MilGraContextTemplate, M_COLOR_GREEN); McalDraw(m_MilGraContextTemplate, M_NULL, m_MilGraList, M_DRAW_PIXEL_COORDINATE_SYSTEM+M_DRAW_FRAME, M_DEFAULT, M_DEFAULT); // Show the model edges. MgraColor(m_MilGraContextTemplate, M_COLOR_RED); MmodDraw(m_MilGraContextTemplate, m_MilModContext, m_MilGraList, M_DRAW_EDGES, M_DEFAULT, M_ORIGINAL); // Print intermediate info in the console. MosPrintf(MIL_TEXT("The model's edges and the fixturing offset are shown in the \n")); MosPrintf(MIL_TEXT("template display.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } //***************************************************************************** // Displays all the occurrences of the model that were found. //***************************************************************************** void CDefectDetectionExampleMngr::ShowAllOccurrences() { MgraColor(m_MilGraContextTarget, M_COLOR_GREEN); for(MIL_INT i = 0; i < m_NbOccurences; i++) { MmodDraw(m_MilGraContextTarget, m_MilModResult, m_MilGraList, M_DRAW_BOX, i, M_DEFAULT); MmodDraw(m_MilGraContextTarget, m_MilModResult, m_MilGraList, M_DRAW_POSITION, i, M_DEFAULT); if(i == 0) m_ModOccDrawStartIndex = MgraInquireList(m_MilGraList, M_LIST, M_DEFAULT, M_NUMBER_OF_GRAPHICS, M_NULL) - 2; } // Print intermediate info in the console. MosPrintf(MIL_TEXT("The occurrences found in the target image are shown in the target\n")); MosPrintf(MIL_TEXT("display.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } //***************************************************************************** // Displays the current warped occurrence. //***************************************************************************** void CDefectDetectionExampleMngr::ShowWarpedOccurrence(MIL_INT OccurrenceIdx) { // Set the color of the occurences. All are green except the one to process which is red. for(MIL_INT i = 0, GraphicIndex = m_ModOccDrawStartIndex; i < m_NbOccurences; i++) { MgraControlList(m_MilGraList, M_GRAPHIC_INDEX(GraphicIndex++), M_DEFAULT, M_COLOR, i == OccurrenceIdx? M_COLOR_RED : M_COLOR_GREEN); MgraControlList(m_MilGraList, M_GRAPHIC_INDEX(GraphicIndex++), M_DEFAULT, M_COLOR, i == OccurrenceIdx? M_COLOR_RED : M_COLOR_GREEN); } // Show the coordinate system of the warped target and of the fixtured target. MgraColor(m_MilGraContextTarget, M_COLOR_RED); McalDraw(m_MilGraContextTarget, m_MilTargetImage, m_MilGraList, M_DRAW_RELATIVE_COORDINATE_SYSTEM+M_DRAW_FRAME, M_DEFAULT, M_DEFAULT); MgraColor(m_MilGraContextWarpedTarget, M_COLOR_RED); McalDraw(m_MilGraContextWarpedTarget, m_MilWarpedTargetImage, m_MilGraList, M_DRAW_RELATIVE_COORDINATE_SYSTEM+M_DRAW_FRAME, M_DEFAULT, M_DEFAULT); // Print intermediate info in the console. MosPrintf(MIL_TEXT("The occurrence %i has been warped.\n"), (int)OccurrenceIdx); MosPrintf(MIL_TEXT("Will now proceed with the defect detection.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } //***************************************************************************** // Displays the defect detection. //***************************************************************************** void CDefectDetectionExampleMngr::ShowDefectDetection() { if(m_ChangeDiff) { // Update the displayed difference image and inspection image(the displayed images are the same). MbufCopy(m_MilDifferenceGrayImage, m_MilDifferenceImage); MbufCopy(m_MilDifferenceGrayImage, m_MilInspectionImage); } if(m_ChangeBin) { if(m_BlobDrawLabel) MgraControlList(m_MilGraList, M_GRAPHIC_LABEL(m_BlobDrawLabel), M_DEFAULT, M_DELETE, M_DEFAULT); MgraColor(m_MilGraContextInspection, M_COLOR_RED); MblobDraw(m_MilGraContextInspection, m_MilBlobResult, m_MilGraList, M_DRAW_BLOBS, M_DEFAULT, M_DEFAULT); MgraInquireList(m_MilGraList, M_LIST, M_DEFAULT, M_LAST_LABEL, &m_BlobDrawLabel); } } //***************************************************************************** // Clears the defect detection. //***************************************************************************** void CDefectDetectionExampleMngr::ClearDefectDetection() { // Get the number of graphics in the graphic list. MIL_INT NbGraphics = MgraInquireList(m_MilGraList, M_LIST, M_DEFAULT, M_NUMBER_OF_GRAPHICS, M_NULL); // Clear all the primitives related to the defect detection. for(MIL_INT GraphicIndex = m_ModOccDrawStartIndex + m_NbOccurences*2; GraphicIndex < NbGraphics; GraphicIndex++) MgraControlList(m_MilGraList, M_GRAPHIC_INDEX(GraphicIndex), M_DEFAULT, M_DELETE, M_DEFAULT); // Reset the blob draw label. m_BlobDrawLabel = M_NULL; } //***************************************************************************** // Prints a given method choices. //***************************************************************************** void CDefectDetectionExampleMngr::PrintMethodChoices(MIL_CONST_TEXT_PTR MethodTypeTag, MIL_CONST_TEXT_PTR *MethodsTags, MIL_INT NbMethod, MIL_TEXT_CHAR StartChar) { MosPrintf(MIL_TEXT("%s method:\n"), MethodTypeTag); for(MIL_INT i=0; i<NbMethod; i++) MosPrintf(MIL_TEXT(" %c. %s\n"), StartChar+i, MethodsTags[i]); MosPrintf(MIL_TEXT("\n")); } //***************************************************************************** // Prints the current methods. //***************************************************************************** void CDefectDetectionExampleMngr::PrintCurrentMethods(MIL_TEXT_CHAR DiffStartChar, MIL_TEXT_CHAR BinStartChar, DifferenceExtractionMethod DiffMethod, BinarizationMethod BinMethod) { MosPrintf(MIL_TEXT("Current methods for difference extraction and binarization:\n")); MosPrintf(MIL_TEXT("%c. %s\n"), DiffStartChar+DiffMethod, DifferenceExtractionMethodsTags[DiffMethod]); MosPrintf(MIL_TEXT("%c. %s\n\n"), BinStartChar+BinMethod, BinarizationMethodsTags[BinMethod]); } //***************************************************************************** // Ask the user for interactive method choice. //***************************************************************************** bool CDefectDetectionExampleMngr::AskForInteractive() { // Ask the user if he wants to run the example in interactive mode. MosPrintf(MIL_TEXT("Do you want to run the example in interactive mode? (Y or N)\n\n")); do { switch(MosGetch()) { case 'y': case 'Y': m_IsInteractive = true; return true; case 'n': case 'N': return false; } } while(1); return true; } //***************************************************************************** // Ask the user for a method modification. //***************************************************************************** bool CDefectDetectionExampleMngr::AskForMethod(DifferenceExtractionMethod &DiffMethod, BinarizationMethod &BinMethod) { if(m_IsInteractive) { // Print the methods currently in use. PrintCurrentMethods(MIL_TEXT('1'), MIL_TEXT('A'), DiffMethod, BinMethod); // Print the methods choices. PrintMethodChoices(MIL_TEXT("Difference extraction"), DifferenceExtractionMethodsTags, enNbDiffMethod, MIL_TEXT('1')); PrintMethodChoices(MIL_TEXT("Binarization"), BinarizationMethodsTags, enNbBinMethod, MIL_TEXT('A')); MosPrintf(MIL_TEXT("Other:\n")); MosPrintf(MIL_TEXT(" Q. Continue\n\n")); MosPrintf(MIL_TEXT("Your choice : ")); MIL_TEXT_CHAR Choice; while(!m_ChangeDiff && !m_ChangeBin) { // Get the user's choice. Choice = (MIL_TEXT_CHAR)MosGetch(); switch(Choice) { case '1': m_ChangeDiff = true; DiffMethod = enAbsoluteDiff; break; case '2': m_ChangeDiff = true; DiffMethod = enColDistance; break; case '3': m_ChangeDiff = true; DiffMethod = enBottomHat; break; case '4': m_ChangeDiff = true; DiffMethod = enTopHat; break; case 'a': case 'A': m_ChangeBin = true; BinMethod = enBiModal; break; case 'b': case 'B': m_ChangeBin = true; BinMethod = enTriangleBisection; break; case 'c': case 'C': m_ChangeBin = true; BinMethod = enCumulHistPercentage; break; case 'd': case 'D': m_ChangeBin = true; BinMethod = enFixed; break; case 'q': case 'Q': MosPrintf(MIL_TEXT("Q. Continue\n\n")); return false; default: break; } } if(m_ChangeDiff) MosPrintf(MIL_TEXT("%c. %s\n\n"), Choice, DifferenceExtractionMethodsTags[DiffMethod]); else if(m_ChangeBin) MosPrintf(MIL_TEXT("%c. %s\n\n"), Choice, BinarizationMethodsTags[BinMethod]); return true; } else { MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); return false; } } //***************************************************************************** // Draws the histogram of the image //***************************************************************************** void CDefectDetectionExampleMngr::ShowHistogram() { // Calculate the histogram. MimHistogram(m_MilDifferenceGrayImage, m_MilHistResult); // Get the results of the histogram. MIL_INT Histogram[256]; MimGetResult(m_MilHistResult, M_VALUE+M_TYPE_MIL_INT, Histogram); // Get the maximum value of the histogram. MIL_INT MaxHistValue = -MIL_INT_MAX; for(MIL_INT i = ((MIL_INT) TRIANGLE_LOWER_CUTOFF); i < 256; i++) MaxHistValue = Histogram[i] > MaxHistValue ? Histogram[i] : MaxHistValue; if(MaxHistValue < 1) { MaxHistValue = 1; } // Calculate the pixel scale. MIL_DOUBLE YPixelScale = 256.0 / MaxHistValue; // Disable the graphic updates. MdispControl(m_MilHistDisplay, M_UPDATE_GRAPHIC_LIST, M_DISABLE); // Update the histogram bands. for(MIL_INT i = 0; i < 256; i++) { MIL_DOUBLE Width = Histogram[i]*YPixelScale; MgraControlList(m_MilHistDispGraphicList, M_GRAPHIC_INDEX(i), M_DEFAULT, M_RECTANGLE_WIDTH, Width > 256.0 ? 256.0 : Width); } // Update the threshold MgraControlList(m_MilHistDispGraphicList, M_GRAPHIC_INDEX(256), M_DEFAULT, M_POSITION_X, (MIL_DOUBLE) (HIST_BORDER + m_BinValue + 0.5)); // Update the threshold text MIL_TEXT_CHAR BinValueString[4]; MosSprintf(BinValueString, 4, MIL_TEXT("%i"), (int)m_BinValue); MgraControlList(m_MilHistDispGraphicList, M_GRAPHIC_INDEX(260), M_DEFAULT, M_DELETE, M_DEFAULT); MgraControl(M_DEFAULT, M_TEXT_ALIGN_HORIZONTAL, M_CENTER); MgraControl(M_DEFAULT, M_TEXT_ALIGN_VERTICAL, M_TOP); MgraColor(M_DEFAULT, M_COLOR_BLUE); MgraText(M_DEFAULT, m_MilHistDispGraphicList, HIST_BORDER + m_BinValue + 0.5, 256 + HIST_BORDER + 5, BinValueString); // Enable The graphic updates. MdispControl(m_MilHistDisplay, M_UPDATE_GRAPHIC_LIST, M_ENABLE); // Select the image on the display to show it MdispSelect(m_MilHistDisplay, m_MilHistDisplayImage); } //***************************************************************************** // Initialize the Histogram //***************************************************************************** void CDefectDetectionExampleMngr::InitHistogram() { // Create the histogram bands. MgraColor(M_DEFAULT, M_COLOR_GREEN); for(MIL_INT i = 0; i < 256; i++) MgraRectAngle(M_DEFAULT, m_MilHistDispGraphicList, i+HIST_BORDER, 256.0 + HIST_BORDER, 1, 1, 90, M_CORNER_AND_DIMENSION + M_FILLED); // Create the threshold MgraColor(M_DEFAULT, M_COLOR_BLUE); MgraLine(M_DEFAULT, m_MilHistDispGraphicList, HIST_BORDER, HIST_BORDER/2, HIST_BORDER, 261.0+HIST_BORDER); // Create the axis on the histogram. MgraColor(M_DEFAULT, M_COLOR_RED); MgraLine(M_DEFAULT, m_MilHistDispGraphicList, HIST_BORDER, 256.0 + HIST_BORDER, HIST_BORDER, HIST_BORDER/2); MgraLine(M_DEFAULT, m_MilHistDispGraphicList, HIST_BORDER, 256.0 + HIST_BORDER, 256.0 + 3*HIST_BORDER/2, 256.0 + HIST_BORDER); // Create the histogram title. MgraColor(M_DEFAULT, M_COLOR_CYAN); MgraControl(M_DEFAULT, M_TEXT_ALIGN_HORIZONTAL, M_CENTER); MgraControl(M_DEFAULT, M_TEXT_ALIGN_VERTICAL, M_TOP); MgraText(M_DEFAULT, m_MilHistDispGraphicList, 128.0 + HIST_BORDER, 0, MIL_TEXT("Histogram")); //Draw the threshold text MgraControl(M_DEFAULT, M_TEXT_ALIGN_HORIZONTAL, M_CENTER); MgraControl(M_DEFAULT, M_TEXT_ALIGN_VERTICAL, M_TOP); MgraText(M_DEFAULT, m_MilHistDispGraphicList, HIST_BORDER, 256.0 + HIST_BORDER + 5, MIL_TEXT("")); }