#include "common.h"
#include "BlackFiducialFinder.h"
static const MIL_INT STARTING_ARRAY_SIZE = 16;
static const MIL_DOUBLE MIN_AREA = 80.0;
static const MIL_DOUBLE MAX_AREA = 800.0;
static const MIL_DOUBLE EXPECTED_HOLES = 1.0;
static const MIL_DOUBLE MIN_FERET_MAX = 12.0;
static const MIL_DOUBLE MAX_FERET_MAX = 40.0;
static const MIL_DOUBLE MAX_ROUGHNESS = 1.65;
CBlackFiducialFinder::CBlackFiducialFinder(MIL_ID MilSystem)
{
MblobAllocFeatureList(MilSystem, &m_MilFeatureList);
MblobAllocResult(MilSystem, &m_MilBlobResult);
MblobControl(m_MilBlobResult, M_FOREGROUND_VALUE, M_ZERO );
MblobControl(m_MilBlobResult, M_LATTICE , M_8_CONNECTED);
AllocateArrays(STARTING_ARRAY_SIZE);
}
CBlackFiducialFinder::~CBlackFiducialFinder()
{
DestroyArrays();
MblobFree(m_MilBlobResult);
MblobFree(m_MilFeatureList);
}
MIL_INT CBlackFiducialFinder::Find(MIL_ID MilBinarizedImage)
{
MblobSelectFeature(m_MilFeatureList, M_NO_FEATURES);
MblobSelectFeature(m_MilFeatureList, M_AREA);
MblobSelectFeature(m_MilFeatureList, M_NUMBER_OF_HOLES);
MblobCalculate(MilBinarizedImage, M_NULL, m_MilFeatureList, m_MilBlobResult);
MblobSelect(m_MilBlobResult, M_DELETE, M_AREA, M_OUT_RANGE, MIN_AREA, MAX_AREA);
MblobSelect(m_MilBlobResult, M_DELETE, M_NUMBER_OF_HOLES, M_NOT_EQUAL, EXPECTED_HOLES, M_NULL);
MblobSelectFeature(m_MilFeatureList, M_FERET_MAX_DIAMETER);
MblobSelectFeature(m_MilFeatureList, M_ROUGHNESS);
MblobCalculate(MilBinarizedImage, M_NULL, m_MilFeatureList, m_MilBlobResult);
MblobSelect(m_MilBlobResult, M_DELETE, M_FERET_MAX_DIAMETER, M_OUT_RANGE, MIN_FERET_MAX, MAX_FERET_MAX);
MblobSelect(m_MilBlobResult, M_DELETE, M_ROUGHNESS, M_GREATER, MAX_ROUGHNESS, M_NULL);
MIL_INT NbBlobs = MblobGetNumber(m_MilBlobResult, M_NULL);
if (NbBlobs > 0)
{
MblobSelectFeature(m_MilFeatureList, M_CENTER_OF_GRAVITY);
MblobSelectFeature(m_MilFeatureList, M_BOX_X_MIN);
MblobSelectFeature(m_MilFeatureList, M_BOX_X_MAX);
MblobSelectFeature(m_MilFeatureList, M_BOX_Y_MIN);
MblobSelectFeature(m_MilFeatureList, M_BOX_Y_MAX);
MblobCalculate(MilBinarizedImage, M_NULL, m_MilFeatureList, m_MilBlobResult);
ReserveArraySpace(NbBlobs);
MblobGetResult(m_MilBlobResult, M_BOX_X_MIN, m_BoxXMinArray);
MblobGetResult(m_MilBlobResult, M_BOX_Y_MIN, m_BoxYMinArray);
MblobGetResult(m_MilBlobResult, M_BOX_X_MAX, m_BoxXMaxArray);
MblobGetResult(m_MilBlobResult, M_BOX_Y_MAX, m_BoxYMaxArray);
MblobGetResult(m_MilBlobResult, M_CENTER_OF_GRAVITY_X+M_BINARY, m_CoGXArray );
MblobGetResult(m_MilBlobResult, M_CENTER_OF_GRAVITY_Y+M_BINARY, m_CoGYArray );
}
return NbBlobs;
}
void CBlackFiducialFinder::GetChildRect(MIL_INT FiducialIdx,
MIL_INT* pChildOffsetX, MIL_INT* pChildOffsetY,
MIL_INT* pChildSizeX, MIL_INT* pChildSizeY)
{
*pChildOffsetX = static_cast<MIL_INT>( m_BoxXMinArray[FiducialIdx] );
*pChildOffsetY = static_cast<MIL_INT>( m_BoxYMinArray[FiducialIdx] );
*pChildSizeX = static_cast<MIL_INT>( m_BoxXMaxArray[FiducialIdx]+1.0 ) - *pChildOffsetX;
*pChildSizeY = static_cast<MIL_INT>( m_BoxYMaxArray[FiducialIdx]+1.0 ) - *pChildOffsetY;
}
void CBlackFiducialFinder::ReserveArraySpace(MIL_INT MinArraySize)
{
if (m_ArraySize < MinArraySize)
{
DestroyArrays();
AllocateArrays(MinArraySize);
}
}
void CBlackFiducialFinder::AllocateArrays(MIL_INT ArraySize)
{
m_BoxXMinArray = new MIL_DOUBLE[ArraySize];
m_BoxYMinArray = new MIL_DOUBLE[ArraySize];
m_BoxXMaxArray = new MIL_DOUBLE[ArraySize];
m_BoxYMaxArray = new MIL_DOUBLE[ArraySize];
m_CoGXArray = new MIL_DOUBLE[ArraySize];
m_CoGYArray = new MIL_DOUBLE[ArraySize];
m_ArraySize = ArraySize;
}
void CBlackFiducialFinder::DestroyArrays()
{
delete [] m_CoGYArray;
delete [] m_CoGXArray;
delete [] m_BoxYMaxArray;
delete [] m_BoxXMaxArray;
delete [] m_BoxYMinArray;
delete [] m_BoxXMinArray;
}