#include "common.h"
#include "FeatureFinder.h"
#include "AdaptiveThresholder.h"
#include "BlackFiducialFinder.h"
#include "WhiteFiducialFinder.h"
#include "PharmacodeReader.h"
struct SCADFeature
{
const MIL_TEXT_CHAR* m_CodeString;
MIL_DOUBLE m_PosX;
MIL_DOUBLE m_PosY;
MIL_DOUBLE m_PosZ;
};
static const SCADFeature CAD_FEATURE_ARRAY[] =
{
{MIL_TEXT("16"), 68.6, 178.9, -93.6},
{MIL_TEXT("17"), 101.8, 178.8, -93.8},
{MIL_TEXT("18"), 112.1, 11.0, -60.9},
{MIL_TEXT("20"), 55.5, 12.6, -61.0},
{MIL_TEXT("22"), 107.7, 92.6, -92.8},
{MIL_TEXT("26"), 61.4, 92.5, -92.7},
{MIL_TEXT("64"), 127.5, 177.5, -73.2},
{MIL_TEXT("65"), 43.1, 178.6, -73.5},
{MIL_TEXT("66"), 123.8, 120.8, -84.8},
{MIL_TEXT("67"), 45.4, 120.2, -85.4},
{MIL_TEXT("68"), 133.4, 157.5, -62.3},
{MIL_TEXT("69"), 37.3, 159.1, -63.2},
{MIL_TEXT("72"), 134.5, 81.2, -56.9},
{MIL_TEXT("73"), 34.5, 79.7, -58.3}
};
static const MIL_INT NB_CAD_FEATURES = sizeof(CAD_FEATURE_ARRAY)/sizeof(CAD_FEATURE_ARRAY[0]);
CFeatureFinder::CFeatureFinder(MIL_ID MilSystem, MIL_INT SizeX, MIL_INT SizeY)
: m_pAdaptiveThresholder(new CAdaptiveThresholder(MilSystem, SizeX, SizeY)),
m_pBlackFiducialFinder(new CBlackFiducialFinder(MilSystem)),
m_pWhiteFiducialFinder(new CWhiteFiducialFinder(MilSystem)),
m_pPharmacodeReader (new CPharmacodeReader (MilSystem))
{
MbufAlloc2d(MilSystem, SizeX, SizeY, 1+M_UNSIGNED, M_IMAGE+M_PROC, &m_MilBinarizedImage);
MbufChild2d(m_MilBinarizedImage, 0, 0, 1, 1, &m_MilBinarizedChild);
}
CFeatureFinder::~CFeatureFinder()
{
delete m_pAdaptiveThresholder;
delete m_pBlackFiducialFinder;
delete m_pWhiteFiducialFinder;
delete m_pPharmacodeReader ;
MbufFree(m_MilBinarizedChild);
MbufFree(m_MilBinarizedImage);
}
void CFeatureFinder::Find(MIL_ID MilDisplay, MIL_ID MilDisplayImage, SObjectFeatures* pObjectFeatures)
{
MIL_ID MilOverlayImage;
MdispInquire(MilDisplay, M_OVERLAY_ID, &MilOverlayImage);
pObjectFeatures->m_NumPoint = 0;
m_pAdaptiveThresholder->Binarize(MilDisplayImage, m_MilBinarizedImage);
MIL_INT NbBlackFiducials = m_pBlackFiducialFinder->Find(m_MilBinarizedImage);
for (MIL_INT BlackFiducialIdx = 0; BlackFiducialIdx < NbBlackFiducials; ++BlackFiducialIdx)
{
MIL_INT ChildOffsetX, ChildOffsetY, ChildSizeX, ChildSizeY;
m_pBlackFiducialFinder->GetChildRect(BlackFiducialIdx, &ChildOffsetX, &ChildOffsetY, &ChildSizeX, &ChildSizeY);
MbufChildMove(m_MilBinarizedChild, ChildOffsetX, ChildOffsetY, ChildSizeX, ChildSizeY, M_DEFAULT);
MIL_DOUBLE ApproxWhiteBlobX = 0.5*static_cast<MIL_DOUBLE>(ChildSizeX+1);
MIL_DOUBLE ApproxWhiteBlobY = 0.5*static_cast<MIL_DOUBLE>(ChildSizeY+1);
bool WhiteFiducialFound = m_pWhiteFiducialFinder->Find(m_MilBinarizedChild, ApproxWhiteBlobX, ApproxWhiteBlobY);
MIL_DOUBLE WhiteFiducialX = m_pWhiteFiducialFinder->GetCoGX() + static_cast<MIL_DOUBLE>(ChildOffsetX);
MIL_DOUBLE WhiteFiducialY = m_pWhiteFiducialFinder->GetCoGY() + static_cast<MIL_DOUBLE>(ChildOffsetY);
if (WhiteFiducialFound)
{
McalFixture(MilDisplayImage, M_NULL, M_MOVE_RELATIVE, M_POINT_AND_DIRECTION_POINT, M_NULL,
WhiteFiducialX, WhiteFiducialY,
m_pBlackFiducialFinder->GetCoGX(BlackFiducialIdx), m_pBlackFiducialFinder->GetCoGY(BlackFiducialIdx));
const MIL_TEXT_CHAR* PharmacodeString = m_pPharmacodeReader->Read(MilDisplayImage);
if ( PharmacodeString != NULL )
{
for (MIL_INT CADFeatureIdx = 0; CADFeatureIdx < NB_CAD_FEATURES; ++CADFeatureIdx)
{
if (MosStrcmp(PharmacodeString, CAD_FEATURE_ARRAY[CADFeatureIdx].m_CodeString) == 0)
{
MIL_INT FoundFeatureIdx = pObjectFeatures->m_NumPoint;
pObjectFeatures->m_XPixArray [FoundFeatureIdx] = WhiteFiducialX;
pObjectFeatures->m_YPixArray [FoundFeatureIdx] = WhiteFiducialY;
pObjectFeatures->m_XWorldArray[FoundFeatureIdx] = CAD_FEATURE_ARRAY[CADFeatureIdx].m_PosX;
pObjectFeatures->m_YWorldArray[FoundFeatureIdx] = CAD_FEATURE_ARRAY[CADFeatureIdx].m_PosY;
pObjectFeatures->m_ZWorldArray[FoundFeatureIdx] = CAD_FEATURE_ARRAY[CADFeatureIdx].m_PosZ;
pObjectFeatures->m_NumPoint++;
m_pWhiteFiducialFinder->Draw(MilOverlayImage);
m_pPharmacodeReader->Draw(MilOverlayImage);
break;
}
}
}
}
if (pObjectFeatures->m_NumPoint == MAX_NB_FEATURES)
break;
}
McalAssociate(M_NULL, MilDisplayImage, M_DEFAULT);
}