#include <mil.h>
#include "..\DMILprocessingMaster\DMILprocessing.h"
#define MODEL_WIDTH 128L
#define MODEL_HEIGHT 128L
#define MODEL_POS_X_INIT 320L
#define MODEL_POS_Y_INIT 240L
#define MODEL_NB_OF_OCCURENCE 1L
#define MODEL_MIN_FOUND_SCORE 50.0
#define MODEL_MIN_PASS_SCORE 70.0
#define MODEL_ANGLE_DELTA_ANGLE 10
#define MODEL_ANGLE_DELTA_POS MODEL_ANGLE_DELTA_ANGLE
#define MODEL_ANGLE_DELTA_NEG MODEL_ANGLE_DELTA_ANGLE
#define MODEL_ANGLE_ANGLE_STEP 2
#define MODEL_ANGLE_MIN_ACCURACY 2.00
#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 SlaveProcessingLoop(MIL_ID Func);
#ifdef __cplusplus
}
#endif
#define PROCESSING_LOOP_ERROR_CODE 2
MIL_INT MFTYPE PreprocessingHook(MIL_INT HookType, MIL_ID EventId, void* DataExPtr);
MIL_INT MFTYPE ProcessingHook(MIL_INT HookType, MIL_ID EventId, void* DataExPtr);
void SetExternalIOState(MIL_INT Operation, DataExchangeStruct *DataExPtr);
#define IO_INITIALIZE 1
#define IO_SET 2
#define IO_CLOSE 3
void MFTYPE SlaveProcessingLoop(MIL_ID Func)
{
MIL_ID MilDataExchangeBuffer;
DataExchangeStruct DataEx;
MIL_INT Iter;
MfuncParamValue(Func, 1, &MilDataExchangeBuffer);
MbufGet(MilDataExchangeBuffer, &DataEx);
if (DataEx.IoUpdateFlag)
SetExternalIOState(IO_INITIALIZE, &DataEx);
for (Iter = 0; Iter < NB_TARGET_IMAGES; Iter++)
{
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[Iter]);
}
MbufPut(DataEx.MilDataExchangeBuffer, &DataEx);
DataEx.NbGrabDone = 0;
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_START, M_ASYNCHRONOUS, PreprocessingHook, &DataEx);
MthrWait(DataEx.MilPreprocessingStopEvent, M_EVENT_WAIT, M_NULL);
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_STOP, M_SYNCHRONOUS, PreprocessingHook, &DataEx);
MthrControl(DataEx.MilDataExchangeBufferAvailableEvent, M_EVENT_SET, M_SIGNALED);
MthrWait(DataEx.MilStartProcessingEvent, M_EVENT_WAIT, M_NULL);
MbufGet(DataEx.MilDataExchangeBuffer, &DataEx);
DataEx.NbProcessingDone = 0;
DataEx.Found = 0;
DataEx.FrameMissed = 0;
DataEx.ProcessingTimeExceededCount = 0;
DataEx.ProcessingTimeVariationAverage = 0;
DataEx.ProcessingTimeExceededMax = 0;
DataEx.ProcessingTimeVariationCurrent = 0;
DataEx.Error = M_FALSE;
if (DataEx.ProcessingMethod == PATTERN_MATCHING)
{
MpatAllocModel(DataEx.MilSystem, DataEx.MilImage[0],
(MIL_INT)(MODEL_POS_X_INIT + 0.5) - (MODEL_WIDTH / 2) - 1,
(MIL_INT)(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))
{
MpatSetNumber(DataEx.MilModel, MODEL_NB_OF_OCCURENCE);
MpatSetAcceptance(DataEx.MilModel, MODEL_MIN_FOUND_SCORE);
MpatSetSpeed(DataEx.MilModel, M_HIGH);
MpatSetAccuracy(DataEx.MilModel, M_LOW);
MpatSetAngle(DataEx.MilModel, M_SEARCH_ANGLE_DELTA_NEG, MODEL_ANGLE_DELTA_NEG);
MpatSetAngle(DataEx.MilModel, M_SEARCH_ANGLE_DELTA_POS, MODEL_ANGLE_DELTA_POS);
MpatSetAngle(DataEx.MilModel, M_SEARCH_ANGLE_ACCURACY, MODEL_ANGLE_MIN_ACCURACY);
MpatPreprocModel(DataEx.MilImage[0], DataEx.MilModel, M_DEFAULT);
}
else
{
DataEx.Error = M_TRUE;
MfuncErrorReport(Func, M_FUNC_ERROR + PROCESSING_LOOP_ERROR_CODE,
MIL_TEXT("Error during target processing loop model allocations."),
M_NULL, M_NULL, M_NULL);
}
}
else
{
if (PROCESSING_TYPE != BINARIZATION)
{
DataEx.Error = M_TRUE;
MfuncErrorReport(Func, M_FUNC_ERROR + PROCESSING_LOOP_ERROR_CODE,
MIL_TEXT("No known processing Specified."),
M_NULL, M_NULL, M_NULL);
}
}
if (DataEx.Error == M_FALSE)
{
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_START, M_ASYNCHRONOUS, ProcessingHook, &DataEx);
MthrWait(DataEx.MilStopProcessingEvent, M_EVENT_WAIT, M_NULL);
MdigProcess(DataEx.MilDigitizer, DataEx.MilImage, NB_TARGET_IMAGES,
M_STOP, M_SYNCHRONOUS, ProcessingHook, &DataEx);
}
else
{
MbufPut(DataEx.MilDataExchangeBuffer, &DataEx);
MthrControl(DataEx.MilDataExchangeBufferAvailableEvent, M_EVENT_SET, M_SIGNALED);
}
if (DataEx.ProcessingMethod == PATTERN_MATCHING)
{
if (DataEx.MilResult != M_NULL) MpatFree(DataEx.MilResult);
if (DataEx.MilModel != M_NULL) MpatFree(DataEx.MilModel);
}
if (DataEx.IoUpdateFlag)
SetExternalIOState(IO_CLOSE, &DataEx);
}
MIL_INT MFTYPE PreprocessingHook(MIL_INT HookType, MIL_ID EventId, void* DataExVoidPtr)
{
DataExchangeStruct *DataExPtr = (DataExchangeStruct *)DataExVoidPtr;
MIL_ID GrabBufferId;
if (DataExPtr->NbGrabDone == 0)
MappTimer(M_DEFAULT, M_TIMER_RESET, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &DataExPtr->Time);
DataExPtr->FrameRate = (MIL_DOUBLE)DataExPtr->NbGrabDone / DataExPtr->Time;
DataExPtr->NbGrabDone++;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER + M_BUFFER_ID, &GrabBufferId);
if (DataExPtr->ProcessingMethod == PATTERN_MATCHING)
{
MgraRect(M_DEFAULT, GrabBufferId,
(MIL_INT)(MODEL_POS_X_INIT + 0.5) - (MODEL_WIDTH / 2) - 2,
(MIL_INT)(MODEL_POS_Y_INIT + 0.5) - (MODEL_HEIGHT / 2) - 2,
(MIL_INT)(MODEL_POS_X_INIT + 0.5) + (MODEL_WIDTH / 2) + 1,
(MIL_INT)(MODEL_POS_Y_INIT + 0.5) + (MODEL_HEIGHT / 2) + 1);
}
else
{
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT, MIL_TEXT("<<<< LIVE IMAGE >>>>"));
}
MbufCopy(GrabBufferId, DataExPtr->MilImageDisp);
MbufPut(DataExPtr->MilDataExchangeBuffer, DataExPtr);
if (MappGetError(M_DEFAULT, M_CURRENT, M_NULL))
DataExPtr->Error = M_TRUE;
else
DataExPtr->Error = M_FALSE;
#if M_MIL_USE_CE
if(MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((DataExPtr->NbProcessingDone%10) == 0)
Sleep(2);
}
#endif
return (M_NULL);
}
MIL_INT MFTYPE ProcessingHook(MIL_INT HookType, MIL_ID EventId, void* DataExVoidPtr)
{
DataExchangeStruct *DataExPtr = (DataExchangeStruct *)DataExVoidPtr;
MIL_ID GrabBufferId;
MIL_INT NbFound, PreviousFrameMissed, Threshold;
MIL_DOUBLE PreviousTime = 0;
MdigGetHookInfo(EventId, M_MODIFIED_BUFFER + M_BUFFER_ID, &GrabBufferId);
if (DataExPtr->NbProcessingDone == 0)
{
MappTimer(M_DEFAULT, M_TIMER_RESET, M_NULL);
MappTimer(M_DEFAULT, M_TIMER_READ, &DataExPtr->Time);
}
else
{
PreviousTime = DataExPtr->Time;
MappTimer(M_DEFAULT, M_TIMER_READ, &DataExPtr->Time);
DataExPtr->ProcessingTimeVariationCurrent = (DataExPtr->Time - PreviousTime) -
(1 / DataExPtr->FrameRate);
if (DataExPtr->ProcessingTimeVariationCurrent < 0)
DataExPtr->ProcessingTimeVariationCurrent = 0;
if (DataExPtr->ProcessingTimeVariationCurrent > DataExPtr->ProcessingTimeExceededMax)
DataExPtr->ProcessingTimeExceededMax = DataExPtr->ProcessingTimeVariationCurrent;
DataExPtr->ProcessingTimeVariationAverage =
((DataExPtr->ProcessingTimeVariationAverage * (DataExPtr->NbProcessingDone)) +
DataExPtr->ProcessingTimeVariationCurrent) / (DataExPtr->NbProcessingDone + 1);
if (DataExPtr->ProcessingTimeVariationCurrent > DataExPtr->MaxJitterAllowed)
{
DataExPtr->Late = M_TRUE;
DataExPtr->ProcessingTimeExceededCount++;
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT - 120, MODEL_POS_Y_INIT + 100,
MIL_TEXT("<<<< WARNING: PROCESSING WAS LATE >>>>"));
}
else
{
DataExPtr->Late = M_FALSE;
}
}
PreviousFrameMissed = DataExPtr->FrameMissed;
MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_FRAME_MISSED, &DataExPtr->FrameMissed);
if (DataExPtr->FrameMissed > PreviousFrameMissed)
{
DataExPtr->Late = M_TRUE;
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT - 120, MODEL_POS_Y_INIT + 150,
MIL_TEXT("<<<< WARNING: FRAME WAS MISSED >>>>"));
}
if (DataExPtr->ProcessingMethod == PATTERN_MATCHING)
{
MpatFindModel(GrabBufferId, DataExPtr->MilModel, DataExPtr->MilResult);
DataExPtr->NbProcessingDone++;
MpatGetNumber(DataExPtr->MilResult, &NbFound);
DataExPtr->Found = NbFound;
MpatGetResult(DataExPtr->MilResult, M_POSITION_X, &DataExPtr->PosX);
MpatGetResult(DataExPtr->MilResult, M_POSITION_Y, &DataExPtr->PosY);
MpatGetResult(DataExPtr->MilResult, M_SCORE, &DataExPtr->Score);
}
else
{
Threshold = MimBinarize(GrabBufferId, M_NULL, M_BIMODAL + M_GREATER, M_NULL, M_NULL);
MimBinarize(GrabBufferId, GrabBufferId, M_BIMODAL + M_GREATER, M_NULL, M_NULL);
MgraText(M_DEFAULT, GrabBufferId,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT, MIL_TEXT("<<<< BINARIZED IMAGE >>>>"));
DataExPtr->NbProcessingDone++;
if (Threshold <= 128)
DataExPtr->Score = (MIL_DOUBLE)(Threshold * 100) / 128;
else
DataExPtr->Score = (MIL_DOUBLE)((255-Threshold) * 100) / 128;
if (DataExPtr->Score > 50)
DataExPtr->Found = 1;
else
DataExPtr->Found = 0;
}
if (DataExPtr->Found)
{
if (DataExPtr->Score > MODEL_MIN_PASS_SCORE)
DataExPtr->Status = PASS;
else
DataExPtr->Status = WARNING;
}
else
DataExPtr->Status = FAIL;
if (DataExPtr->IoUpdateFlag)
SetExternalIOState(IO_SET, DataExPtr);
if (MthrInquire(DataExPtr->MilDataExchangeBufferProcessedEvent, M_EVENT_STATE, M_NULL)
== M_SIGNALED)
{
MthrControl(DataExPtr->MilDataExchangeBufferProcessedEvent, M_EVENT_SET, M_NOT_SIGNALED);
MbufPut(DataExPtr->MilDataExchangeBuffer, DataExPtr);
if (DataExPtr->DisplayUpdateFlag)
{
MbufCopy(GrabBufferId, DataExPtr->MilImageResult);
if (DataExPtr->ProcessingMethod == PATTERN_MATCHING)
{
if (DataExPtr->Found)
MpatDraw(M_DEFAULT, DataExPtr->MilResult, DataExPtr->MilImageResult,
M_DRAW_BOX + M_DRAW_POSITION, M_DEFAULT, M_DEFAULT);
else
MgraText(M_DEFAULT, DataExPtr->MilImageResult,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT, MIL_TEXT(" MODEL NOT FOUND ? "));
}
else
{
if (!DataExPtr->Found)
MgraText(M_DEFAULT, DataExPtr->MilImageResult,
MODEL_POS_X_INIT, MODEL_POS_Y_INIT + 50, MIL_TEXT(" BAD CONTRAST ? "));
}
}
MthrControl(DataExPtr->MilDataExchangeBufferAvailableEvent, M_EVENT_SET, M_SIGNALED);
}
if (MappGetError(M_DEFAULT, M_GLOBAL, M_NULL))
DataExPtr->Error = M_TRUE;
else
DataExPtr->Error = M_FALSE;
#if M_MIL_USE_CE
if(MdigInquire(DataExPtr->MilDigitizer, M_PROCESS_PENDING_GRAB_NUM, M_NULL) <= 1)
{
if ((DataExPtr->NbProcessingDone%10) == 0)
Sleep(2);
}
#endif
return (M_NULL);
}
void SetExternalIOState(MIL_INT Operation, DataExchangeStruct *DataExPtr)
{
#if (IO_UPDATE == M_YES)
if (DataExPtr->IoUpdateFlag)
{
if (Operation == IO_INITIALIZE)
{
;
}
if (Operation == IO_SET)
{
if (DataExPtr->Status == M_PASS)
{
;
}
else
if (DataExPtr->Status == M_WARNING)
{
;
}
else
{
if (DataExPtr->Status == M_FAIL)
{
;
}
}
if (DataExPtr->Late == M_TRUE)
{
;
}
}
if (Operation == IO_CLOSE)
{
;
}
}
#endif
}