#include <mil.h>
#include <vector>
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("CodeDetect\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This program creates a code reader context using the\n")
MIL_TEXT("automatically detected code types from a sample image.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: application, system, display, buffer,\n")
MIL_TEXT("graphic, code.\n\n"));
}
#define LARGE_SIZE_IMAGE_LIMIT 2000
#define MID_SIZE_IMAGE_LIMIT 700
#define LARGE_SIZE_IMAGE_ZOOM_FACTOR 0.25
#define MID_SIZE_IMAGE_ZOOM_FACTOR 0.5
#define SMALL_SIZE_IMAGE_ZOOM_FACTOR 1.0
#define TITLE_OFFSET_X 5
#define TITLE_OFFSET_Y 5
#define STRING_ELEMENT_OFFSET_Y 10
const MIL_INT NumberOfSampleImages = 4;
static MIL_CONST_TEXT_PTR ImageFilename[NumberOfSampleImages] =
{
M_IMAGE_PATH MIL_TEXT("CodeDetect/DetectExample_4codes.mim"),
M_IMAGE_PATH MIL_TEXT("CodeDetect/DetectExample_3codes.mim"),
M_IMAGE_PATH MIL_TEXT("CodeDetect/DetectExample_2codes.mim"),
M_IMAGE_PATH MIL_TEXT("CodeDetect/DetectExample_6codes.mim")
};
static const MIL_INT NumberOfBarCodesPerImage[NumberOfSampleImages] =
{4, 3, 2, 6};
class COverlay
{
public:
COverlay();
~COverlay();
void FreeMilObjects();
MIL_ID GetId() { return m_CurrentGraphicList; }
void Reset();
void SetTitle(MIL_CONST_TEXT_PTR TitleString);
MIL_ID GetBoundingBoxCtx() { return m_BoundingBoxGraCtx; }
void WriteTextElement(MIL_DOUBLE TextPosX, MIL_DOUBLE TextPosY, MIL_CONST_TEXT_PTR StringToWrite);
private:
MIL_ID m_TitleGraCtx;
MIL_ID m_CodeRelatedTextGraCtx;
MIL_ID m_BoundingBoxGraCtx;
MIL_ID m_CurrentGraphicList;
};
void PrepareDisplayAndAnnotation(MIL_ID MilSystem,
MIL_ID MilSrcImage,
MIL_ID MilDisplay);
void DetectCodes(MIL_ID SystemId,
MIL_ID Image,
MIL_INT NbBarCodeInImage,
std::vector<MIL_INT> ListOfCodeTypeToDetect,
MIL_ID &MilCodeResult,
std::vector<MIL_INT> &CodesDetectedType,
COverlay &DetectOverlay,
COverlay &ReadOverlay)
{
MIL_INT NbBarCodeDetected = 0;
MIL_INT CodeTypeStringSize = 0;
std::vector<MIL_TEXT_CHAR> CodeTypeString;
if(MilCodeResult != M_NULL)
{
McodeFree(MilCodeResult);
MilCodeResult = M_NULL;
}
if(MilCodeResult == M_NULL)
MilCodeResult = McodeAllocResult(SystemId, M_CODE_DETECT_RESULT, M_NULL);
MosPrintf(MIL_TEXT("Detecting code types..."));
DetectOverlay.SetTitle(MIL_TEXT("CODE TYPES DETECTION"));
McodeDetect(Image,
(MIL_INT)ListOfCodeTypeToDetect.size(),
&ListOfCodeTypeToDetect[0],
NbBarCodeInImage,
M_DEFAULT,
M_DEFAULT,
MilCodeResult);
MosPrintf(MIL_TEXT(" Done!\n\n"));
McodeGetResult(MilCodeResult, M_GENERAL, M_GENERAL, M_NUMBER + M_TYPE_MIL_INT, &NbBarCodeDetected);
MosPrintf(MIL_TEXT("%i barcodes detected on %i expected barcodes\n"), NbBarCodeDetected, NbBarCodeInImage);
if(NbBarCodeDetected > 0)
{
CodesDetectedType.resize(NbBarCodeDetected);
McodeGetResult(MilCodeResult, M_ALL, M_GENERAL, M_CODE_TYPE + M_TYPE_MIL_INT, &CodesDetectedType[0]);
for(MIL_INT jj = 0; jj < NbBarCodeDetected; jj++)
{
McodeDraw(DetectOverlay.GetBoundingBoxCtx(), MilCodeResult, DetectOverlay.GetId(), M_DRAW_BOX, jj, M_GENERAL, M_DEFAULT);
McodeGetResult(MilCodeResult, jj, M_GENERAL, M_CODE_TYPE_NAME + M_STRING_SIZE + M_TYPE_MIL_INT, &CodeTypeStringSize);
CodeTypeString.resize(CodeTypeStringSize);
McodeGetResult(MilCodeResult, jj, M_GENERAL, M_CODE_TYPE_NAME + M_TYPE_TEXT_CHAR, &CodeTypeString[0]);
MosPrintf(MIL_TEXT("Type detected: %s\n"), &CodeTypeString[0]);
double DrawPosX;
double DrawPosY;
McodeGetResult(MilCodeResult, jj, M_GENERAL, M_BOTTOM_RIGHT_X, &DrawPosX);
McodeGetResult(MilCodeResult, jj, M_GENERAL, M_BOTTOM_RIGHT_Y, &DrawPosY);
DrawPosY += STRING_ELEMENT_OFFSET_Y;
DetectOverlay.WriteTextElement(DrawPosX, DrawPosY, &CodeTypeString[0]);
ReadOverlay.WriteTextElement(DrawPosX, DrawPosY, &CodeTypeString[0]);
}
}
}
void ReadCodesAndOutputString(MIL_ID SystemId,
MIL_ID Image,
MIL_ID CodeContext,
COverlay &ReadOverlay)
{
MIL_INT SizeDecodedString = 0;
MIL_INT NumberCodesRead = 0;
std::vector<MIL_TEXT_CHAR> DecodedString;
MIL_ID ReadCodeResultId = McodeAllocResult(SystemId, M_DEFAULT, M_NULL);
McodeControl(CodeContext, M_NUMBER, M_ALL);
MosPrintf(MIL_TEXT("Reading codes..."));
ReadOverlay.SetTitle(MIL_TEXT("READING CODES"));
McodeRead(CodeContext, Image, ReadCodeResultId);
MosPrintf(MIL_TEXT(" Done!\n\n"));
McodeGetResult(ReadCodeResultId, M_GENERAL, M_GENERAL, M_NUMBER + M_TYPE_MIL_INT, &NumberCodesRead);
MosPrintf(MIL_TEXT("%i barcodes read\n"), NumberCodesRead);
for(MIL_INT jj = 0; jj < NumberCodesRead; jj++)
{
McodeDraw(ReadOverlay.GetBoundingBoxCtx(), ReadCodeResultId, ReadOverlay.GetId(), M_DRAW_BOX, jj, M_GENERAL, M_DEFAULT);
McodeGetResult(ReadCodeResultId, jj, M_GENERAL, M_STRING + M_STRING_SIZE + M_TYPE_MIL_INT, &SizeDecodedString);
DecodedString.resize(SizeDecodedString);
McodeGetResult(ReadCodeResultId, jj, M_GENERAL, M_STRING, &DecodedString[0]);
MosPrintf(MIL_TEXT("Decoded string: %s\n"), &DecodedString[0]);
double DrawPosX;
double DrawPosY;
McodeGetResult(ReadCodeResultId, jj, M_GENERAL, M_POSITION_X, &DrawPosX);
McodeGetResult(ReadCodeResultId, jj, M_GENERAL, M_POSITION_Y, &DrawPosY);
DrawPosY += STRING_ELEMENT_OFFSET_Y;
ReadOverlay.WriteTextElement(DrawPosX, DrawPosY, &DecodedString[0]);
}
McodeFree(ReadCodeResultId);
}
int MosMain()
{
MIL_ID MilApplication = MappAlloc(M_DEFAULT, M_NULL);
MIL_ID MilSystem = M_DEFAULT_HOST;
MIL_ID MilDisplay = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, M_NULL);
MIL_ID MilCodeContext = M_NULL;
MIL_ID MilCodeResult = M_NULL;
MilCodeResult = McodeAllocResult(MilSystem, M_CODE_DETECT_RESULT, M_NULL);
MilCodeContext = McodeAlloc(MilSystem, M_DEFAULT, M_DEFAULT, M_NULL);
std::vector<MIL_INT> CodesDetectedType;
COverlay DetectOverlay;
COverlay ReadOverlay;
std::vector<MIL_INT> ListOfCodeTypes[NumberOfSampleImages];
ListOfCodeTypes[0].push_back(M_SUPPORTED_CODE_TYPES_DETECT);
ListOfCodeTypes[1].push_back(M_SUPPORTED_CODE_TYPES_DETECT);
ListOfCodeTypes[2].push_back(M_CODE39);
ListOfCodeTypes[2].push_back(M_CODE93);
ListOfCodeTypes[2].push_back(M_CODE128);
ListOfCodeTypes[2].push_back(M_EAN13);
ListOfCodeTypes[3].push_back(M_SUPPORTED_CODE_TYPES_DETECT);
PrintHeader();
MosPrintf(MIL_TEXT("Starting automatic code type detection:\n\n"));
for (MIL_INT ii = 0; ii < NumberOfSampleImages; ii++)
{
MIL_ID MilSrcImage = MbufRestore(ImageFilename[ii], MilSystem, M_NULL);
MosPrintf(MIL_TEXT("Image %i\n\n"), ii);
DetectOverlay.Reset();
ReadOverlay.Reset();
PrepareDisplayAndAnnotation(MilSystem, MilSrcImage, MilDisplay);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, DetectOverlay.GetId());
CodesDetectedType.clear();
DetectCodes(MilSystem, MilSrcImage, NumberOfBarCodesPerImage[ii], ListOfCodeTypes[ii], MilCodeResult, CodesDetectedType, DetectOverlay, ReadOverlay);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("Populating a context from the detected code types..."));
if(MilCodeContext != M_NULL)
{
McodeModel(MilCodeContext, M_RESET_FROM_DETECTED_RESULTS, M_NULL, M_ALL, MilCodeResult, M_NULL);
}
MosPrintf(MIL_TEXT(" Done!\n\n"));
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, ReadOverlay.GetId());
ReadCodesAndOutputString(MilSystem, MilSrcImage, MilCodeContext, ReadOverlay);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MbufFree(MilSrcImage);
}
MosPrintf(MIL_TEXT("\nPress <Enter> to terminate.\n\n"));
MosGetch();
DetectOverlay.FreeMilObjects();
ReadOverlay.FreeMilObjects();
MdispFree(MilDisplay);
if(MilCodeResult != M_NULL)
McodeFree(MilCodeResult);
if(MilCodeContext != M_NULL)
McodeFree(MilCodeContext);
if (MilSystem != M_DEFAULT_HOST)
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
void PrepareDisplayAndAnnotation(MIL_ID MilSystem,
MIL_ID MilSrcImage,
MIL_ID MilDisplay)
{
MIL_INT SrcSizeX, SrcSizeY;
MbufInquire(MilSrcImage, M_SIZE_X, &SrcSizeX);
MbufInquire(MilSrcImage, M_SIZE_Y, &SrcSizeY);
if (SrcSizeX > LARGE_SIZE_IMAGE_LIMIT && SrcSizeY > LARGE_SIZE_IMAGE_LIMIT)
{
MdispZoom(MilDisplay, LARGE_SIZE_IMAGE_ZOOM_FACTOR, LARGE_SIZE_IMAGE_ZOOM_FACTOR);
}
else if(SrcSizeX > MID_SIZE_IMAGE_LIMIT && SrcSizeY > MID_SIZE_IMAGE_LIMIT)
{
MdispZoom(MilDisplay, MID_SIZE_IMAGE_ZOOM_FACTOR, MID_SIZE_IMAGE_ZOOM_FACTOR);
}
else
{
MdispZoom(MilDisplay, SMALL_SIZE_IMAGE_ZOOM_FACTOR, SMALL_SIZE_IMAGE_ZOOM_FACTOR);
}
MdispSelect(MilDisplay, MilSrcImage);
MdispControl(MilDisplay, M_OVERLAY, M_ENABLE);
MdispControl(MilDisplay, M_OVERLAY_CLEAR, M_DEFAULT);
}
COverlay::COverlay()
{
m_CurrentGraphicList = MgraAllocList(M_DEFAULT_HOST, M_DEFAULT, M_NULL);
m_TitleGraCtx = MgraAlloc(M_DEFAULT_HOST, M_NULL);
m_CodeRelatedTextGraCtx = MgraAlloc(M_DEFAULT_HOST, M_NULL);
m_BoundingBoxGraCtx = MgraAlloc(M_DEFAULT_HOST, M_NULL);
MgraColor(m_TitleGraCtx, M_COLOR_CYAN);
MgraBackColor(m_TitleGraCtx, M_COLOR_GRAY);
MgraControl(m_TitleGraCtx, M_TEXT_ALIGN_HORIZONTAL, M_LEFT);
MgraColor(m_CodeRelatedTextGraCtx, M_COLOR_CYAN);
MgraBackColor(m_CodeRelatedTextGraCtx, M_COLOR_GRAY);
MgraControl(m_CodeRelatedTextGraCtx, M_TEXT_ALIGN_HORIZONTAL, M_CENTER);
MgraColor(m_BoundingBoxGraCtx, M_COLOR_GREEN);
}
COverlay::~COverlay()
{
FreeMilObjects();
}
void COverlay::FreeMilObjects()
{
if(m_CurrentGraphicList)
{
MgraFree(m_CurrentGraphicList);
m_CurrentGraphicList = M_NULL;
}
if(m_TitleGraCtx)
{
MgraFree(m_TitleGraCtx);
m_TitleGraCtx = M_NULL;
}
if(m_CodeRelatedTextGraCtx)
{
MgraFree(m_CodeRelatedTextGraCtx);
m_CodeRelatedTextGraCtx = M_NULL;
}
if(m_BoundingBoxGraCtx)
{
MgraFree(m_BoundingBoxGraCtx);
m_BoundingBoxGraCtx = M_NULL;
}
}
void COverlay::Reset()
{
if(m_CurrentGraphicList)
MgraClear(M_DEFAULT, m_CurrentGraphicList);
}
void COverlay::SetTitle(MIL_CONST_TEXT_PTR TitleString)
{
MgraText(m_TitleGraCtx, m_CurrentGraphicList, TITLE_OFFSET_X, TITLE_OFFSET_Y, TitleString);
}
void COverlay::WriteTextElement(MIL_DOUBLE TextPosX, MIL_DOUBLE TextPosY, MIL_CONST_TEXT_PTR StringToWrite)
{
MgraText(m_CodeRelatedTextGraCtx, m_CurrentGraphicList, TextPosX, TextPosY, StringToWrite);
}