#include <mil.h>
#include <vector>
#define IMAGE_DIR M_IMAGE_PATH MIL_TEXT("PolarizationImaging")
const MIL_INT NB_TILES_TO_DISP = 4;
const MIL_INT NB_EXAMPLES = 4;
const MIL_CONST_TEXT_PTR ImageNameArray[NB_EXAMPLES] = {MIL_TEXT("CarbonFiber.mim"),
MIL_TEXT("CellPhoneCase.mim"),
MIL_TEXT("PlasticPiece.mim"),
MIL_TEXT("BlackCone.mim")};
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("PolarizationImaging\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This example demonstrates how to process images captured\n")
MIL_TEXT("from a polarization sensor to enhance features, detect a\n")
MIL_TEXT("material's internal stress, and detect defects.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: application, buffer, display, image processing, system.\n"));
}
void ExtractPolarizedChannels ( MIL_ID MilSysId,
MIL_ID OriginalImgId,
std::vector<MIL_ID> PolarizedImgVect);
void ComputeStokesParams ( MIL_ID MilSysId,
std::vector<MIL_ID> pPolarizedImgVect,
std::vector<MIL_ID> pStokesImgVect);
void ComputeDescriptors ( MIL_ID MilSysId,
MIL_ID OriginalImgId,
std::vector<MIL_ID> StokesImgVect,
std::vector<MIL_ID> DescriptorImgVect);
void ShowOriginalImage ( MIL_ID MilSystemId,
MIL_ID MilDisplayId,
MIL_ID OriginalImgId,
MIL_ID DisplayImgId);
void ShowPolarizedChannels ( MIL_ID MilSystemId,
MIL_ID MilDisplayId,
std::vector<MIL_ID> PolarizedImgVect,
MIL_ID DisplayImgId,
MIL_ID MilGraphicListId);
void ShowStokesParameters ( MIL_ID MilSystemId,
MIL_ID MilDisplayId,
std::vector<MIL_ID> StokesImgVect,
MIL_ID DisplayImgId,
MIL_ID MilGraphicListId);
void ShowDescriptors ( MIL_ID MilSystemId,
MIL_ID MilDisplayId,
std::vector<MIL_ID> DescriptorImgVect,
MIL_ID DisplayImgId,
MIL_ID MilGraphicListId);
void PseudoColorAoLP(MIL_ID MilSysId, MIL_ID SourceImgId, MIL_ID DisplayImgId);
int MosMain()
{
PrintHeader();
MIL_ID MilApplicationId = MappAlloc (M_DEFAULT, M_NULL);
MIL_ID MilSystemId = MsysAlloc (M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, M_NULL);
MIL_ID MilDisplayId = MdispAlloc(MilSystemId, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, M_NULL);
MdispZoom(MilDisplayId, 0.5, 0.5);
MIL_ID MilGraphicList = MgraAllocList(MilSystemId, M_DEFAULT, M_NULL);
MdispControl(MilDisplayId, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicList);
std::vector<MIL_ID> PolarizedImgVect(NB_TILES_TO_DISP, M_NULL);
std::vector<MIL_ID> StokesImgVect(NB_TILES_TO_DISP, M_NULL);
std::vector<MIL_ID> DescriptorImgVect(NB_TILES_TO_DISP, M_NULL);
MIL_ID OriginalImgId, DisplayImgId;
MIL_INT ImgSizeX, ImgSizeY, i;
MIL_TEXT_CHAR ImgName[256];
MIL_CONST_TEXT_PTR DescPtr[4] = {MIL_TEXT("In this example, the angle of linear polarization is used to distinguish\nstructures made with of a carbon fiber material. \n"),
MIL_TEXT("In this example, polarization imaging results emphasize the presence of\ninternal stress in parts made with a transparent material.\n"),
MIL_TEXT("In this example, the degree of linear polarization is used to detect defects\nin parts made with a dark plastic material. \n"),
MIL_TEXT("In this example, polarization imaging is used to increase the contrast\nbetween parts made with a dark plastic material. \n")};
for (MIL_INT ExampleIdx = 0; ExampleIdx < NB_EXAMPLES; ExampleIdx++)
{
MosPrintf(MIL_TEXT("\n-----------------------------------------------------------------------\n"));
MosPrintf(DescPtr[ExampleIdx]);
MosSprintf(ImgName, 256, MIL_TEXT("%s/%s"), IMAGE_DIR, ImageNameArray[ExampleIdx]);
MbufRestore(ImgName, MilSystemId, &OriginalImgId);
ImgSizeX = MbufInquire(OriginalImgId, M_SIZE_X, M_NULL);
ImgSizeY = MbufInquire(OriginalImgId, M_SIZE_Y, M_NULL);
MbufAllocColor(MilSystemId, 3, ImgSizeX, ImgSizeY, 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &DisplayImgId);
for (i = 0; i < NB_TILES_TO_DISP; ++i)
MbufAlloc2d(MilSystemId, ImgSizeX / 2, ImgSizeY / 2, 8 + M_UNSIGNED, M_IMAGE + M_PROC, &PolarizedImgVect[i]);
for (i = 0; i < NB_TILES_TO_DISP -1; ++i)
MbufAlloc2d(MilSystemId, ImgSizeX / 2, ImgSizeY / 2, 32 + M_FLOAT, M_IMAGE + M_PROC, &StokesImgVect[i]);
for (i = 0; i < NB_TILES_TO_DISP -1; ++i)
MbufAlloc2d(MilSystemId, ImgSizeX / 2, ImgSizeY / 2, 32 + M_FLOAT, M_IMAGE + M_PROC, &DescriptorImgVect[i]);
ShowOriginalImage(MilSystemId, MilDisplayId, OriginalImgId, DisplayImgId);
ExtractPolarizedChannels(MilSystemId, OriginalImgId, PolarizedImgVect);
ShowPolarizedChannels(MilSystemId, MilDisplayId, PolarizedImgVect, DisplayImgId, MilGraphicList);
ComputeStokesParams(MilSystemId, PolarizedImgVect, StokesImgVect);
ShowStokesParameters(MilSystemId, MilDisplayId, StokesImgVect, DisplayImgId, MilGraphicList);
ComputeDescriptors(MilSystemId, OriginalImgId, StokesImgVect, DescriptorImgVect);
ShowDescriptors(MilSystemId, MilDisplayId, DescriptorImgVect, DisplayImgId, MilGraphicList);
for (i = 0; i < NB_TILES_TO_DISP -1; ++i)
{
MbufFree(DescriptorImgVect[i]);
MbufFree(StokesImgVect[i]);
}
for (i = 0; i < NB_TILES_TO_DISP; ++i)
{
MbufFree(PolarizedImgVect[i]);
}
MbufFree(DisplayImgId);
MbufFree(OriginalImgId);
}
MosPrintf(MIL_TEXT("\nPress <Enter> to end.\n\n"));
MosGetch();
MgraFree(MilGraphicList);
MdispFree(MilDisplayId);
MsysFree (MilSystemId);
MappFree (MilApplicationId);
}
void ExtractPolarizedChannels(MIL_ID MilSysId, MIL_ID OriginalImgId, std::vector<MIL_ID> PolarizedImgVect)
{
MIL_INT ImgSizeX = MbufInquire(OriginalImgId, M_SIZE_X, M_NULL);
MIL_INT ImgSizeY = MbufInquire(OriginalImgId, M_SIZE_Y, M_NULL);
MIL_ID WarpMatrixId = MbufAllocColor(M_DEFAULT_HOST, 1, 3, 3, 32 + M_FLOAT, M_ARRAY, M_NULL);
MgenWarpParameter(M_NULL, WarpMatrixId, M_NULL, M_WARP_POLYNOMIAL, M_SCALE, 0.5, 0.5);
MIL_ID SrcChildId = MbufChild2d(OriginalImgId, 0, 0, ImgSizeX, ImgSizeY, M_NULL);
MimWarp(SrcChildId, PolarizedImgVect[0], WarpMatrixId, M_NULL, M_WARP_POLYNOMIAL, M_NEAREST_NEIGHBOR);
MbufChildMove(SrcChildId, 1, 0, ImgSizeX - 1, ImgSizeY, M_DEFAULT);
MimWarp(SrcChildId, PolarizedImgVect[1], WarpMatrixId, M_NULL, M_WARP_POLYNOMIAL, M_NEAREST_NEIGHBOR);
MbufChildMove(SrcChildId, 0, 1, ImgSizeX, ImgSizeY - 1, M_DEFAULT);
MimWarp(SrcChildId, PolarizedImgVect[2], WarpMatrixId, M_NULL, M_WARP_POLYNOMIAL, M_NEAREST_NEIGHBOR);
MbufChildMove(SrcChildId, 1, 1, ImgSizeX - 1, ImgSizeY - 1, M_DEFAULT);
MimWarp(SrcChildId, PolarizedImgVect[3], WarpMatrixId, M_NULL, M_WARP_POLYNOMIAL, M_NEAREST_NEIGHBOR);
MbufFree(WarpMatrixId);
MbufFree(SrcChildId);
}
void ComputeStokesParams(MIL_ID MilSysId, std::vector<MIL_ID> PolarizedImgVect, std::vector<MIL_ID> StokesImgVect)
{
MIL_INT TileSizeX = MbufInquire((PolarizedImgVect)[0], M_SIZE_X, M_NULL);
MIL_INT TileSizeY = MbufInquire((PolarizedImgVect)[0], M_SIZE_Y, M_NULL);
MimArith(PolarizedImgVect[3], PolarizedImgVect[0], StokesImgVect[0], M_ADD);
MimArith(PolarizedImgVect[3], PolarizedImgVect[0], StokesImgVect[1], M_SUB);
MimArith(PolarizedImgVect[1], PolarizedImgVect[2], StokesImgVect[2], M_SUB);
}
void ComputeDescriptors(MIL_ID MilSysId, MIL_ID OriginalImgId, std::vector<MIL_ID> StokesImgVect, std::vector<MIL_ID> DescriptorImgVect)
{
MIL_INT TileSizeX = MbufInquire(StokesImgVect[0], M_SIZE_X, M_NULL);
MIL_INT TileSizeY = MbufInquire(StokesImgVect[0], M_SIZE_Y, M_NULL);
MimResize(OriginalImgId, DescriptorImgVect[0], 0.5, 0.5, M_MIN);
MimTransform(StokesImgVect[1], StokesImgVect[2], DescriptorImgVect[1], DescriptorImgVect[2], M_POLAR, M_FORWARD);
MimArith(DescriptorImgVect[1], StokesImgVect[0], DescriptorImgVect[1], M_DIV);
MimArith(DescriptorImgVect[2], 0.5, DescriptorImgVect[2], M_MULT_CONST);
}
void ShowOriginalImage(MIL_ID MilSystemId, MIL_ID MilDisplayId, MIL_ID OriginalImgId, MIL_ID DisplayImgId)
{
MosPrintf(MIL_TEXT("\n(1) Capture a polarized image using a polarization sensor.\n"));
MdispControl(MilDisplayId, M_TITLE, MIL_TEXT("Original Image"));
MbufCopy(OriginalImgId, DisplayImgId);
MdispSelect(MilDisplayId, DisplayImgId);
MosPrintf(MIL_TEXT("Press any key to continue...\n"));
MosGetch();
}
void ShowPolarizedChannels(MIL_ID MilSystemId, MIL_ID MilDisplayId, std::vector<MIL_ID> PolarizedImgVect, MIL_ID DisplayImgId, MIL_ID MilGraphicListId)
{
MosPrintf(MIL_TEXT("\n(2) De-mosaic the 4 polarization orientations.\n"));
MIL_INT TileSizeX = MbufInquire(DisplayImgId, M_SIZE_X, M_NULL) / 2;
MIL_INT TileSizeY = MbufInquire(DisplayImgId, M_SIZE_Y, M_NULL) / 2;
MbufCopyClip(PolarizedImgVect[0], DisplayImgId, 0, 0);
MbufCopyClip(PolarizedImgVect[1], DisplayImgId, TileSizeX, 0);
MbufCopyClip(PolarizedImgVect[2], DisplayImgId, 0, TileSizeY);
MbufCopyClip(PolarizedImgVect[3], DisplayImgId, TileSizeX, TileSizeY);
MgraColor(M_DEFAULT, M_COLOR_GREEN);
MdispControl(MilDisplayId, M_TITLE, MIL_TEXT("Polarization channels."));
MgraText(M_DEFAULT, MilGraphicListId, 0, 0, MIL_TEXT("I90 - Pixels polarized at 90 degrees"));
MgraText(M_DEFAULT, MilGraphicListId, TileSizeX, 0, MIL_TEXT("I45 - Pixels polarized at 45 degrees"));
MgraText(M_DEFAULT, MilGraphicListId, 0, TileSizeY, MIL_TEXT("I135 - Pixels polarized at 135 degrees"));
MgraText(M_DEFAULT, MilGraphicListId, TileSizeX, TileSizeY, MIL_TEXT("I0 - Pixels polarized at 0 degree"));
MosPrintf(MIL_TEXT("Press any key to continue...\n"));
MosGetch();
}
void ShowStokesParameters(MIL_ID MilSystemId, MIL_ID MilDisplayId, std::vector<MIL_ID> StokesImgVect, MIL_ID DisplayImgId, MIL_ID MilGraphicListId)
{
MosPrintf(MIL_TEXT("\n(3) Compute the Stokes polarization state parameters.\n"));
MIL_INT TileSizeX = MbufInquire(DisplayImgId, M_SIZE_X, M_NULL) / 2;
MIL_INT TileSizeY = MbufInquire(DisplayImgId, M_SIZE_Y, M_NULL) / 2;
MbufClear(DisplayImgId, 0L);
MgraClear(M_DEFAULT, MilGraphicListId);
MIL_ID DstChildId = MbufChild2d(DisplayImgId, 0, 0, TileSizeX, TileSizeY, M_NULL);
MbufControl(StokesImgVect[0], M_MIN, 0);
MbufControl(StokesImgVect[0], M_MAX, 510);
MimRemap(M_DEFAULT, StokesImgVect[0], DstChildId, M_FIT_SRC_RANGE);
MbufChildMove(DstChildId, TileSizeX, 0, TileSizeX, TileSizeY, M_NULL);
MbufControl(StokesImgVect[1], M_MIN, -255);
MbufControl(StokesImgVect[1], M_MAX, 255);
MimRemap(M_DEFAULT, StokesImgVect[1], DstChildId, M_FIT_SRC_RANGE);
MbufChildMove(DstChildId, 0, TileSizeY, TileSizeX, TileSizeY, M_NULL);
MbufControl(StokesImgVect[2], M_MIN, -255);
MbufControl(StokesImgVect[2], M_MAX, 255);
MimRemap(M_DEFAULT, StokesImgVect[2], DstChildId, M_FIT_SRC_RANGE);
MbufFree(DstChildId);
MdispControl(MilDisplayId, M_TITLE, MIL_TEXT("Stokes parameters"));
MgraText(M_DEFAULT,MilGraphicListId, 0, 0, MIL_TEXT("S0 = I0 + I90"));
MgraText(M_DEFAULT, MilGraphicListId, TileSizeX, 0, MIL_TEXT("S1 = I0 - I90"));
MgraText(M_DEFAULT, MilGraphicListId, 0, TileSizeY, MIL_TEXT("S2 = I45 - I135"));
MosPrintf(MIL_TEXT("Press any key to continue...\n"));
MosGetch();
}
void ShowDescriptors(MIL_ID MilSystemId, MIL_ID MilDisplayId, std::vector<MIL_ID> DescriptorImgVect, MIL_ID DisplayImgId, MIL_ID MilGraphicListId)
{
MosPrintf(MIL_TEXT("\n(4) Compute results for the derived minimum intensity, degree of Linear\n")
MIL_TEXT("Polarization, and angle of Linear Polarization.\n"));
MIL_INT TileSizeX = MbufInquire(DisplayImgId, M_SIZE_X, M_NULL) / 2;
MIL_INT TileSizeY = MbufInquire(DisplayImgId, M_SIZE_Y, M_NULL) / 2;
MIL_ID DstChildId = MbufChild2d(DisplayImgId, 0, 0, TileSizeX, TileSizeY, M_NULL);
MdispControl(MilDisplayId, M_TITLE, MIL_TEXT("Result Images"));
MgraClear(M_DEFAULT, MilGraphicListId);
MgraText(M_DEFAULT, MilGraphicListId, 0, 0, MIL_TEXT("Intensity."));
MbufCopyClip(DescriptorImgVect[0], DisplayImgId, TileSizeX, 0);
MbufChildMove(DstChildId, 0, TileSizeY, TileSizeX, TileSizeY, M_NULL);
MbufControl(DescriptorImgVect[1], M_MIN, 0.0);
MbufControl(DescriptorImgVect[1], M_MAX, 1.0);
MimRemap(M_DEFAULT, DescriptorImgVect[1], DstChildId, M_FIT_SRC_RANGE);
MbufChildMove(DstChildId, TileSizeX, TileSizeY, TileSizeX, TileSizeY, M_NULL);
MbufControl(DescriptorImgVect[2], M_MIN, 0.0);
MbufControl(DescriptorImgVect[2], M_MAX, 180.0);
PseudoColorAoLP(MilSystemId, DescriptorImgVect[2], DstChildId);
MgraText(M_DEFAULT, MilGraphicListId, TileSizeX, 0, MIL_TEXT("Minimum Intensity."));
MgraText(M_DEFAULT, MilGraphicListId, 0, TileSizeY, MIL_TEXT("Degree of Linear Polarization."));
MgraText(M_DEFAULT, MilGraphicListId, TileSizeX, TileSizeY, MIL_TEXT("Angle of Linear Polarization."));
MbufFree(DstChildId);
MosPrintf(MIL_TEXT("Press any key to continue...\n"));
MosGetch();
MgraClear(M_DEFAULT, MilGraphicListId);
}
void PseudoColorAoLP(MIL_ID MilSysId, MIL_ID SourceImgId, MIL_ID DisplayImgId)
{
MIL_INT TileSizeX = MbufInquire(DisplayImgId, M_SIZE_X, M_NULL);
MIL_INT TileSizeY = MbufInquire(DisplayImgId, M_SIZE_Y, M_NULL);
MIL_ID MonoSrcRemapped = MbufAlloc2d(MilSysId, TileSizeX, TileSizeY, 8+M_UNSIGNED, M_IMAGE + M_PROC, M_NULL);
MimRemap(M_DEFAULT, SourceImgId, MonoSrcRemapped, M_FIT_SRC_RANGE);
MIL_ID MilLut;
MbufAllocColor(MilSysId, 3, 256, 1, 8 + M_UNSIGNED, M_LUT, &MilLut);
MgenLutFunction(MilLut, M_COLORMAP_HUE, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MimLutMap(MonoSrcRemapped, DisplayImgId, MilLut);
MbufFree(MilLut);
MbufFree(MonoSrcRemapped);
}