#include <mil.h>
#include "DefectDetectionTask.h"
static const MIL_INT DEFECT_SIZE = 4;
static const MIL_DOUBLE GRADIENT_MASK_SMOOTHNESS = 70;
static const MIL_DOUBLE TRIANGLE_LOWER_CUTOFF = 2;
static const MIL_DOUBLE TRIANGLE_UPPER_CUTOFF = 255;
static const MIL_DOUBLE BIN_CUMULATIVE_VALUE = 99.0;
static const MIL_DOUBLE FIXED_DIFF_THRESHOLD = 10;
static const MIL_DOUBLE NORMAL_VARIATIONS = 20;
static const MIL_INT CLEAN_MORPH_SIZE = 0;
static const MIL_DOUBLE MIN_AREA = 10;
CDefectDetectionTask::CDefectDetectionTask(MIL_CONST_TEXT_PTR TemplatePath, MIL_CONST_TEXT_PTR TemplateMaskPath, DifferenceExtractionMethod DiffMethod, BinarizationMethod BinMethod, MIL_INT ColorConversion , CInspectionTask* FixtureProvider , CInspectionTask* ImageProvider )
: CInspectionTask(ColorConversion, FixtureProvider, ImageProvider),
m_DiffMethod(DiffMethod),
m_BinMethod(BinMethod),
m_MilBlobFeatureList (M_NULL),
m_MilBlobResult (M_NULL),
m_MilTemplateImage (M_NULL),
m_MilTemplateGrayImage (M_NULL),
m_MilTemplateMask (M_NULL),
m_MilTemplateGradientMask (M_NULL),
m_MilTemplateGradientGrayMask (M_NULL),
m_MilDifferenceGrayImage (M_NULL),
m_MilExtractedDefectsImage (M_NULL)
{
CloneString(m_TemplatePath, TemplatePath);
CloneString(m_TemplateMaskPath, TemplateMaskPath);
}
CDefectDetectionTask::~CDefectDetectionTask()
{
if(m_TemplateMaskPath)
{ delete [] m_TemplateMaskPath; }
if(m_TemplatePath)
{ delete [] m_TemplatePath; }
FreeMilObjects();
}
void CDefectDetectionTask::Free()
{
CInspectionTask::Free();
FreeMilObjects();
}
void CDefectDetectionTask::Init(MIL_ID MilSystem, MIL_INT ImageSizeX , MIL_INT ImageSizeY )
{
CInspectionTask::Init(MilSystem, ImageSizeX, ImageSizeY);
MbufRestore(m_TemplatePath, MilSystem, &m_MilTemplateImage);
MIL_INT TemplateSizeX = MbufInquire(m_MilTemplateImage, M_SIZE_X, M_NULL);
MIL_INT TemplateSizeY = MbufInquire(m_MilTemplateImage, M_SIZE_Y, M_NULL);
MbufRestore(m_TemplateMaskPath, MilSystem, &m_MilTemplateMask);
m_MilTemplateGrayImage = CreateConvertedImage(m_MilTemplateImage, GetColorConversion());
CreateGradientMaskImage(m_MilTemplateGrayImage, m_MilTemplateImage, GRADIENT_MASK_SMOOTHNESS, &m_MilTemplateGradientMask, &m_MilTemplateGradientGrayMask);
MbufAlloc2d(MilSystem, TemplateSizeX, TemplateSizeY, 8+M_UNSIGNED, M_IMAGE+M_PROC, &m_MilDifferenceGrayImage);
MbufAlloc2d(MilSystem, TemplateSizeX, TemplateSizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC, &m_MilExtractedDefectsImage);
MblobAllocFeatureList(MilSystem, &m_MilBlobFeatureList);
MblobSelectFeature(m_MilBlobFeatureList, M_BOX);
MblobAllocResult(MilSystem, &m_MilBlobResult);
MblobControl(m_MilBlobResult, M_RESULT_OUTPUT_UNITS, M_WORLD);
}
ResultStatusEnum CDefectDetectionTask::Inspect(MIL_ID MilImage)
{
ExtractDifferences(m_MilTemplateImage, m_MilTemplateGrayImage, m_MilTemplateGradientMask, m_MilTemplateGradientGrayMask, MilImage, m_MilDifferenceGrayImage, M_NULL, m_DiffMethod);
MimArith(m_MilDifferenceGrayImage, m_MilTemplateMask, m_MilDifferenceGrayImage, M_AND);
ExtractDefects(m_MilDifferenceGrayImage,
m_MilExtractedDefectsImage,
TRIANGLE_LOWER_CUTOFF,
TRIANGLE_UPPER_CUTOFF,
BIN_CUMULATIVE_VALUE,
NORMAL_VARIATIONS,
FIXED_DIFF_THRESHOLD,
CLEAN_MORPH_SIZE,
m_BinMethod);
McalAssociate(M_NULL, m_MilExtractedDefectsImage, M_DEFAULT);
McalUniform(m_MilExtractedDefectsImage, 0.0, 0.0, 1.0, 1.0, 0.0, M_DEFAULT);
MblobCalculate(m_MilExtractedDefectsImage, M_NULL, m_MilBlobFeatureList, m_MilBlobResult);
MblobSelect(m_MilBlobResult, M_DELETE, M_AREA, M_LESS, MIN_AREA, M_NULL);
return eValid;
}
void CDefectDetectionTask::DrawGraphicalResult(MIL_ID MilGraContext, MIL_ID MilDest)
{
MgraColor(MilGraContext, M_COLOR_RED);
MblobDraw(MilGraContext, m_MilBlobResult, MilDest, M_DRAW_BOX, M_DEFAULT, M_DEFAULT);
}
void CDefectDetectionTask::DrawTextResult(MIL_ID MilGraContext, MIL_ID MilDest)
{
if(GetResultStatus() == eUnknown)
{
MgraColor(MilGraContext, M_COLOR_YELLOW);
MgraText(MilGraContext, MilDest, 0, 0, MIL_TEXT("Defect detection: UNKNOWN"));
}
else
{
if(IsResultValid() && MblobGetNumber(m_MilBlobResult, M_NULL) == 0)
{
MgraColor(MilGraContext, M_COLOR_GREEN);
MgraText(MilGraContext, MilDest, 0, 0, MIL_TEXT("Defect detection: PASS"));
}
else
{
MgraColor(MilGraContext, M_COLOR_RED);
MgraText(MilGraContext, MilDest, 0, 0, MIL_TEXT("Defect detection: FAIL"));
}
}
MoveGraphicContextYOffset(MilGraContext, 1);
}
void CDefectDetectionTask::FreeMilObjects()
{
if(m_MilTemplateGrayImage)
{
MbufFree(m_MilTemplateGrayImage);
m_MilTemplateGrayImage = 0;
}
if(m_MilTemplateImage)
{
MbufFree(m_MilTemplateImage);
m_MilTemplateImage = 0;
}
if(m_MilTemplateMask)
{
MbufFree(m_MilTemplateMask);
m_MilTemplateMask = 0;
}
if(m_MilTemplateGradientMask)
{
MbufFree(m_MilTemplateGradientMask);
m_MilTemplateGradientMask = 0;
}
if(m_MilTemplateGradientGrayMask)
{
MbufFree(m_MilTemplateGradientGrayMask);
m_MilTemplateGradientGrayMask = 0;
}
if(m_MilDifferenceGrayImage)
{
MbufFree(m_MilDifferenceGrayImage);
m_MilDifferenceGrayImage = 0;
}
if(m_MilExtractedDefectsImage)
{
MbufFree(m_MilExtractedDefectsImage);
m_MilExtractedDefectsImage = 0;
}
if(m_MilBlobFeatureList)
{
MblobFree(m_MilBlobFeatureList);
m_MilBlobFeatureList = 0;
}
if(m_MilBlobResult)
{
MblobFree(m_MilBlobResult);
m_MilBlobResult = 0;
}
}