#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)
{
MblobAlloc(MilSystem, M_DEFAULT, M_DEFAULT, &m_MilBlobContext);
MblobAllocResult(MilSystem, M_DEFAULT, M_DEFAULT, &m_MilBlobResult);
MblobControl(m_MilBlobContext, M_FOREGROUND_VALUE, M_ZERO);
MblobControl(m_MilBlobContext, M_CONNECTIVITY, M_8_CONNECTED);
AllocateArrays(STARTING_ARRAY_SIZE);
}
CBlackFiducialFinder::~CBlackFiducialFinder()
{
DestroyArrays();
MblobFree(m_MilBlobResult);
MblobFree(m_MilBlobContext);
}
MIL_INT CBlackFiducialFinder::Find(MIL_ID MilBinarizedImage)
{
MblobControl(m_MilBlobContext, M_ALL_FEATURES, M_DISABLE);
MblobControl(m_MilBlobContext, M_NUMBER_OF_HOLES, M_ENABLE);
MblobCalculate(m_MilBlobContext, MilBinarizedImage, M_NULL, 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);
MblobControl(m_MilBlobContext, M_FERETS, M_ENABLE);
MblobControl(m_MilBlobContext, M_ROUGHNESS, M_ENABLE);
MblobCalculate(m_MilBlobContext, MilBinarizedImage, M_NULL, 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;
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_NUMBER + M_TYPE_MIL_INT, &NbBlobs);
if (NbBlobs > 0)
{
MblobControl(m_MilBlobContext, M_CENTER_OF_GRAVITY + M_BINARY, M_ENABLE);
MblobControl(m_MilBlobContext, M_BOX, M_ENABLE);
MblobCalculate(m_MilBlobContext, MilBinarizedImage, M_NULL, m_MilBlobResult);
ReserveArraySpace(NbBlobs);
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_BOX_X_MIN, m_BoxXMinArray);
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_BOX_Y_MIN, m_BoxYMinArray);
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_BOX_X_MAX, m_BoxXMaxArray);
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_BOX_Y_MAX, m_BoxYMaxArray);
MblobGetResult(m_MilBlobResult, M_DEFAULT, M_CENTER_OF_GRAVITY_X + M_BINARY, m_CoGXArray);
MblobGetResult(m_MilBlobResult, M_DEFAULT, 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;
}