#include <mil.h>
#include <math.h>
#include <stdlib.h>
#include <vector>
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n"));
MosPrintf(MIL_TEXT("Simple3dBinPicking\n\n"));
MosPrintf(MIL_TEXT("[SYNOPSIS]\n"));
MosPrintf(MIL_TEXT("This example shows how to combine 2D Model Finder and \n"));
MosPrintf(MIL_TEXT("3D registration to estimate the pose of 3D objects stacked \n"));
MosPrintf(MIL_TEXT("with minor variations in pitch and roll. \n\n"));
MosPrintf(MIL_TEXT("[MODULES USED]\n"));
MosPrintf(MIL_TEXT("Modules used: 3D Geometry, 3D Image Processing, 3D Registration,\n")
MIL_TEXT("Geometric Model Finder, Buffer, Calibration, Display, Graphics, \n")
MIL_TEXT("3D Display, Image Processing and 3D Metrology. \n\n"));
}
enum { eModel = 0, eScene = 1 };
static const MIL_INT NUM_SCENE_SCANS = 3;
static const MIL_TEXT_CHAR* const FILE_POINT_CLOUD[NUM_SCENE_SCANS + 1] =
{ M_IMAGE_PATH MIL_TEXT("Simple3dBinPicking/3dPlugCloudModel.ply"),
M_IMAGE_PATH MIL_TEXT("Simple3dBinPicking/BinCloudScene_0.ply") ,
M_IMAGE_PATH MIL_TEXT("Simple3dBinPicking/BinCloudScene_1.ply") ,
M_IMAGE_PATH MIL_TEXT("Simple3dBinPicking/BinCloudScene_2.ply") };
static const MIL_INT DEPTHMAP_SIZE_X = 300;
static const MIL_INT DEPTHMAP_SIZE_Y = 480;
static const MIL_INT DEPTHMAP_NUM_VALUES = 65536;
static const MIL_DOUBLE DEPTHMAP_MISSING_DATA = DEPTHMAP_NUM_VALUES - 1;
static const MIL_DOUBLE SCANNER_FOV_MIN_X = -44.0;
static const MIL_DOUBLE SCANNER_FOV_MIN_Y = -80.0;
static const MIL_DOUBLE SCANNER_FOV_MIN_Z = -6.0;
static const MIL_DOUBLE SCANNER_FOV_MAX_X = 50.0;
static const MIL_DOUBLE SCANNER_FOV_MAX_Y = 80.0;
static const MIL_DOUBLE SCANNER_FOV_MAX_Z = -60.0;
static const MIL_DOUBLE MODEL_ROI_MARGIN_X = 5.0;
static const MIL_DOUBLE MODEL_ROI_MARGIN_Y = 5.0;
static const MIL_DOUBLE MODEL_ROI_MARGIN_Z = 20.0;
static const MIL_DOUBLE FINDER_ACCEPTANCE = 50.0;
#define FOUND_OCCURRENCES_COLOR M_RGB888(192, 0, 0)
#define SELECTED_OCCURRENCE_COLOR M_RGB888(0, 255, 0)
static const MIL_INT DECIMATION_STEP = 4;
static const MIL_DOUBLE OVERLAP = 90.0;
static const MIL_INT MAX_ITERATIONS = 50;
static const MIL_INT ERROR_MINIMIZATION_METRIC = M_POINT_TO_POINT;
struct SPose
{ MIL_DOUBLE Tx, Ty, Tz, Rx, Ry, Rz; };
struct SBox
{
MIL_DOUBLE MinX, MinY, MinZ, MaxX, MaxY, MaxZ;
MIL_INT OffsetX, OffsetY, SizeX, SizeY;
};
void DefineModelRoiBox (MIL_ID MilSystem, MIL_ID MilPtCldCtn, MIL_ID MilDepthMap, SBox& ModelRoiBox);
void MapDynamicRangeTo8Bits (MIL_ID MilSystem, MIL_ID MilSrcImage, MIL_ID MilTgtImage);
bool FindPreregistrationWithTopFoundOccurrence(MIL_ID MilSystem, MIL_UNIQUE_BUF_ID MilPtCldCtn[], MIL_DOUBLE ModelMeanElevation, MIL_UNIQUE_BUF_ID MilDepthMap[],
MIL_ID MilFixturingOffset, MIL_ID MilFinderResult, MIL_ID MilPreregistrationMatrix, MIL_INT* pTopOccIdx);
void ExtractRegisteredDepthMaps (MIL_ID MilSystem, MIL_UNIQUE_BUF_ID MilPtCldCtn[], MIL_UNIQUE_BUF_ID& MilTransformedModel, MIL_UNIQUE_BUF_ID MilDepthMap[], MIL_ID MilRegisterationResult, SPose& Pose);
void GetPose (MIL_ID MilMatrixId, SPose& Pose);
MIL_ID Alloc3dDisplayId (MIL_ID MilSystem);
bool CheckForRequiredMILFile (const MIL_STRING& FileName);
static const MIL_DOUBLE DISPLAY_3D_EYE_AZIM = 85.0;
static const MIL_DOUBLE DISPLAY_3D_EYE_ELEV = 230.0;
static const MIL_DOUBLE DISPLAY_3D_EYE_ROLL = 0.0;
int MosMain()
{
PrintHeader();
auto MilApplication = MappAlloc(M_NULL, M_DEFAULT, M_UNIQUE_ID);
MIL_ID MilSystem = M_DEFAULT_HOST;
if(!CheckForRequiredMILFile(FILE_POINT_CLOUD[eModel]))
{ return 0; }
auto MilDisplay = MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, M_UNIQUE_ID);
MIL_ID MilDisplay3d = Alloc3dDisplayId(MilSystem);
MIL_ID MilGraphicList;
MIL_UNIQUE_BUF_ID MilPtCldCtn[2];
MIL_UNIQUE_BUF_ID MilDepthMap[2];
MIL_DOUBLE ModelMeanElevation;
SBox ModelRoiBox;
MIL_UNIQUE_3DGEO_ID MilBox;
MIL_ID MilFinderImage[2];
MIL_ID MilFinderContext;
MIL_ID MilFinderResult;
MIL_INT TopOccurrenceIdx;
MIL_ID MilRegistrationContext;
MIL_ID MilRegistrationResult;
MIL_ID MilPreregistrationMatrix;
MIL_INT RegistrationCompleted;
MgraAllocList(MilSystem, M_DEFAULT, &MilGraphicList);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraphicList);
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
if(MilDisplay3d)
{
M3ddispControl(MilDisplay3d, M_WINDOW_INITIAL_POSITION_X, (MIL_INT)(1.04 * DEPTHMAP_SIZE_X));
M3ddispSetView(MilDisplay3d, M_AZIM_ELEV_ROLL , DISPLAY_3D_EYE_AZIM, DISPLAY_3D_EYE_ELEV, DISPLAY_3D_EYE_ROLL, M_DEFAULT);
}
MbufImport(FILE_POINT_CLOUD[eModel], M_DEFAULT, M_RESTORE, MilSystem, &MilPtCldCtn[eModel]);
MilDepthMap[eModel]=MbufAlloc2d(MilSystem, DEPTHMAP_SIZE_X, DEPTHMAP_SIZE_Y, M_UNSIGNED + 16, M_IMAGE + M_DISP + M_PROC, M_UNIQUE_ID);
MilBox = M3dgeoAlloc(MilSystem, M_GEOMETRY, M_DEFAULT, M_UNIQUE_ID);
M3dgeoBox(MilBox, M_BOTH_CORNERS,
SCANNER_FOV_MIN_X, SCANNER_FOV_MIN_Y, SCANNER_FOV_MIN_Z,
SCANNER_FOV_MAX_X, SCANNER_FOV_MAX_Y, SCANNER_FOV_MAX_Z, M_DEFAULT);
M3dimCrop(MilPtCldCtn[eModel], MilPtCldCtn[eModel],MilBox,M_NULL,M_DEFAULT,M_DEFAULT);
MIL_INT SizeX = MbufInquireContainer(MilPtCldCtn[eModel], M_COMPONENT_RANGE, M_SIZE_X, M_NULL);
MIL_INT SizeY = MbufInquireContainer(MilPtCldCtn[eModel], M_COMPONENT_RANGE, M_SIZE_Y, M_NULL);
MIL_ID MilModelReflectance = MbufAllocComponent(MilPtCldCtn[eModel], 3, SizeX, SizeY, M_UNSIGNED + 8, M_IMAGE + M_PROC + M_DISP, M_COMPONENT_REFLECTANCE, M_NULL);
MbufClear(MilModelReflectance, M_COLOR_GREEN);
M3dimCalibrateDepthMap(MilBox, MilDepthMap[eModel], M_NULL, M_NULL, M_DEFAULT, M_NEGATIVE, M_DEFAULT);
M3dimProject(MilPtCldCtn[eModel], MilDepthMap[eModel], M_NULL, M_POINT_BASED, M_MAX_Z, M_DEFAULT,M_DEFAULT);
MIL_ID StatResultId = M3dmetAllocResult(MilSystem, M_STATISTICS_RESULT, M_DEFAULT, M_NULL);
M3dmetStat(M_STAT_CONTEXT_MEAN, MilDepthMap[eModel], M_XY_PLANE, StatResultId, M_SIGNED_DISTANCE_Z_TO_SURFACE, M_ALL, M_NULL, M_NULL,M_DEFAULT);
M3dmetGetResult(StatResultId, M_STAT_MEAN, &ModelMeanElevation);
M3dmetFree(StatResultId);
DefineModelRoiBox(MilSystem,MilPtCldCtn[eModel], MilDepthMap[eModel], ModelRoiBox);
MbufAlloc2d(MilSystem, ModelRoiBox.SizeX, ModelRoiBox.SizeY, M_UNSIGNED + 8, M_IMAGE + M_DISP + M_PROC, &MilFinderImage[eModel]);
MIL_ID MilModelRoiChild = MbufChild2d(MilDepthMap[eModel], ModelRoiBox.OffsetX, ModelRoiBox.OffsetY, ModelRoiBox.SizeX, ModelRoiBox.SizeY, M_NULL);
MapDynamicRangeTo8Bits(MilSystem, MilModelRoiChild, MilFinderImage[eModel]);
MbufFree(MilModelRoiChild);
MmodAlloc(MilSystem, M_GEOMETRIC, M_DEFAULT, &MilFinderContext);
MmodAllocResult(MilSystem, M_DEFAULT, &MilFinderResult);
MmodDefine(MilFinderContext, M_IMAGE, MilFinderImage[eModel], M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MmodControl(MilFinderContext, M_ALL, M_NUMBER, M_ALL);
MmodControl(MilFinderContext, M_ALL, M_ACCEPTANCE, FINDER_ACCEPTANCE);
MIL_ID MilFinderFixturingOffset;
McalAlloc(MilSystem, M_FIXTURING_OFFSET, M_DEFAULT, &MilFinderFixturingOffset);
McalFixture(M_NULL, MilFinderFixturingOffset, M_LEARN_OFFSET,
M_MODEL_MOD, MilFinderContext, 0, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MmodPreprocess(MilFinderContext, M_DEFAULT);
MdispSelect(MilDisplay, MilFinderImage[eModel]);
MgraColor(M_DEFAULT, SELECTED_OCCURRENCE_COLOR);
MmodDraw(M_DEFAULT, MilFinderContext, MilGraphicList, M_DRAW_EDGES + M_DRAW_BOX + M_DRAW_POSITION, 0, M_DEFAULT);
MosPrintf(MIL_TEXT("A scanned object sample, acquired using a third-party 3D scanner, \n"));
MosPrintf(MIL_TEXT("is restored. A top-view depth-map of the object is generated and \n"));
MosPrintf(MIL_TEXT("used to define a 2-dimensional Model Finder model (displayed \n"));
MosPrintf(MIL_TEXT("in green). \n\n"));
MosPrintf(MIL_TEXT("Press any key to continue. \n\n"));
MosGetch();
MilPtCldCtn[eScene] = MbufAllocContainer(MilSystem, M_PROC+M_DISP, M_DEFAULT, M_UNIQUE_ID);
MilDepthMap[eScene] = MbufAlloc2d(MilSystem, DEPTHMAP_SIZE_X, DEPTHMAP_SIZE_Y, M_UNSIGNED + 16, M_IMAGE + M_DISP + M_PROC, M_UNIQUE_ID);
MbufAlloc2d(MilSystem, DEPTHMAP_SIZE_X, DEPTHMAP_SIZE_Y, M_UNSIGNED + 8, M_IMAGE + M_DISP + M_PROC, &MilFinderImage[eScene]);
M3dregAlloc(MilSystem, M_PAIRWISE_REGISTRATION_CONTEXT, M_DEFAULT, &MilRegistrationContext);
M3dregAllocResult(MilSystem, M_PAIRWISE_REGISTRATION_RESULT, M_DEFAULT, &MilRegistrationResult);
M3dgeoAlloc(MilSystem, M_TRANSFORMATION_MATRIX, M_DEFAULT, &MilPreregistrationMatrix);
MIL_ID MilSubsampleContext = M_NULL;
M3dregInquire(MilRegistrationContext, M_DEFAULT, M_SUBSAMPLE_CONTEXT_ID, &MilSubsampleContext);
M3dimControl(MilSubsampleContext, M_SUBSAMPLE_MODE, M_SUBSAMPLE_DECIMATE);
M3dimControl(MilSubsampleContext, M_STEP_SIZE_X, DECIMATION_STEP);
M3dimControl(MilSubsampleContext, M_STEP_SIZE_Y, DECIMATION_STEP);
M3dregControl(MilRegistrationContext, M_DEFAULT, M_SUBSAMPLE, M_ENABLE);
M3dregControl(MilRegistrationContext, M_ALL, M_OVERLAP, OVERLAP);
M3dregControl(MilRegistrationContext, M_DEFAULT, M_MAX_ITERATIONS, MAX_ITERATIONS);
M3dregControl(MilRegistrationContext, M_DEFAULT, M_ERROR_MINIMIZATION_METRIC, ERROR_MINIMIZATION_METRIC);
M3dimCalibrateDepthMap(MilBox, MilDepthMap[eScene], M_NULL, M_NULL, M_DEFAULT, M_NEGATIVE, M_DEFAULT);
MIL_UNIQUE_BUF_ID MilTransformedModel = MbufAllocContainer(MilSystem, M_PROC+M_DISP, M_DEFAULT, M_UNIQUE_ID);
for(MIL_INT iScene = 0; iScene < NUM_SCENE_SCANS; iScene++)
{
MbufImport(FILE_POINT_CLOUD[eScene + iScene], M_DEFAULT, M_LOAD, MilSystem, &MilPtCldCtn[eScene]);
if(MilDisplay3d)
{ M3ddispControl(MilDisplay3d, M_UPDATE, M_ENABLE); }
MIL_INT Scene_SizeX = MbufInquireContainer(MilPtCldCtn[eScene], M_COMPONENT_RANGE, M_SIZE_X, M_NULL);
MIL_INT Scene_SizeY = MbufInquireContainer(MilPtCldCtn[eScene], M_COMPONENT_RANGE, M_SIZE_Y, M_NULL);
MIL_ID MilReflectance = MbufAllocComponent(MilPtCldCtn[eScene], 3, Scene_SizeX, Scene_SizeY, M_UNSIGNED + 8, M_IMAGE + M_PROC + M_DISP, M_COMPONENT_REFLECTANCE, M_NULL);
MbufClear(MilReflectance,M_COLOR_BRIGHT_GRAY);
if(MilDisplay3d)
{ M3ddispSelect(MilDisplay3d, MilPtCldCtn[eScene], M_SELECT, M_DEFAULT); }
M3dimProject(MilPtCldCtn[eScene], MilDepthMap[eScene], M_NULL, M_DEFAULT, M_MAX_Z, M_DEFAULT, M_DEFAULT);
MapDynamicRangeTo8Bits(MilSystem, MilDepthMap[eScene], MilFinderImage[eScene]);
MgraClear(M_DEFAULT, MilGraphicList);
MdispSelect(MilDisplay, MilFinderImage[eScene]);
MmodFind(MilFinderContext, MilFinderImage[eScene], MilFinderResult);
MgraColor(M_DEFAULT, FOUND_OCCURRENCES_COLOR);
MmodDraw(M_DEFAULT, MilFinderResult, MilGraphicList, M_DRAW_EDGES, M_ALL, M_DEFAULT);
if(!FindPreregistrationWithTopFoundOccurrence(MilSystem, MilPtCldCtn, ModelMeanElevation, MilDepthMap,
MilFinderFixturingOffset,
MilFinderResult, MilPreregistrationMatrix,
&TopOccurrenceIdx))
{
MosPrintf(MIL_TEXT("No occurrence found. Press any key to continue.\n\n"));
MosGetch();
continue;
}
MgraColor(M_DEFAULT, SELECTED_OCCURRENCE_COLOR);
MmodDraw(M_DEFAULT, MilFinderResult, MilGraphicList, M_DRAW_EDGES + M_DRAW_BOX, TopOccurrenceIdx, M_DEFAULT);
if(iScene == 0)
{
MosPrintf(MIL_TEXT("The stack of objects has been scanned. \n\n"));
}
else
{
MosPrintf(MIL_TEXT("The first object located was removed from the stack of objects \n"));
MosPrintf(MIL_TEXT("and a new scan was done. \n\n"));
}
MosPrintf(MIL_TEXT("STEP 1 : Object occurrences that are on top are located in the 2-dimensional \n"));
MosPrintf(MIL_TEXT(" depth-map (left). The top-most occurrence is detected (displayed\n")
MIL_TEXT(" in green). \n\n"));
MosPrintf(MIL_TEXT("STEP 2 : Using its 2D position, the occurence's 3D pose is estimated in the\n"));
MosPrintf(MIL_TEXT(" 3D point cloud using 3D registration with the 3D model sample.\n\n"));
MosPrintf(MIL_TEXT("Estimating 3D pose.."));
M3dgeoMatrixSetTransform(MilPreregistrationMatrix, M_INVERSE, (MIL_DOUBLE) MilPreregistrationMatrix, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dregSetLocation(MilRegistrationContext, eScene, eModel, MilPreregistrationMatrix, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dregCalculate(MilRegistrationContext,
MilPtCldCtn, 2,
MilRegistrationResult, M_DEFAULT);
M3dregGetResult(MilRegistrationResult, eScene, M_REGISTRATION_COMPLETED, &RegistrationCompleted);
MosPrintf(MIL_TEXT(".done\n"));
SPose RegistrationPose;
if(RegistrationCompleted)
{
ExtractRegisteredDepthMaps(MilSystem, MilPtCldCtn, MilTransformedModel, MilDepthMap, MilRegistrationResult, RegistrationPose);
if(MilDisplay3d)
{ M3ddispSelect(MilDisplay3d, MilTransformedModel, M_ADD, M_DEFAULT); }
MosPrintf(MIL_TEXT("\tDisplayed in green in the point cloud.\n"));
MosPrintf(MIL_TEXT("\t(X, Y, Z) : (%9.4f mm ,%9.4f mm ,%9.4f mm ) \n"), RegistrationPose.Tx, RegistrationPose.Ty, RegistrationPose.Tz);
MosPrintf(MIL_TEXT("\t(Roll, Pitch, Yaw): (%9.4f deg,%9.4f deg,%9.4f deg) \n\n"), RegistrationPose.Rx, RegistrationPose.Ry, RegistrationPose.Rz);
}
else
{
MosPrintf(MIL_TEXT("Occurrence's pose was not successfully determined. \n\n"));
}
if(iScene < NUM_SCENE_SCANS -1)
{ MosPrintf(MIL_TEXT("Press any key to continue.\n\n")); }
else
{ MosPrintf(MIL_TEXT("Press any key to end.\n\n")); }
MosGetch();
if(MilDisplay3d)
{
M3ddispControl(MilDisplay3d, M_UPDATE, M_DISABLE);
M3ddispSelect(MilDisplay3d, MilPtCldCtn[eScene], M_REMOVE, M_DEFAULT);
M3ddispSelect(MilDisplay3d, MilTransformedModel, M_REMOVE, M_DEFAULT);
}
MbufFreeComponent(MilPtCldCtn[eScene], M_COMPONENT_ALL, M_DEFAULT);
}
MdispSelect(MilDisplay, M_NULL);
M3dgeoFree(MilPreregistrationMatrix);
M3dregFree(MilRegistrationResult);
M3dregFree(MilRegistrationContext);
McalFree(MilFinderFixturingOffset);
MmodFree(MilFinderResult);
MmodFree(MilFinderContext);
for(MIL_INT i = 0; i < 2; i++)
{
MbufFree(MilFinderImage[i]);
}
MgraFree(MilGraphicList);
if(MilDisplay3d)
M3ddispFree(MilDisplay3d);
return 0;
}
void DefineModelRoiBox(MIL_ID MilSystem,MIL_ID MilPtCldCtn, MIL_ID MilDepthMap, SBox& ModelRoiBox)
{
MIL_UNIQUE_3DIM_ID MilStatContext = M3dimAlloc(MilSystem, M_STATISTICS_CONTEXT, M_DEFAULT, M_UNIQUE_ID);
MIL_UNIQUE_3DIM_ID MilStatResult = M3dimAllocResult(MilSystem, M_STATISTICS_RESULT, M_DEFAULT, M_UNIQUE_ID);
M3dimControl(MilStatContext, M_BOUNDING_BOX, M_ENABLE);
M3dimControl(MilStatContext, M_BOUNDING_BOX_ALGORITHM, M_ROBUST);
M3dimStat(MilStatContext, MilPtCldCtn, MilStatResult, M_DEFAULT);
MIL_DOUBLE BoxMinX, BoxMinY, BoxMinZ;
MIL_DOUBLE BoxMaxX, BoxMaxY, BoxMaxZ;
M3dimGetResult(MilStatResult, M_MIN_X + M_TYPE_MIL_DOUBLE, &BoxMinX);
M3dimGetResult(MilStatResult, M_MIN_Y , &BoxMinY);
M3dimGetResult(MilStatResult, M_MIN_Z , &BoxMinZ);
M3dimGetResult(MilStatResult, M_MAX_X , &BoxMaxX);
M3dimGetResult(MilStatResult, M_MAX_Y , &BoxMaxY);
M3dimGetResult(MilStatResult, M_MAX_Z , &BoxMaxZ);
BoxMinX -= MODEL_ROI_MARGIN_X;
BoxMinY -= MODEL_ROI_MARGIN_Y;
BoxMinZ -= MODEL_ROI_MARGIN_Z;
BoxMaxX += MODEL_ROI_MARGIN_X;
BoxMaxY += MODEL_ROI_MARGIN_Y;
BoxMaxZ += MODEL_ROI_MARGIN_Z;
MIL_DOUBLE RoiMinX, RoiMinY;
MIL_DOUBLE RoiMaxX, RoiMaxY;
McalTransformCoordinate(MilDepthMap, M_WORLD_TO_PIXEL, BoxMinX, BoxMinY, &RoiMinX, &RoiMinY);
McalTransformCoordinate(MilDepthMap, M_WORLD_TO_PIXEL, BoxMaxX, BoxMaxY, &RoiMaxX, &RoiMaxY);
ModelRoiBox.MinX = BoxMinX;
ModelRoiBox.MinY = BoxMinY;
ModelRoiBox.MinZ = BoxMinZ;
ModelRoiBox.MaxX = BoxMaxX;
ModelRoiBox.MaxY = BoxMaxY;
ModelRoiBox.MaxZ = BoxMaxZ;
ModelRoiBox.OffsetX = static_cast<MIL_INT>(RoiMinX);
ModelRoiBox.OffsetY = static_cast<MIL_INT>(RoiMinY);
ModelRoiBox.SizeX = static_cast<MIL_INT>(RoiMaxX - RoiMinX);
ModelRoiBox.SizeY = static_cast<MIL_INT>(RoiMaxY - RoiMinY);
}
bool FindPreregistrationWithTopFoundOccurrence(MIL_ID MilSystem,
MIL_UNIQUE_BUF_ID MilPtCldCtn[],
MIL_DOUBLE ModelMeanElevation,
MIL_UNIQUE_BUF_ID MilDepthMap[],
MIL_ID MilFinderFixturingOffset,
MIL_ID MilFinderResult,
MIL_ID MilPreregistrationMatrix,
MIL_INT* pTopOccIdx)
{
MIL_INT NumOccurrences;
MmodGetResult(MilFinderResult, M_GENERAL, M_NUMBER + M_TYPE_MIL_INT, &NumOccurrences);
if(NumOccurrences == 0) return false;
M3dimProject(MilPtCldCtn[eModel], MilDepthMap[eModel], M_NULL, M_POINT_BASED, M_MAX_Z, M_DEFAULT, M_DEFAULT);
MIL_DOUBLE CurTopOccMeanElevation = 0.0;
MIL_UNIQUE_BUF_ID MilTransformedScene = MbufAllocContainer(MilSystem, M_PROC, M_DEFAULT, M_UNIQUE_ID);
MIL_UNIQUE_3DGEO_ID MilFixturingMatrix = M3dgeoAlloc(MilSystem, M_TRANSFORMATION_MATRIX, M_DEFAULT, M_UNIQUE_ID);
MIL_UNIQUE_BUF_ID MaskedScene = MbufAlloc2d(MilSystem, DEPTHMAP_SIZE_X, DEPTHMAP_SIZE_Y, M_UNSIGNED + 16, M_PROC + M_IMAGE + M_DISP, M_UNIQUE_ID);
MIL_ID StatResultId = M3dmetAllocResult(MilSystem, M_STATISTICS_RESULT, M_DEFAULT, M_NULL);
for(MIL_INT iOcc = 0; iOcc < NumOccurrences; iOcc++)
{
McalFixture(MilFixturingMatrix, MilFinderFixturingOffset, M_MOVE_RELATIVE,
M_RESULT_MOD, MilFinderResult, iOcc, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dgeoMatrixSetTransform(MilFixturingMatrix, M_INVERSE, (MIL_DOUBLE)MilFixturingMatrix, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
M3dimMatrixTransform(MilPtCldCtn[eScene], MilTransformedScene, MilFixturingMatrix, M_DEFAULT);
M3dimProject(MilTransformedScene, MilDepthMap[eScene], M_NULL, M_DEFAULT, M_MAX_Z,M_DEFAULT, M_DEFAULT);
MbufClear(MaskedScene, DEPTHMAP_MISSING_DATA);
MbufCopyCond(MilDepthMap[eScene], MaskedScene, MilDepthMap[eModel], M_NOT_EQUAL, DEPTHMAP_MISSING_DATA);
McalAssociate(MilDepthMap[eScene], MaskedScene, M_DEFAULT);
MIL_DOUBLE OccMeanElevation;
M3dmetStat(M_STAT_CONTEXT_MEAN, MaskedScene, M_XY_PLANE, StatResultId, M_SIGNED_DISTANCE_Z_TO_SURFACE, M_ALL, M_NULL, M_NULL, M_DEFAULT);
M3dmetGetResult(StatResultId, M_STAT_MEAN, &OccMeanElevation);
if((iOcc == 0) || (iOcc > 0 && (OccMeanElevation < CurTopOccMeanElevation)))
{
*pTopOccIdx = iOcc;
CurTopOccMeanElevation = OccMeanElevation;
M3dgeoMatrixSetTransform( MilFixturingMatrix, M_INVERSE, (MIL_DOUBLE)MilFixturingMatrix, M_DEFAULT, M_DEFAULT, M_DEFAULT, M_DEFAULT);
MIL_DOUBLE OffsetZ = CurTopOccMeanElevation - ModelMeanElevation;
M3dgeoMatrixSetTransform(MilFixturingMatrix, M_TRANSLATION, 0.0, 0.0, OffsetZ, M_DEFAULT, M_COMPOSE_WITH_CURRENT);
M3dgeoCopy(MilFixturingMatrix, MilPreregistrationMatrix, M_TRANSFORMATION_MATRIX, M_DEFAULT);
}
}
M3dmetFree(StatResultId);
M3dimProject(MilPtCldCtn[eScene], MilDepthMap[eScene], M_NULL, M_DEFAULT,M_MAX_Z, M_DEFAULT, M_DEFAULT);
return true;
}
void ExtractRegisteredDepthMaps(MIL_ID MilSystem, MIL_UNIQUE_BUF_ID MilPtCldCtn[], MIL_UNIQUE_BUF_ID& MilTransformedModel, MIL_UNIQUE_BUF_ID MilDepthMap[], MIL_ID MilResult, SPose& Pose)
{
MIL_UNIQUE_3DGEO_ID MatrixId = M3dgeoAlloc(MilSystem, M_TRANSFORMATION_MATRIX, M_DEFAULT, M_UNIQUE_ID);
M3dregCopyResult(MilResult, eModel, eScene, MatrixId, M_REGISTRATION_MATRIX, M_DEFAULT);
M3dimMatrixTransform(MilPtCldCtn[eModel], MilTransformedModel, MatrixId, M_DEFAULT);
M3dimProject(MilTransformedModel, MilDepthMap[eModel], M_NULL, M_DEFAULT, M_MAX_Z, M_DEFAULT, M_DEFAULT);
GetPose(MatrixId, Pose);
}
void MapDynamicRangeTo8Bits(MIL_ID MilSystem, MIL_ID MilSrcImage, MIL_ID MilTgtImage)
{
MIL_ID MilRegion = MbufAlloc2d(MilSystem,
MbufInquire(MilSrcImage, M_SIZE_X, M_NULL),
MbufInquire(MilSrcImage, M_SIZE_Y, M_NULL),
8 + M_UNSIGNED, M_IMAGE + M_PROC, M_NULL);
MimBinarize(MilSrcImage, MilRegion, M_FIXED + M_NOT_EQUAL, DEPTHMAP_MISSING_DATA, M_NULL);
MbufSetRegion(MilSrcImage, MilRegion, M_DEFAULT, M_RASTERIZE, M_DEFAULT);
MbufClear(MilTgtImage, 0.0);
MimRemap(M_DEFAULT, MilSrcImage, MilTgtImage, M_FIT_SRC_DATA);
MbufSetRegion(MilSrcImage, M_NULL, M_DEFAULT, M_DELETE, M_DEFAULT);
MbufFree(MilRegion);
}
void GetPose(MIL_ID MilMatrixId, SPose& Pose)
{
M3dgeoMatrixGetTransform(MilMatrixId, M_TRANSLATION, &Pose.Tx, &Pose.Ty, &Pose.Tz, M_NULL,M_DEFAULT);
M3dgeoMatrixGetTransform(MilMatrixId, M_ROTATION_XYZ, &Pose.Rx, &Pose.Ry, &Pose.Rz, M_NULL,M_DEFAULT);
if(fabs(Pose.Rx) > 180.0) Pose.Rx = fmod(Pose.Rx - 360.0, 360.0);
if(fabs(Pose.Ry) > 180.0) Pose.Ry = fmod(Pose.Ry - 360.0, 360.0);
if(fabs(Pose.Rz) > 180.0) Pose.Rz = fmod(Pose.Rz - 360.0, 360.0);
}
MIL_ID Alloc3dDisplayId(MIL_ID MilSystem)
{
MappControl(M_DEFAULT, M_ERROR, M_PRINT_DISABLE);
MIL_ID MilDisplay3D = M3ddispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_DEFAULT, M_NULL);
MappControl(M_DEFAULT, M_ERROR, M_PRINT_ENABLE);
if(!MilDisplay3D)
{
MosPrintf(MIL_TEXT("\n")
MIL_TEXT("The current system does not support the 3D display.\n\n"));
}
return MilDisplay3D;
}
bool CheckForRequiredMILFile(const MIL_STRING& FileName)
{
MIL_INT FilePresent = M_NO;
MappFileOperation(M_DEFAULT, FileName, M_NULL, M_NULL, M_FILE_EXISTS, M_DEFAULT, &FilePresent);
if(FilePresent == M_NO)
{
MosPrintf(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);
}