#include <mil.h>
#define GEOMETRIC 0
#define GRAYSCALE 1
#define PATTERN_MATCHING_METHOD GRAYSCALE
#define MODEL_WIDTH 128L
#define MODEL_HEIGHT 128L
#define MODEL_POS_X_INIT 320L
#define MODEL_POS_Y_INIT 240L
#define MODEL_MIN_MATCH_SCORE 50.0
#define NB_TARGET_IMAGES 4
#if M_MIL_USE_RT
#define MIL_SLAVE_EXPORT __declspec(dllexport)
#else
#define MIL_SLAVE_EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
MIL_SLAVE_EXPORT void MFTYPE SlavePatternMatchingLoop(MIL_ID Func);
#ifdef __cplusplus
}
#endif
typedef struct
{
MIL_ID MilSystem;
MIL_ID MilDisplay;
MIL_ID MilDigitizer;
MIL_ID MilImageDisp;
MIL_ID MilImage[NB_TARGET_IMAGES];
MIL_ID MilThread;
MIL_ID MilDataExchangeBuffer;
MIL_ID MilDataExchangeBufferReadyEvent;
MIL_ID MilModelPositionOkEvent;
MIL_ID MilStopProcessingEvent;
MIL_ID MilModel;
MIL_ID MilResult;
MIL_INT32 PatternMatchingMethod;
MIL_INT32 DisplayUpdateFlag;
MIL_INT32 Found;
MIL_DOUBLE PosX;
MIL_DOUBLE PosY;
MIL_DOUBLE Score;
MIL_DOUBLE Time;
MIL_INT32 NbFindDone;
MIL_INT32 Error;
} DataExchangeStruct;
#define PATTERN_MATCHING_LOOP_ERROR_CODE 2
MIL_INT MFTYPE ModelPositionningHook(MIL_INT HookType, MIL_ID EventId, void* DataExPtr);
MIL_INT MFTYPE GeometricPatternMatchingHook(MIL_INT HookType, MIL_ID EventId, void* DataExPtr);
MIL_INT MFTYPE GrayscalePatternMatchingHook(MIL_INT HookType, MIL_ID EventId, void* DataExPtr);
void MFTYPE SlavePatternMatchingLoop(MIL_ID Func)
{
MIL_ID MilDataExchangeBuffer;
long n;
DataExchangeStruct DataEx;
long *ErrorReturnValuePtr = M_NULL;
MfuncParamValue(Func, 1, &MilDataExchangeBuffer);
MbufGet(MilDataExchangeBuffer, &DataEx);
for( n=0; n<NB_TARGET_IMAGES; n++)
{
MbufAlloc2d(DataEx.MilSystem,
MdigInquire(DataEx.MilDigitizer, M_SIZE_X, M_NULL),
MdigInquire(DataEx.MilDigitizer, M_SIZE_Y, M_NULL),
8L+M_UNSIGNED,
M_IMAGE+M_GRAB+M_PROC, &DataEx.MilImage[n]);
}
DataEx.NbFindDone = 0;
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_START, M_ASYNCHRONOUS, ModelPositionningHook, &DataEx);
MthrWait(DataEx.MilModelPositionOkEvent, M_EVENT_WAIT, M_NULL);
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_STOP, M_SYNCHRONOUS, ModelPositionningHook, &DataEx);
MdigGrab(DataEx.MilDigitizer, DataEx.MilImage[0]);
#if (!M_MIL_LITE)
if (DataEx.PatternMatchingMethod == GEOMETRIC)
{
MmodAlloc(DataEx.MilSystem, M_GEOMETRIC, M_DEFAULT, &DataEx.MilModel);
MmodDefine(DataEx.MilModel, M_IMAGE, DataEx.MilImage[0],
(long)(MODEL_POS_X_INIT+0.5) - (MODEL_WIDTH/2) - 1,
(long)(MODEL_POS_Y_INIT+0.5) - (MODEL_HEIGHT/2) - 1,
MODEL_WIDTH, MODEL_HEIGHT);
MmodAllocResult(DataEx.MilSystem, M_DEFAULT, &DataEx.MilResult);
if ((DataEx.MilModel != M_NULL) && (DataEx.MilResult != M_NULL))
{
MmodControl(DataEx.MilModel, M_CONTEXT, M_NUMBER, 1);
MmodControl(DataEx.MilModel, M_CONTEXT, M_SPEED, M_VERY_HIGH);
MmodControl(DataEx.MilModel, M_CONTEXT, M_ACCURACY, M_MEDIUM);
MmodControl(DataEx.MilModel, M_ALL, M_ACCEPTANCE, MODEL_MIN_MATCH_SCORE);
MmodPreprocess(DataEx.MilModel, M_DEFAULT);
DataEx.Error = M_FALSE;
DataEx.NbFindDone = 0;
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_START, M_ASYNCHRONOUS, GeometricPatternMatchingHook, &DataEx);
MthrWait(DataEx.MilStopProcessingEvent, M_EVENT_WAIT, M_NULL);
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_STOP, M_SYNCHRONOUS, GeometricPatternMatchingHook, &DataEx);
}
else
{
MfuncErrorReport(Func, M_FUNC_ERROR+PATTERN_MATCHING_LOOP_ERROR_CODE,
MIL_TEXT("Error during target processing loop allocations."),
M_NULL, M_NULL, M_NULL
);
DataEx.Error = M_TRUE;
}
if (DataEx.MilResult != M_NULL) MmodFree(DataEx.MilResult);
if (DataEx.MilModel != M_NULL) MmodFree(DataEx.MilModel);
}
else
{
MpatAllocModel(DataEx.MilSystem, DataEx.MilImage[0],
(long)(MODEL_POS_X_INIT+0.5) - (MODEL_WIDTH/2) - 1,
(long)(MODEL_POS_Y_INIT+0.5) - (MODEL_HEIGHT/2) - 1,
MODEL_WIDTH, MODEL_HEIGHT,
M_NORMALIZED, &DataEx.MilModel);
MpatAllocResult(DataEx.MilSystem, 1L, &DataEx.MilResult);
if ((DataEx.MilModel != M_NULL) && (DataEx.MilResult != M_NULL))
{
MpatSetAcceptance(DataEx.MilModel,MODEL_MIN_MATCH_SCORE);
MpatSetSpeed(DataEx.MilModel,M_HIGH);
MpatSetAccuracy(DataEx.MilModel,M_LOW);
MpatPreprocModel(DataEx.MilImage[0], DataEx.MilModel, M_DEFAULT);
DataEx.Error = M_FALSE;
DataEx.NbFindDone = 0;
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_START, M_ASYNCHRONOUS, GrayscalePatternMatchingHook, &DataEx);
MthrWait(DataEx.MilStopProcessingEvent, M_EVENT_WAIT, M_NULL);
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_STOP, M_SYNCHRONOUS, GrayscalePatternMatchingHook, &DataEx);
}
else
{
MfuncErrorReport(Func, M_FUNC_ERROR+PATTERN_MATCHING_LOOP_ERROR_CODE,
MIL_TEXT("Error during target processing loop model allocations."),
M_NULL, M_NULL, M_NULL);
DataEx.Error = M_TRUE;
}
if (DataEx.MilResult != M_NULL) MpatFree(DataEx.MilResult);
if (DataEx.MilModel != M_NULL) MpatFree(DataEx.MilModel);
}
#endif
for( n=0; n<NB_TARGET_IMAGES; n++)
{
MbufFree(DataEx.MilImage[n]);
}
}
MIL_INT MFTYPE ModelPositionningHook(MIL_INT HookType, MIL_ID EventId, void* DataExVoidPtr)
{
DataExchangeStruct *DataExPtr = (DataExchangeStruct *)DataExVoidPtr;
MIL_ID GrabBufferId;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER+M_BUFFER_ID, &GrabBufferId);
MgraRect(M_DEFAULT, GrabBufferId,
(long)(MODEL_POS_X_INIT+0.5) - (MODEL_WIDTH/2) - 2,
(long)(MODEL_POS_Y_INIT+0.5) - (MODEL_HEIGHT/2) - 2,
(long)(MODEL_POS_X_INIT+0.5) + (MODEL_WIDTH/2) + 1,
(long)(MODEL_POS_Y_INIT+0.5) + (MODEL_HEIGHT/2) + 1);
MbufCopy(GrabBufferId, DataExPtr->MilImageDisp);
DataExPtr->NbFindDone++;
#if M_MIL_USE_CE
if(MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((DataExPtr->NbFindDone%10) == 0)
Sleep(2);
}
#endif
return (M_NULL);
}
#if (!M_MIL_LITE)
MIL_INT MFTYPE GeometricPatternMatchingHook(MIL_INT HookType, MIL_ID EventId, void* DataExVoidPtr)
{
DataExchangeStruct *DataExPtr = (DataExchangeStruct *)DataExVoidPtr;
MIL_ID GrabBufferId;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER+M_BUFFER_ID, &GrabBufferId);
if (DataExPtr->NbFindDone == 0)
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS, M_NULL);
MmodFind(DataExPtr->MilModel, GrabBufferId, DataExPtr->MilResult);
DataExPtr->NbFindDone++;
MmodGetResult(DataExPtr->MilResult, M_DEFAULT, M_NUMBER+M_TYPE_MIL_INT32, &DataExPtr->Found);
MmodGetResult(DataExPtr->MilResult, M_DEFAULT, M_POSITION_X, &DataExPtr->PosX);
MmodGetResult(DataExPtr->MilResult, M_DEFAULT, M_POSITION_Y, &DataExPtr->PosY);
MmodGetResult(DataExPtr->MilResult, M_DEFAULT, M_SCORE, &DataExPtr->Score);
if (DataExPtr->DisplayUpdateFlag)
{
if (DataExPtr->Found)
MmodDraw(M_DEFAULT, DataExPtr->MilResult, GrabBufferId,
M_DRAW_POSITION+M_DRAW_BOX, M_DEFAULT, M_DEFAULT);
else
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT, MIL_TEXT(" MODEL NOT FOUND ? "));
MbufCopy(GrabBufferId, DataExPtr->MilImageDisp);
}
MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &DataExPtr->Time);
MthrWait(DataExPtr->MilDataExchangeBufferReadyEvent, M_EVENT_WAIT, M_NULL);
MbufPut(DataExPtr->MilDataExchangeBuffer, DataExPtr);
#if M_MIL_USE_CE
if(MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((DataExPtr->NbFindDone%10) == 0)
Sleep(2);
}
#endif
return (M_NULL);
}
#endif
#if (!M_MIL_LITE)
MIL_INT MFTYPE GrayscalePatternMatchingHook(MIL_INT HookType, MIL_ID EventId, void* DataExVoidPtr)
{
DataExchangeStruct *DataExPtr = (DataExchangeStruct *)DataExVoidPtr;
MIL_ID GrabBufferId;
MIL_INT NbFound;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER+M_BUFFER_ID, &GrabBufferId);
if (DataExPtr->NbFindDone == 0)
MappTimer(M_DEFAULT, M_TIMER_RESET+M_SYNCHRONOUS, M_NULL);
MpatFindModel(GrabBufferId, DataExPtr->MilModel, DataExPtr->MilResult);
DataExPtr->NbFindDone++;
MpatGetNumber(DataExPtr->MilResult, &NbFound);
DataExPtr->Found = (MIL_INT32)NbFound;
MpatGetResult(DataExPtr->MilResult, M_POSITION_X, &DataExPtr->PosX);
MpatGetResult(DataExPtr->MilResult, M_POSITION_Y, &DataExPtr->PosY);
MpatGetResult(DataExPtr->MilResult, M_SCORE, &DataExPtr->Score);
if (DataExPtr->DisplayUpdateFlag)
{
if (DataExPtr->Found)
MpatDraw(M_DEFAULT, DataExPtr->MilResult, GrabBufferId,
M_DRAW_BOX+M_DRAW_POSITION, M_DEFAULT, M_DEFAULT);
else
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT, MIL_TEXT(" MODEL NOT FOUND ? "));
MbufCopy(GrabBufferId, DataExPtr->MilImageDisp);
}
MappTimer(M_DEFAULT, M_TIMER_READ+M_SYNCHRONOUS, &DataExPtr->Time);
MthrWait(DataExPtr->MilDataExchangeBufferReadyEvent, M_EVENT_WAIT, M_NULL);
MbufPut(DataExPtr->MilDataExchangeBuffer, DataExPtr);
#if M_MIL_USE_CE
if(MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((DataExPtr->NbFindDone%10) == 0)
Sleep(2);
}
#endif
return (M_NULL);
}
#endif