#include <mil.h>
void OfflineDepthFromFocusIndexMapAndConfidenceMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory);
void OnlineDepthFromFocusIndexMapAndIntensityMap (MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory);
void OnlineDepthFromFocusIndexMapAndConfidenceMap (MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory);
void RemapDisplayRangeTo8Bits(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilScrImage, MIL_ID MilDisplayedImage);
bool CheckForRequiredMILFile(MIL_CONST_TEXT_PTR FileName);
#define IMAGES_DIR_SOURCE_HEAT_SINK M_IMAGE_PATH MIL_TEXT("DepthFromFocus/HeatSinkFocusStackingImages")
#define IMAGES_DIR_SOURCE_IRIS_CASE M_IMAGE_PATH MIL_TEXT("DepthFromFocus/IrisCaseFocusStackingImages")
#define IMAGES_DIR_SOURCE_BOTTLE M_IMAGE_PATH MIL_TEXT("DepthFromFocus/BottleFocusStackingImages")
const MIL_INT NB_IMG_HEAT_SINK = 141;
const MIL_INT SIZE_X_IMG_HEAT_SINK = 672;
const MIL_INT SIZE_Y_IMG_HEAT_SINK = 512;
const MIL_INT TYPE_IMG_HEAT_SINK = 8 + M_UNSIGNED;
const MIL_INT64 ATTRIBUTE_IMG_HEAT_SINK = M_IMAGE + M_DISP + M_GRAB + M_PROC;
const MIL_INT NB_IMG_IRIS_CASE = 61;
const MIL_INT SIZE_X_IMG_IRIS_CASE = 672;
const MIL_INT SIZE_Y_IMG_IRIS_CASE = 512;
const MIL_INT TYPE_IMG_IRIS_CASE = 8 + M_UNSIGNED;
const MIL_INT64 ATTRIBUTE_IMG_IRIS_CASE = M_IMAGE + M_DISP + M_GRAB + M_PROC;
const MIL_INT NB_IMG_BOTTLE = 101;
const MIL_INT SIZE_X_IMG_BOTTLE = 512;
const MIL_INT SIZE_Y_IMG_BOTTLE = 672;
const MIL_INT TYPE_IMG_BOTTLE = 8 + M_UNSIGNED;
const MIL_INT64 ATTRIBUTE_IMG_BOTTLE = M_IMAGE + M_DISP + M_GRAB + M_PROC;
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("DepthFromFocus\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This program demonstrates how to combine\n")
MIL_TEXT("multiple images taken at different focus\n")
MIL_TEXT("distances to obtain a resulting ordered map\n")
MIL_TEXT("of indexes. Each index corresponds to the\n")
MIL_TEXT("best focus distance at each pixel.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: Application, System, Display,\n")
MIL_TEXT("Buffer, Image Processing, Registration.\n"));
}
int MosMain()
{
MIL_ID MilApplication,
MilSystem,
MilDisplay;
PrintHeader();
MappAlloc(MIL_TEXT("M_DEFAULT"), M_DEFAULT, &MilApplication);
if (!CheckForRequiredMILFile(IMAGES_DIR_SOURCE_HEAT_SINK MIL_TEXT("/Img_heatsink_000.mim")))
{
MappFree(MilApplication);
return -1;
}
MsysAlloc(M_DEFAULT, M_SYSTEM_HOST, M_DEFAULT, M_DEFAULT, &MilSystem);
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay);
MosPrintf(MIL_TEXT("\n\nFirst example: offline operation on a textured\n")
MIL_TEXT("surface\n")
MIL_TEXT("----------------------------------------------\n")
MIL_TEXT("All the images are first collected. The depth\n")
MIL_TEXT("from focus index map image is then calculated.\n\n")
MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
OfflineDepthFromFocusIndexMapAndConfidenceMap(MilSystem,
MilDisplay,
NB_IMG_HEAT_SINK,
SIZE_X_IMG_HEAT_SINK,
SIZE_Y_IMG_HEAT_SINK,
TYPE_IMG_HEAT_SINK,
ATTRIBUTE_IMG_HEAT_SINK,
IMAGES_DIR_SOURCE_HEAT_SINK);
MosPrintf(MIL_TEXT("\nSecond example: online operation on a textured\n")
MIL_TEXT("object\n")
MIL_TEXT("----------------------------------------------\n")
MIL_TEXT("The images are sequentially acquired and added\n")
MIL_TEXT("to the computation of the index map.\n\n")
MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
OnlineDepthFromFocusIndexMapAndIntensityMap(MilSystem,
MilDisplay,
NB_IMG_IRIS_CASE,
SIZE_X_IMG_IRIS_CASE,
SIZE_Y_IMG_IRIS_CASE,
TYPE_IMG_IRIS_CASE,
ATTRIBUTE_IMG_IRIS_CASE,
IMAGES_DIR_SOURCE_IRIS_CASE);
MosPrintf(MIL_TEXT("\nThird example: using the confidence map result\n")
MIL_TEXT("on a textureless object\n")
MIL_TEXT("----------------------------------------------\n")
MIL_TEXT("The images are sequentially acquired and added\n")
MIL_TEXT("to the computation of the index map.\n\n")
MIL_TEXT("A pattern is cast on the smooth surface of the\n")
MIL_TEXT("object using a high power structured light.\n\n")
MIL_TEXT("To filter out irrelevant areas in the index\n")
MIL_TEXT("map, a confidence map is calculated.\n\n")
MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
OnlineDepthFromFocusIndexMapAndConfidenceMap(MilSystem,
MilDisplay,
NB_IMG_BOTTLE,
SIZE_X_IMG_BOTTLE,
SIZE_Y_IMG_BOTTLE,
TYPE_IMG_BOTTLE,
ATTRIBUTE_IMG_BOTTLE,
IMAGES_DIR_SOURCE_BOTTLE);
MdispFree(MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
typedef struct
{
MIL_ID Display;
} HookDisplayStruct;
MIL_INT MFTYPE DisplayingFunction(MIL_INT HookType,
MIL_ID HookId,
void *UserDisplayPtr)
{
HookDisplayStruct* UserStruct = (HookDisplayStruct*)UserDisplayPtr;
MIL_ID ModifiedBufferId;
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER + M_BUFFER_ID, &ModifiedBufferId);
MdispSelect(UserStruct->Display, ModifiedBufferId);
MosSleep(50);
return 0;
}
void OfflineDepthFromFocusIndexMapAndConfidenceMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory)
{
MIL_ID IndexMap,
DisplayedIndexMap,
RegContext,
DigId;
MIL_ID* ImagesArray;
HookDisplayStruct UserHookData;
RegContext = MregAlloc(MilSystem, M_DEPTH_FROM_FOCUS, M_DEFAULT, M_NULL);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_MODE, M_AVERAGE);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_SIZE, 5);
ImagesArray = new MIL_ID[NbImages];
for(MIL_INT NumImg = 0; NumImg < NbImages; NumImg++)
{
MbufAlloc2d(MilSystem, SizeX, SizeY, Type, Attribute, &ImagesArray[NumImg]);
}
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &IndexMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &DisplayedIndexMap);
UserHookData.Display = MilDisplay;
DigId = MdigAlloc(MilSystem, M_DEFAULT, ImageDirectory, M_EMULATED, M_NULL);
MosPrintf(MIL_TEXT("A stack of images is acquired using a liquid lens.\n"));
MosPrintf(MIL_TEXT("Load in progress...\n\n"));
MdigProcess(DigId, ImagesArray, NbImages, M_SEQUENCE + M_COUNT(NbImages), M_DEFAULT, DisplayingFunction, &UserHookData);
MosPrintf(MIL_TEXT("A stack of %d images has been loaded.\n"), NbImages);
MdigFree(DigId);
DigId = M_NULL;
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MosPrintf(MIL_TEXT("Calculation in progress...\n\n"));
MregCalculate(RegContext, ImagesArray, IndexMap, NbImages, M_COMPUTE);
RemapDisplayRangeTo8Bits(MilSystem, MilDisplay, IndexMap, DisplayedIndexMap);
MosPrintf(MIL_TEXT("The index map result is displayed.\n"));
MosPrintf(MIL_TEXT("Each gray value corresponds to the index of an\n"));
MosPrintf(MIL_TEXT("image among the acquired stack.\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MbufFree(IndexMap);
MbufFree(DisplayedIndexMap);
for(MIL_INT NumImg = 0; NumImg < NbImages; NumImg++)
{
MbufFree(ImagesArray[NumImg]);
}
delete[] ImagesArray;
MregFree(RegContext);
}
typedef struct
{
MIL_ID RegContext;
MIL_ID RegResult;
MIL_ID Display;
} HookDataStruct;
MIL_INT MFTYPE ProcessingFunction(MIL_INT HookType,
MIL_ID HookId,
void *UserDataPtr)
{
HookDataStruct* UserStruct = (HookDataStruct*)UserDataPtr;
MIL_ID ModifiedBufferId;
MdigGetHookInfo(HookId, M_MODIFIED_BUFFER + M_BUFFER_ID, &ModifiedBufferId);
MdispSelect(UserStruct->Display, ModifiedBufferId);
MosSleep(30);
MregCalculate(UserStruct->RegContext, &ModifiedBufferId, UserStruct->RegResult, 1, M_ACCUMULATE_AND_COMPUTE);
return 0;
}
void OnlineDepthFromFocusIndexMapAndIntensityMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory)
{
MIL_ID IndexMap,
DisplayedIndexMap,
IntensityMap,
RegContext,
RegResult,
DigId;
MIL_ID* ImagesArray;
HookDataStruct UserHookData;
RegContext = MregAlloc (MilSystem, M_DEPTH_FROM_FOCUS, M_DEFAULT, M_NULL);
RegResult = MregAllocResult(MilSystem, M_DEPTH_FROM_FOCUS_RESULT , M_NULL);
DigId = MdigAlloc(MilSystem, M_DEFAULT, ImageDirectory, M_EMULATED, M_NULL);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_MODE, M_AVERAGE);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_SIZE, 11);
MregControl(RegContext, M_DEFAULT, M_INTENSITY_MAP , M_ENABLE);
const MIL_INT ImageCount = 1;
ImagesArray = new MIL_ID[ImageCount];
for(MIL_INT NumImg = 0; NumImg < ImageCount; NumImg++)
{
MbufAlloc2d(MilSystem, SizeX, SizeY, Type, Attribute, &ImagesArray[NumImg]);
}
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &IndexMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &DisplayedIndexMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, Type , Attribute, &IntensityMap);
UserHookData.RegContext = RegContext;
UserHookData.RegResult = RegResult;
UserHookData.Display = MilDisplay;
MosPrintf(MIL_TEXT("The images are processed when acquired.\n"));
MosPrintf(MIL_TEXT("Load and processing in progress...\n\n"));
MdigProcess(DigId, ImagesArray, ImageCount, M_SEQUENCE + M_COUNT(NbImages), M_DEFAULT, ProcessingFunction, &UserHookData);
MosPrintf(MIL_TEXT("A stack of %d images has been processed.\n"), NbImages);
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MregDraw(M_DEFAULT, RegResult, IndexMap, M_DRAW_DEPTH_INDEX_MAP, M_DEFAULT, M_DEFAULT);
RemapDisplayRangeTo8Bits(MilSystem, MilDisplay, IndexMap, DisplayedIndexMap);
MosPrintf(MIL_TEXT("The resulting index map image is displayed.\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MregDraw(M_DEFAULT, RegResult, IntensityMap, M_DRAW_DEPTH_INTENSITY_MAP, M_DEFAULT, M_DEFAULT);
MdispSelect(MilDisplay, IntensityMap);
MosPrintf(MIL_TEXT("An extended depth of field image, reconstructed\n"));
MosPrintf(MIL_TEXT("using the index map result, is displayed.\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MbufFree(IndexMap);
MbufFree(DisplayedIndexMap);
MbufFree(IntensityMap);
for(MIL_INT NumImg = 0; NumImg < ImageCount; NumImg++)
{
MbufFree(ImagesArray[NumImg]);
}
delete[] ImagesArray;
MdigFree(DigId);
MregFree(RegResult);
MregFree(RegContext);
}
void OnlineDepthFromFocusIndexMapAndConfidenceMap(MIL_ID MilSystem,
MIL_ID MilDisplay,
MIL_INT NbImages,
MIL_INT SizeX,
MIL_INT SizeY,
MIL_INT Type,
MIL_INT64 Attribute,
MIL_CONST_TEXT_PTR ImageDirectory)
{
MIL_ID IndexMap,
DisplayedIndexMap,
ConfidenceMap,
DisplayedConfidenceMap,
RelevantResult,
RegContext,
RegResult,
DigId;
MIL_ID* ImagesArray;
HookDataStruct UserHookData;
RegContext = MregAlloc(MilSystem, M_DEPTH_FROM_FOCUS, M_DEFAULT, M_NULL);
RegResult = MregAllocResult(MilSystem, M_DEPTH_FROM_FOCUS_RESULT, M_NULL);
DigId = MdigAlloc(MilSystem, M_DEFAULT, ImageDirectory, M_EMULATED, M_NULL);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_MODE, M_AVERAGE);
MregControl(RegContext, M_DEFAULT, M_REGULARIZATION_SIZE, 7);
MregControl(RegContext, M_DEFAULT, M_CONFIDENCE_MAP , M_ENABLE);
const MIL_INT ImageCount = 1;
ImagesArray = new MIL_ID[ImageCount];
for(MIL_INT NumImg = 0; NumImg < ImageCount; NumImg++)
{
MbufAlloc2d(MilSystem, SizeX, SizeY, Type, Attribute, &ImagesArray[NumImg]);
}
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &IndexMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + M_UNSIGNED, Attribute, &DisplayedIndexMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 32 + M_FLOAT , Attribute, &ConfidenceMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 32 + M_FLOAT , Attribute, &DisplayedConfidenceMap);
MbufAlloc2d(MilSystem, SizeX, SizeY, 32 + M_FLOAT , Attribute, &RelevantResult);
UserHookData.RegContext = RegContext;
UserHookData.RegResult = RegResult;
UserHookData.Display = MilDisplay;
MosPrintf(MIL_TEXT("The images are processed when acquired.\n"));
MosPrintf(MIL_TEXT("Load and processing in progress...\n\n"));
MdigProcess(DigId, ImagesArray, ImageCount, M_SEQUENCE + M_COUNT(NbImages), M_DEFAULT, ProcessingFunction, &UserHookData);
MosPrintf(MIL_TEXT("A stack of %d images has been processed.\n"), NbImages);
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n"));
MosGetch();
MregDraw(M_DEFAULT, RegResult, IndexMap, M_DRAW_DEPTH_INDEX_MAP, M_DEFAULT, M_DEFAULT);
RemapDisplayRangeTo8Bits(MilSystem, MilDisplay, IndexMap, DisplayedIndexMap);
MosPrintf(MIL_TEXT("The resulting index map image is displayed.\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MregDraw(M_DEFAULT, RegResult, ConfidenceMap, M_DRAW_DEPTH_CONFIDENCE_MAP, M_DEFAULT, M_DEFAULT);
RemapDisplayRangeTo8Bits(MilSystem, MilDisplay, ConfidenceMap, DisplayedConfidenceMap);
MosPrintf(MIL_TEXT("The resulting confidence map image is\n"));
MosPrintf(MIL_TEXT("displayed.\n"));
MosPrintf(MIL_TEXT("Darker values correspond to lower confidence\n"));
MosPrintf(MIL_TEXT("areas while brighter values correspond to\n"));
MosPrintf(MIL_TEXT("highter confidence areas.\n"));
MosPrintf(MIL_TEXT("Higher confidence areas indicate meaningful\n"));
MosPrintf(MIL_TEXT("index map areas.\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to continue.\n\n"));
MosGetch();
MimBinarize(ConfidenceMap, RelevantResult, M_FIXED + M_GREATER, 2.6, M_NULL);
MimArith(IndexMap, RelevantResult, IndexMap, M_MULT);
RemapDisplayRangeTo8Bits(MilSystem, MilDisplay, IndexMap, DisplayedIndexMap);
MosPrintf(MIL_TEXT("Low confidence areas are masked and the\n"));
MosPrintf(MIL_TEXT("resulting index map image is displayed.\n"));
MosPrintf(MIL_TEXT("\nPress <Enter> to end.\n\n"));
MosGetch();
MbufFree(IndexMap);
MbufFree(DisplayedIndexMap);
MbufFree(ConfidenceMap);
MbufFree(DisplayedConfidenceMap);
MbufFree(RelevantResult);
for(MIL_INT NumImg = 0; NumImg < ImageCount; NumImg++)
{
MbufFree(ImagesArray[NumImg]);
}
delete[] ImagesArray;
MdigFree(DigId);
MregFree(RegResult);
MregFree(RegContext);
}
void RemapDisplayRangeTo8Bits(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilScrImage, MIL_ID MilDisplayedImage)
{
MIL_ID MilStatContext = MimAlloc(MilSystem, M_STATISTICS_CONTEXT, M_DEFAULT, M_NULL);
MimControl(MilStatContext, M_STAT_MIN, M_ENABLE);
MimControl(MilStatContext, M_STAT_MAX, M_ENABLE);
MIL_ID MilStatResult = MimAllocResult(MilSystem, M_DEFAULT, M_STATISTICS_RESULT, M_NULL);
MIL_ID MilDynRangeLut = MbufAlloc1d(MilSystem, 256, 8 + M_UNSIGNED, M_LUT, M_NULL);
MimStatCalculate(MilStatContext, MilScrImage, MilStatResult, M_DEFAULT);
MIL_INT StatMin;
MimGetResult(MilStatResult, M_STAT_MIN + M_TYPE_MIL_INT, &StatMin);
MIL_INT StatMax;
MimGetResult(MilStatResult, M_STAT_MAX + M_TYPE_MIL_INT, &StatMax);
MbufClear(MilDynRangeLut, 0.0);
MgenLutRamp(MilDynRangeLut, StatMin, 1.0, StatMax, 255.0);
MimLutMap(MilScrImage, MilDisplayedImage, MilDynRangeLut);
MbufFree(MilDynRangeLut);
MimFree(MilStatResult);
MimFree(MilStatContext);
MdispSelect(MilDisplay, MilDisplayedImage);
}
bool CheckForRequiredMILFile(MIL_CONST_TEXT_PTR FileName)
{
MIL_INT FilePresent;
MappFileOperation(M_DEFAULT, FileName, M_NULL, M_NULL, M_FILE_EXISTS, M_DEFAULT, &FilePresent);
if (FilePresent == M_NO)
{
MosPrintf(MIL_TEXT("\n")
MIL_TEXT("The footage needed to run this example is missing. You need \n")
MIL_TEXT("to obtain and apply a separate specific update to have it.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n"));
MosGetch();
}
return (FilePresent == M_YES);
}