#include <mil.h>
#define HTTP_SERVER_PORT 9002L
#if M_MIL_USE_WINDOWS
#include <windows.h>
static HANDLE MdispWebClientHandle = NULL;
#else
static pid_t MdispWebClientHandle = 0;
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#endif
enum AppEnum {WEB_CLIENT=0, WEB_BROWSER, WEB_CSHARP_FORM, WEB_VB_FORM};
void LaunchApplication(AppEnum AppType);
void StartHttpServer(MIL_ID& HttpServerId);
#define MODEL_WIDTH 128L
#define MODEL_HEIGHT 128L
#define MODEL_POS_X_INIT(TargetImage) (MbufInquire(TargetImage, M_SIZE_X, M_NULL)/2)
#define MODEL_POS_Y_INIT(TargetImage) (MbufInquire(TargetImage, M_SIZE_Y, M_NULL)/2)
#define RECTANGLE_ANGLE 0
#define MODEL_MIN_MATCH_SCORE 50.0
#define DRAW_COLOR 0xFF
#define SELECTION_RADIUS 10
#define TEXT_SIZE 2048
struct SParameter
{
MIL_INT PosX;
MIL_INT PosY;
MIL_INT Width;
MIL_INT Height;
};
#define CONTINUE_MSG_TAG 99991
#define STOP_MSG_TAG 99992
#define QUIT_MSG_TAG 99993
static bool ContinueReceived = false;
static bool StopReceived = false;
static bool QuitReceived = false;
bool MmodTrackingExample(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDigitizer,
MIL_ID MilDisplayImage, MIL_ID MilModelImage, MIL_ID MilMessageOutput, struct SParameter *Data);
void GetModelImage(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDigitizer,
MIL_ID MilDisplayImage, MIL_ID MilModelImage, MIL_ID MilMessageOutput, struct SParameter *Data);
MIL_INT MFTYPE MessageReceiveHandler(MIL_INT HookType, MIL_ID EventId, void* HookDataPtr)
{
if (HookType == M_MESSAGE_RECEIVED)
{
MIL_INT64 MsgStatus = 0, MsgTag = 0;
MIL_INT MsgLength = 0;
MIL_ID MsgId = 0;
MobjGetHookInfo(EventId, M_OBJECT_ID, &MsgId);
MobjInquire(MsgId, M_MESSAGE_LENGTH, &MsgLength);
MIL_UINT8 *Data = new MIL_UINT8[MsgLength + 1];
memset(Data, 0, MsgLength + 1);
MobjMessageRead(MsgId, Data, MsgLength, M_NULL, &MsgTag, &MsgStatus, M_DEFAULT);
if(MsgTag == CONTINUE_MSG_TAG)
ContinueReceived = true;
else if(MsgTag == STOP_MSG_TAG)
StopReceived = true;
else if(MsgTag == QUIT_MSG_TAG)
QuitReceived = true;
delete [] Data;
}
return 0;
}
void WaitForContinue()
{
bool bContinue = true;
while (bContinue)
{
if(ContinueReceived)
{
bContinue = false;
ContinueReceived = false;
}
MosSleep(1);
}
}
int MosMain(void)
{
MIL_ID MilApplication,
MilSystem,
MilDisplay,
MilDigitizer,
MilDisplayImage,
MilMessageOutput,
MilMessageInput,
MilModelImage;
MIL_ID MilHttpServer = M_NULL;
SParameter DataParam;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, M_NULL,
&MilDigitizer, M_NULL);
if(MsysInquire(MilSystem, M_LOCATION, M_NULL) == M_REMOTE)
{
MosPrintf(MIL_TEXT("This example is not supported on a DMIL system (Distributed MIL)\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n"));
MosGetch();
MappFreeDefault(MilApplication, MilSystem, M_NULL, MilDigitizer, M_NULL);
return 0;
}
MappControl(M_DEFAULT, M_WEB_CONNECTION_PORT, 7682);
MappControl(M_DEFAULT, M_WEB_CONNECTION, M_LOSSY);
MIL_INT ImageSizeX = MdigInquire(MilDigitizer, M_SIZE_X, M_NULL);
MIL_INT ImageSizeY = MdigInquire(MilDigitizer, M_SIZE_Y, M_NULL);
MIL_INT SizeBand = MdigInquire(MilDigitizer, M_SIZE_BAND, M_NULL);
MdispAlloc(MilSystem, M_DEFAULT,MIL_TEXT("M_DEFAULT"),M_WEB, &MilDisplay);
MobjControl(MilDisplay, M_OBJECT_NAME, MIL_TEXT("Display"));
MobjControl(MilDisplay, M_WEB_PUBLISH, M_READ_ONLY);
MobjAlloc(MilSystem, M_MESSAGE_MAILBOX, M_OVERWRITE, &MilMessageOutput);
MobjControl( MilMessageOutput, M_OBJECT_NAME, MIL_TEXT("MessageOutput"));
MobjControl( MilMessageOutput, M_WEB_PUBLISH, M_READ_ONLY);
MobjAlloc(MilSystem, M_MESSAGE_MAILBOX, M_QUEUE, &MilMessageInput);
MobjControl( MilMessageInput, M_OBJECT_NAME, MIL_TEXT("MessageInput"));
MobjControl( MilMessageInput, M_WEB_PUBLISH, M_READ_WRITE);
MobjHookFunction( MilMessageInput, M_MESSAGE_RECEIVED, MessageReceiveHandler, M_NULL);
MbufAllocColor(MilSystem, SizeBand, ImageSizeX, ImageSizeY, 8, M_IMAGE+M_DISP+M_PROC+M_GRAB, &MilDisplayImage);
MdispSelect(MilDisplay, MilDisplayImage);
StartHttpServer(MilHttpServer);
LaunchApplication(WEB_BROWSER);
do
{
MbufAlloc2d(MilSystem,
MbufInquire(MilDisplayImage, M_SIZE_X, M_NULL),
MbufInquire(MilDisplayImage, M_SIZE_Y, M_NULL),
8, M_IMAGE+M_PROC, &MilModelImage);
MosPrintf(MIL_TEXT("\nMODEL TRACKING:\n"));
MosPrintf(MIL_TEXT("---------------\n\n"));
MosPrintf(MIL_TEXT("\n\n"));
MosPrintf(MIL_TEXT("This example demonstrates how to publish various MIL objects\nusing the MIL web API.\n"));
MosPrintf(MIL_TEXT("It also show how to interact with MIL display from a web browser.\n"));
MosPrintf(MIL_TEXT("The example execution is controlled from the web client.\n"));
bool Done = false;
do
{
GetModelImage(MilSystem, MilDisplay, MilDigitizer, MilDisplayImage, MilModelImage, MilMessageOutput, &DataParam);
Done = MmodTrackingExample(MilSystem, MilDisplay, MilDigitizer,MilDisplayImage, MilModelImage, MilMessageOutput, &DataParam);
} while (!Done);
MbufFree(MilModelImage);
MosPrintf(MIL_TEXT("Press a <Enter> to end the example.\n\n"));
} while(!QuitReceived && !MosKbhit());
MobjFree(MilHttpServer);
MbufFree(MilDisplayImage);
MdispFree(MilDisplay);
MobjFree(MilMessageOutput);
MobjFree(MilMessageInput);
MappFreeDefault(MilApplication, MilSystem, M_NULL, MilDigitizer, M_NULL);
return 0;
}
void GetModelImage(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDigitizer,
MIL_ID MilDisplayImage, MIL_ID MilModelImage, MIL_ID MilMessageOutput, struct SParameter *Data)
{
MIL_ID MilGraphicsList;
MIL_ID MilGraphicsContext;
MIL_DOUBLE DrawColor = DRAW_COLOR;
MgraAllocList(MilSystem, M_DEFAULT, &MilGraphicsList);
MgraControlList(MilGraphicsList, M_LIST, M_DEFAULT, M_SELECTION_RADIUS,
SELECTION_RADIUS);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicsList);
MgraAlloc(MilSystem, &MilGraphicsContext);
MdispControl(MilDisplay, M_GRAPHIC_LIST_INTERACTIVE, M_ENABLE);
Data->PosX = MODEL_POS_X_INIT(MilDisplayImage) - (MODEL_WIDTH/2);
Data->PosY = MODEL_POS_Y_INIT(MilDisplayImage) - (MODEL_HEIGHT/2);
Data->Width = MODEL_WIDTH;
Data->Height = MODEL_HEIGHT;
MgraRectAngle(MilGraphicsContext, MilGraphicsList, Data->PosX,
Data->PosY,
Data->Width,
Data->Height,
RECTANGLE_ANGLE,
M_DEFAULT);
MgraControlList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_GRAPHIC_SELECTED, M_TRUE);
MgraControlList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_ROTATABLE, M_DISABLE);
MgraControlList(MilGraphicsList, M_LIST, M_DEFAULT, M_SELECTION_RADIUS, 30.0);
char TextAscii[TEXT_SIZE];
memset(TextAscii, 0, TEXT_SIZE);
sprintf(TextAscii, "Model definition:\n\n"
"Place a unique model to find in the marked rectangle.\n"
"Then push the \"Continue\" button.\n"
);
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, CONTINUE_MSG_TAG, M_DEFAULT);
MdigGrabContinuous(MilDigitizer, MilDisplayImage);
WaitForContinue();
MdigHalt(MilDigitizer);
MbufCopy(MilDisplayImage, MilModelImage);
Data->PosX = MgraInquireList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_POSITION_X, M_NULL);
Data->PosY = MgraInquireList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_POSITION_Y, M_NULL);
Data->Width = MgraInquireList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_RECTANGLE_WIDTH, M_NULL);
Data->Height = MgraInquireList(MilGraphicsList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_RECTANGLE_HEIGHT, M_NULL);
MdispControl(MilDisplay, M_GRAPHIC_LIST_INTERACTIVE, M_DISABLE);
MgraFree(MilGraphicsContext);
MgraFree(MilGraphicsList);
}
#define MODEL_MAX_OCCURRENCES 16L
bool MmodTrackingExample(MIL_ID MilSystem, MIL_ID MilDisplay,
MIL_ID MilDigitizer, MIL_ID MilDisplayImage, MIL_ID MilModelImage, MIL_ID MilMessageOutput, struct SParameter *Data)
{
MIL_ID MilImage[2]={M_NULL,M_NULL},
SearchContext,
Result;
MIL_DOUBLE DrawColor = DRAW_COLOR;
MIL_INT Found;
MIL_INT NbFindDone = 0;
MIL_DOUBLE OrgX = 0.0, OrgY = 0.0;
MIL_DOUBLE Score[MODEL_MAX_OCCURRENCES],
x[MODEL_MAX_OCCURRENCES],
y[MODEL_MAX_OCCURRENCES],
Angle[MODEL_MAX_OCCURRENCES],
Scale[MODEL_MAX_OCCURRENCES];
MIL_DOUBLE Time = 0.0;
bool Done = true;
MbufCopy(MilModelImage, MilDisplayImage);
MmodAlloc(MilSystem, M_GEOMETRIC, M_DEFAULT, &SearchContext);
MmodDefine(SearchContext, M_IMAGE, MilModelImage,
(MIL_DOUBLE)Data->PosX,
(MIL_DOUBLE)Data->PosY,
(MIL_DOUBLE)Data->Width,
(MIL_DOUBLE)Data->Height);
MmodAllocResult(MilSystem, M_DEFAULT, &Result);
MgraColor(M_DEFAULT, DrawColor);
MmodDraw(M_DEFAULT, SearchContext, MilDisplayImage, M_DRAW_BOX, M_DEFAULT, M_ORIGINAL);
MmodControl(SearchContext, M_CONTEXT, M_SPEED, M_VERY_HIGH);
MmodControl(SearchContext, M_DEFAULT, M_ACCEPTANCE, MODEL_MIN_MATCH_SCORE);
MappControl(M_ERROR, M_PRINT_DISABLE);
MmodPreprocess(SearchContext, M_DEFAULT);
if(MappGetError(M_GLOBAL, 0) != M_NULL_ERROR)
{
Done = false;
goto end;
}
MappControl(M_ERROR, M_PRINT_ENABLE);
MmodInquire(SearchContext, M_DEFAULT, M_ORIGINAL_X, &OrgX);
MmodInquire(SearchContext, M_DEFAULT, M_ORIGINAL_Y, &OrgY);
char TextAscii[TEXT_SIZE];
memset(TextAscii, 0, TEXT_SIZE);
sprintf(TextAscii,"The Geometric target model was defined.\n"
"Model dimensions: %ld x %ld.\n"
"Model center: X=%.2f, Y=%.2f.\n"
"Model is scale and rotation independent.\n"
"Push \"Continue\" button to continue execution\n",
MODEL_WIDTH, MODEL_HEIGHT, OrgX, OrgY);
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, 2, M_DEFAULT);
WaitForContinue();
MbufAlloc2d(MilSystem,
MbufInquire(MilModelImage, M_SIZE_X, M_NULL),
MbufInquire(MilModelImage, M_SIZE_Y, M_NULL),
8,
M_IMAGE+M_GRAB+M_PROC,
&MilImage[0]);
MbufAlloc2d(MilSystem,
MbufInquire(MilModelImage, M_SIZE_X, M_NULL),
MbufInquire(MilModelImage, M_SIZE_Y, M_NULL),
8,
M_IMAGE+M_GRAB+M_PROC,
&MilImage[1]);
memset(TextAscii, 0, TEXT_SIZE);
sprintf(TextAscii,"\nContinuously finding the Geometric Model.\n"
"Push \"Restart\" to stop finding and restart the example.\n"
"Push \"Quit\" to end the example.\n");
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, 2, M_DEFAULT);
MdigControl(MilDigitizer, M_GRAB_MODE, M_ASYNCHRONOUS);
MdigGrab(MilDigitizer, MilImage[NbFindDone%2]);
MdigGrab(MilDigitizer, MilImage[NbFindDone%2]);
MappTimer(M_DEFAULT, M_TIMER_RESET, &Time);
do
{
MdigGrab(MilDigitizer, MilImage[(NbFindDone+1)%2]);
MappTimer(M_DEFAULT, M_TIMER_READ, &Time);
MmodFind(SearchContext, MilImage[NbFindDone%2], Result);
MmodGetResult(Result, M_DEFAULT, M_NUMBER+M_TYPE_MIL_INT, &Found);
if ( (Found >= 1) && (Found < MODEL_MAX_OCCURRENCES) )
{
MmodGetResult(Result, M_DEFAULT, M_POSITION_X, x);
MmodGetResult(Result, M_DEFAULT, M_POSITION_Y, y);
MmodGetResult(Result, M_DEFAULT, M_SCALE, Scale);
MmodGetResult(Result, M_DEFAULT, M_ANGLE, Angle);
MmodGetResult(Result, M_DEFAULT, M_SCORE, Score);
MmodDraw(M_DEFAULT, Result, MilImage[NbFindDone%2],
M_DRAW_BOX+M_DRAW_POSITION+M_DRAW_EDGES, M_DEFAULT, M_DEFAULT);
memset(TextAscii, 0, TEXT_SIZE);
sprintf(TextAscii,"Found: X=%6.1f, Y=%6.1f, Angle=%6.1f, Scale=%5.2f,Score=%5.1f%% (%5.1f fps).\n",
x[0], y[0], Angle[0], Scale[0], Score[0], (NbFindDone+1)/Time);
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, STOP_MSG_TAG, M_DEFAULT);
}
else
{
memset(TextAscii, 0, TEXT_SIZE);
sprintf(TextAscii, "Not found! (score<%5.1f%%) "
"(%5.1f fps).\n", MODEL_MIN_MATCH_SCORE, (NbFindDone+1)/Time);
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, STOP_MSG_TAG, M_DEFAULT);
}
MbufCopy(MilImage[NbFindDone%2], MilDisplayImage);
NbFindDone++;
}
while (!StopReceived && !QuitReceived);
memset(TextAscii, 0, TEXT_SIZE);
MobjMessageWrite(MilMessageOutput, (MIL_UINT8 *)TextAscii, TEXT_SIZE, STOP_MSG_TAG, M_DEFAULT);
StopReceived = false;
MosPrintf(MIL_TEXT("\n\n"));
end:
MdigGrabWait(MilDigitizer, M_GRAB_END);
MmodFree(Result);
MmodFree(SearchContext);
if(MilImage[1])
MbufFree(MilImage[1]);
if(MilImage[0])
MbufFree(MilImage[0]);
return Done;
}
void LaunchApplication(AppEnum AppType)
{
MIL_TEXT_CHAR Buffer[TEXT_SIZE];
memset(Buffer,0,TEXT_SIZE);
#if M_MIL_USE_LINUX
if(AppType == WEB_BROWSER)
{
if (access("/usr/bin/gio", X_OK) == 0)
MosSprintf(Buffer, TEXT_SIZE, MIL_TEXT("gio open http:
else
MosSprintf(Buffer, TEXT_SIZE, MIL_TEXT("xdg-open http:
system(Buffer);
}
else
{
MosPrintf(MIL_TEXT("Invalid application type !!!\n"));
}
#else
if(AppType == WEB_BROWSER)
{
MosSprintf(Buffer, TEXT_SIZE, MIL_TEXT("http:
ShellExecute(NULL, NULL, Buffer, NULL, NULL, SW_SHOWNORMAL);
}
else
{
MosPrintf(MIL_TEXT("Invalid application type !!!\n"));
}
#endif
}
void StartHttpServer(MIL_ID& HttpServerId)
{
MIL_TEXT_CHAR Buffer[TEXT_SIZE];
memset(Buffer,0,TEXT_SIZE);
MIL_STRING ExamplePath;
MappInquire(M_DEFAULT, M_MIL_DIRECTORY_EXAMPLES, ExamplePath);
HttpServerId = MobjAlloc(M_DEFAULT_HOST, M_HTTP_SERVER, M_DEFAULT, M_NULL);
MobjControl(HttpServerId, M_HTTP_PORT, HTTP_SERVER_PORT);
ExamplePath+=MIL_TEXT("Core/MdispWebClient/C++/html");
MobjControl(HttpServerId, M_HTTP_ROOT_DIRECTORY, ExamplePath);
MobjControl(HttpServerId, M_HTTP_START, M_DEFAULT);
}