#include <mil.h>
#include <math.h>
#define IMAGE_FILE_CONNECTOR M_IMAGE_PATH MIL_TEXT("Preprocessing/Connector.tif")
#define IMAGE_FILE_DEPTHMAP M_IMAGE_PATH MIL_TEXT("Preprocessing/DepthMap.mim")
const MIL_INT STRUCT_ELEM_WIDTH = 5,
STRUCT_ELEM_HEIGHT = 1,
STRUCT_ELEM_SIZE = 5,
STRUCT_ELEM_RADIUS = 5,
STRUCT_ELEM_DEPTH = 32;
const MIL_INT32 WEIGHTED_STRUCT_ELEM_ARR[STRUCT_ELEM_SIZE][STRUCT_ELEM_SIZE] =
{{ M_DONT_CARE, 0, 0, 0, M_DONT_CARE },
{ 0, 2, 1, 2, 0 },
{ 0, 1, 3, 1, 0 },
{ 0, 2, 1, 2, 0 },
{ M_DONT_CARE, 0, 0, 0, M_DONT_CARE }
};
const MIL_INT ITERATIONS = 3;
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("MimMorphic\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This program shows the use of multiple custom structuring\n")
MIL_TEXT("elements to perform morphological operations.\n")
MIL_TEXT("This example also demonstrates how to use MIL_UNIQUE_ID.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: application, system, display, buffer,\n")
MIL_TEXT("image processing.\n\n"));
}
MIL_UNIQUE_BUF_ID AllocateCustomStructElem(MIL_ID MilSystem);
MIL_UNIQUE_BUF_ID AllocateRectangularStructElem(MIL_ID MilSystem);
MIL_UNIQUE_BUF_ID AllocateCircularStructElem(MIL_ID MilSystem);
MIL_UNIQUE_BUF_ID AllocateSphericStructElem(MIL_ID MilSystem);
int MosMain(void)
{
MIL_UNIQUE_APP_ID MilApplication;
MIL_UNIQUE_SYS_ID MilSystem;
MIL_UNIQUE_DISP_ID MilDisplay;
MIL_INT SizeX, SizeY, Type;
MappAllocDefault(M_DEFAULT, &MilApplication, &MilSystem, &MilDisplay, M_NULL, M_NULL);
PrintHeader();
auto MilSrcImgConnector = MbufRestore(IMAGE_FILE_CONNECTOR, MilSystem, M_UNIQUE_ID);
MdispSelect(MilDisplay, MilSrcImgConnector);
MbufInquire(MilSrcImgConnector, M_SIZE_X, &SizeX);
MbufInquire(MilSrcImgConnector, M_SIZE_Y, &SizeY);
MbufInquire(MilSrcImgConnector, M_TYPE, &Type);
auto MilDstImgConnector = MbufAlloc2d(M_DEFAULT, SizeX, SizeY, Type,
M_IMAGE + M_PROC + M_DISP, M_UNIQUE_ID);
MosPrintf(MIL_TEXT("Erosion operation using custom structuring elements:\n"));
MosPrintf(MIL_TEXT("---------------------------------------------------\n"));
MosPrintf(MIL_TEXT("Image of an object has been restored.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
auto MilCustomStructElem = AllocateCustomStructElem(MilSystem);
MimMorphic(MilSrcImgConnector, MilDstImgConnector, MilCustomStructElem,
M_ERODE, ITERATIONS, M_GRAYSCALE);
MdispSelect(MilDisplay, MilDstImgConnector);
MosPrintf(MIL_TEXT("An erosion operation has been applied to the source\n"));
MosPrintf(MIL_TEXT("image using a 5x5 weighted structuring element.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
auto MilHorizontalStructElem = AllocateRectangularStructElem(MilSystem);
MimMorphic(MilSrcImgConnector, MilDstImgConnector, MilHorizontalStructElem,
M_ERODE, ITERATIONS, M_GRAYSCALE);
MdispSelect(MilDisplay, MilDstImgConnector);
MosPrintf(MIL_TEXT("An erosion operation has been applied to the source\n"));
MosPrintf(MIL_TEXT("image using a horizontal structuring element.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("Closing operation using custom structuring elements:\n"));
MosPrintf(MIL_TEXT("---------------------------------------------------\n"));
auto MilSrcImgDepthMap = MbufRestore(IMAGE_FILE_DEPTHMAP, MilSystem, M_UNIQUE_ID);
MdispControl(MilDisplay, M_VIEW_MODE, M_AUTO_SCALE);
MdispSelect(MilDisplay, MilSrcImgDepthMap);
MosPrintf(MIL_TEXT("Depth map of a surface has been restored.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MbufInquire(MilSrcImgDepthMap, M_SIZE_X, &SizeX);
MbufInquire(MilSrcImgDepthMap, M_SIZE_Y, &SizeY);
MbufInquire(MilSrcImgDepthMap, M_TYPE, &Type);
auto MilDstImgDepthMap = MbufAlloc2d(M_DEFAULT, SizeX, SizeY, 16 + M_UNSIGNED,
M_IMAGE + M_PROC + M_DISP, M_UNIQUE_ID);
auto MilCircularStructElem = AllocateCircularStructElem(MilSystem);
MbufClear(MilDstImgDepthMap, 0);
MimMorphic(MilSrcImgDepthMap, MilDstImgDepthMap, MilCircularStructElem, M_CLOSE, ITERATIONS,
M_GRAYSCALE);
MdispSelect(MilDisplay, MilDstImgDepthMap);
MosPrintf(MIL_TEXT("A closing operation has been applied to the source\n"));
MosPrintf(MIL_TEXT("image using a circular structuring element.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
auto MilSphericStructElem = AllocateSphericStructElem(MilSystem);
MbufClear(MilDstImgDepthMap, 0);
MimMorphic(MilSrcImgDepthMap, MilDstImgDepthMap, MilSphericStructElem, M_CLOSE, ITERATIONS,
M_GRAYSCALE);
MdispSelect(MilDisplay, MilDstImgDepthMap);
MosPrintf(MIL_TEXT("A closing operation has been applied to the source\n"));
MosPrintf(MIL_TEXT("image using a spheric structuring element (Rolling Ball).\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to finish.\n\n"));
MosGetch();
return 0;
}
MIL_UNIQUE_BUF_ID AllocateCustomStructElem(MIL_ID MilSystem)
{
auto MilCustomStructElem = MbufAlloc2d(MilSystem, STRUCT_ELEM_SIZE, STRUCT_ELEM_SIZE,
STRUCT_ELEM_DEPTH + M_SIGNED, M_STRUCT_ELEMENT, M_UNIQUE_ID);
MbufPut2d(MilCustomStructElem, 0L, 0L, STRUCT_ELEM_SIZE, STRUCT_ELEM_SIZE,
WEIGHTED_STRUCT_ELEM_ARR);
return MilCustomStructElem;
}
MIL_UNIQUE_BUF_ID AllocateRectangularStructElem(MIL_ID MilSystem)
{
auto MilRectangularStructElem = MbufAlloc2d(MilSystem, STRUCT_ELEM_WIDTH, STRUCT_ELEM_HEIGHT,
STRUCT_ELEM_DEPTH + M_UNSIGNED, M_STRUCT_ELEMENT,
M_UNIQUE_ID);
MbufClear(MilRectangularStructElem, 0);
return MilRectangularStructElem;
}
MIL_UNIQUE_BUF_ID AllocateCircularStructElem(MIL_ID MilSystem)
{
MIL_INT BufSize = (2 * STRUCT_ELEM_RADIUS) + 1;
MIL_UINT32 *CircleData = new MIL_UINT32[BufSize*BufSize];
MIL_INT DataIndex = 0;
MIL_ID MilCircularStruct = M_NULL;
MIL_INT SquaredCircleRadius = STRUCT_ELEM_RADIUS * STRUCT_ELEM_RADIUS;
MIL_INT SquaredY = 0;
for(MIL_INT y = -STRUCT_ELEM_RADIUS; y <= STRUCT_ELEM_RADIUS; y++)
{
SquaredY = y * y;
for(MIL_INT x = -STRUCT_ELEM_RADIUS; x <= STRUCT_ELEM_RADIUS; x++)
{
if(x * x + SquaredY <= SquaredCircleRadius)
{
CircleData[DataIndex] = 0;
}
else
CircleData[DataIndex] = M_DONT_CARE;
DataIndex++;
}
}
auto MilCircularStructElem = MbufAlloc2d(MilSystem, BufSize, BufSize,
STRUCT_ELEM_DEPTH + M_UNSIGNED,
M_STRUCT_ELEMENT, M_UNIQUE_ID);
MbufPut2d(MilCircularStructElem, 0, 0, BufSize, BufSize, CircleData);
delete[] CircleData;
return MilCircularStructElem;
}
MIL_UNIQUE_BUF_ID AllocateSphericStructElem(MIL_ID MilSystem)
{
MIL_INT BufSize = (2 * STRUCT_ELEM_RADIUS) + 1;
MIL_UINT32 *SphereData = new MIL_UINT32[BufSize * BufSize];
MIL_INT DataIndex = 0;
MIL_INT SquaredRadius = STRUCT_ELEM_RADIUS * STRUCT_ELEM_RADIUS;
MIL_INT SquaredZ = 0;
MIL_INT SquaredY = 0;
for(MIL_INT y = -STRUCT_ELEM_RADIUS; y <= STRUCT_ELEM_RADIUS; y++)
{
SquaredY = y * y;
for(MIL_INT x = -STRUCT_ELEM_RADIUS; x <= STRUCT_ELEM_RADIUS; x++)
{
SquaredZ = SquaredRadius - SquaredY - x * x;
if(SquaredZ >= 0)
{
SphereData[DataIndex] = (MIL_UINT32)(sqrt(SquaredZ) + 0.5);
}
else
SphereData[DataIndex] = M_DONT_CARE;
DataIndex++;
}
}
auto MilSphericStructElem = MbufAlloc2d(MilSystem, BufSize, BufSize,
STRUCT_ELEM_DEPTH + M_UNSIGNED,
M_STRUCT_ELEMENT, M_UNIQUE_ID);
MbufPut2d(MilSphericStructElem, 0, 0, BufSize, BufSize, SphereData);
delete[] SphereData;
return MilSphericStructElem;
}