using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Matrox.MatroxImagingLibrary;
namespace M3dmap
{
class Program
{
[DllImport("mdispd3d.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr MdepthD3DAlloc(MIL_ID DepthBuffer, MIL_ID IntensityBuffer, MIL_INT DisplaySizeX, MIL_INT DisplaySizeY, double ScaleX, double ScaleY, double ScaleZ, double MinZ, double MaxZ, double MaxDistanceZ, IntPtr WindowHandle);
[DllImport("mdispd3d.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MdispD3DFree(IntPtr DispHandle);
[DllImport("mdispd3d.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MdispD3DShow(IntPtr DispHandle);
[DllImport("mdispd3d.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MdispD3DHide(IntPtr DispHandle);
[DllImport("mdispd3d.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void MdispD3DPrintHelp(IntPtr DispHandle);
static void Main(string[] args)
{
MIL_ID MilApplication = MIL.M_NULL;
MIL_ID MilSystem = MIL.M_NULL;
MIL_ID MilDisplay = MIL.M_NULL;
MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL);
DepthCorrectionExample(MilSystem, MilDisplay);
CalibratedCameraExample(MilSystem, MilDisplay);
MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL);
}
const string REFERENCE_PLANES_SEQUENCE_FILE = MIL.M_IMAGE_PATH + "ReferencePlanes.avi";
const string OBJECT_SEQUENCE_FILE = MIL.M_IMAGE_PATH + "ScannedObject.avi";
const int PEAK_WIDTH_NOMINAL = 10;
const int PEAK_WIDTH_DELTA = 8;
const int MIN_CONTRAST = 140;
static readonly double[] CORRECTED_DEPTHS = { 1.25, 2.50, 3.75, 5.00 };
const double SCALE_FACTOR = 10000.0;
const double CALIB_TEXT_POS_X = 400;
const double CALIB_TEXT_POS_Y = 15;
static void DepthCorrectionExample(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID MilOverlayImage = MIL.M_NULL;
MIL_ID MilImage = MIL.M_NULL;
MIL_ID MilDepthMap = MIL.M_NULL;
MIL_ID MilLaser = MIL.M_NULL;
MIL_ID MilCalibScan = MIL.M_NULL;
MIL_ID MilScan = MIL.M_NULL;
MIL_INT SizeX = 0;
MIL_INT SizeY = 0;
MIL_INT NbReferencePlanes = 0;
MIL_INT NbObjectImages = 0;
MIL_INT n = 0;
double FrameRate = 0.0;
double StartTime = 0.0;
double EndTime = 0.0;
double WaitTime = 0.0;
MIL.MbufDiskInquire(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_SIZE_X, ref SizeX);
MIL.MbufDiskInquire(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_SIZE_Y, ref SizeY);
MIL.MbufDiskInquire(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref NbReferencePlanes);
MIL.MbufDiskInquire(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate);
MIL.MbufDiskInquire(OBJECT_SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref NbObjectImages);
MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP + MIL.M_PROC, ref MilImage);
MIL.MbufClear(MilImage, 0.0);
Console.WriteLine();
Console.WriteLine("DEPTH ANALYSIS:");
Console.WriteLine("---------------");
Console.WriteLine();
Console.WriteLine("This program performs a surface inspection to detect depth");
Console.WriteLine("defects on a wood surface using a laser (sheet-of-light) profiling system.");
Console.WriteLine();
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
MIL.MdispSelect(MilDisplay, MilImage);
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY, MIL.M_ENABLE);
MIL.MdispInquire(MilDisplay, MIL.M_OVERLAY_ID, ref MilOverlayImage);
MIL.MgraControl(MIL.M_DEFAULT, MIL.M_BACKGROUND_MODE, MIL.M_TRANSPARENT);
MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_WHITE);
MIL.M3dmapAlloc(MilSystem, MIL.M_LASER, MIL.M_DEPTH_CORRECTION, ref MilLaser);
MIL.M3dmapAllocResult(MilSystem, MIL.M_LASER_CALIBRATION_DATA, MIL.M_DEFAULT, ref MilCalibScan);
MIL_ID MilPeakLocator = MIL.M_NULL;
MIL.M3dmapInquire(MilLaser, MIL.M_CONTEXT, MIL.M_LOCATE_PEAK_1D_CONTEXT_ID + MIL.M_TYPE_MIL_ID, ref MilPeakLocator);
MIL.MimControl(MilPeakLocator, MIL.M_PEAK_WIDTH_NOMINAL, PEAK_WIDTH_NOMINAL);
MIL.MimControl(MilPeakLocator, MIL.M_PEAK_WIDTH_DELTA, PEAK_WIDTH_DELTA);
MIL.MimControl(MilPeakLocator, MIL.M_MINIMUM_CONTRAST, MIN_CONTRAST);
MIL.MbufImportSequence(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
for (n = 0; n < NbReferencePlanes; n++)
{
string CalibString;
MIL.MbufImportSequence(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ);
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT);
CalibString = string.Format("Reference plane {0}: {1:0.00} mm", n + 1, CORRECTED_DEPTHS[n]);
MIL.MgraText(MIL.M_DEFAULT, MilOverlayImage, CALIB_TEXT_POS_X, CALIB_TEXT_POS_Y, CalibString);
MIL.M3dmapControl(MilLaser, MIL.M_DEFAULT, MIL.M_CORRECTED_DEPTH, CORRECTED_DEPTHS[n] * SCALE_FACTOR);
MIL.M3dmapAddScan(MilLaser, MilCalibScan, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref EndTime);
WaitTime = (1.0 / FrameRate) - (EndTime - StartTime);
if (WaitTime > 0)
{
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref WaitTime);
}
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
}
MIL.MbufImportSequence(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE);
MIL.M3dmapCalibrate(MilLaser, MilCalibScan, MIL.M_NULL, MIL.M_DEFAULT);
Console.WriteLine("The laser profiling system has been calibrated using 4 reference");
Console.WriteLine("planes of known heights.");
Console.WriteLine();
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
Console.WriteLine("The wood surface is being scanned.");
Console.WriteLine();
MIL.M3dmapFree(MilCalibScan);
MilCalibScan = MIL.M_NULL;
MIL.M3dmapAllocResult(MilSystem, MIL.M_DEPTH_CORRECTED_DATA, MIL.M_DEFAULT, ref MilScan);
MIL.MbufDiskInquire(OBJECT_SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate);
MIL.MbufImportSequence(OBJECT_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT);
for (n = 0; n < NbObjectImages; n++)
{
MIL.MbufImportSequence(OBJECT_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ);
MIL.M3dmapAddScan(MilLaser, MilScan, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref EndTime);
WaitTime = (1.0 / FrameRate) - (EndTime - StartTime);
if (WaitTime > 0)
{
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref WaitTime);
}
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
}
MIL.MbufImportSequence(OBJECT_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE);
MIL.MbufAlloc2d(MilSystem, SizeX, NbObjectImages, 16 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilDepthMap);
MIL.M3dmapExtract(MilScan, MilDepthMap, MIL.M_NULL, MIL.M_CORRECTED_DEPTH_MAP, MIL.M_DEFAULT, MIL.M_DEFAULT);
SetupColorDisplay(MilSystem, MilDisplay, MIL.MbufInquire(MilDepthMap, MIL.M_SIZE_BIT, MIL.M_NULL));
MIL.MdispSelect(MilDisplay, MilDepthMap);
MIL.MdispInquire(MilDisplay, MIL.M_OVERLAY_ID, ref MilOverlayImage);
Console.WriteLine("The pseudo-color depth map of the surface is displayed.");
Console.WriteLine();
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
PerformBlobAnalysis(MilSystem, MilDisplay, MilOverlayImage, MilDepthMap);
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
MIL.MdispLut(MilDisplay, MIL.M_DEFAULT);
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT);
MIL.M3dmapFree(MilScan);
MIL.M3dmapFree(MilLaser);
MIL.MbufFree(MilDepthMap);
MIL.MbufFree(MilImage);
}
const double EXPECTED_HEIGHT = 3.4;
const double DEFECT_THRESHOLD = 0.2;
const double SATURATED_DEFECT = 1.0;
const int MIN_BLOB_RADIUS = 3;
const double TEXT_H_OFFSET_1 = -50;
const double TEXT_V_OFFSET_1 = -6;
const double TEXT_H_OFFSET_2 = -30;
const double TEXT_V_OFFSET_2 = 6;
static void PerformBlobAnalysis(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilOverlayImage, MIL_ID MilDepthMap)
{
MIL_ID MilBinImage = MIL.M_NULL;
MIL_ID MilBlobFeatureList = MIL.M_NULL;
MIL_ID MilBlobResult = MIL.M_NULL;
MIL_INT SizeX = 0;
MIL_INT SizeY = 0;
MIL_INT TotalBlobs = 0;
MIL_INT n = 0;
MIL_INT[] MinPixels = null;
double DefectThreshold = 0.0;
double[] CogX = null;
double[] CogY = null;
MIL.MbufInquire(MilDepthMap, MIL.M_SIZE_X, ref SizeX);
MIL.MbufInquire(MilDepthMap, MIL.M_SIZE_Y, ref SizeY);
MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 1 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilBinImage);
DefectThreshold = (EXPECTED_HEIGHT - DEFECT_THRESHOLD) * SCALE_FACTOR;
MIL.MimBinarize(MilDepthMap, MilBinImage, MIL.M_FIXED + MIL.M_LESS_OR_EQUAL, DefectThreshold, MIL.M_NULL);
MIL.MimOpen(MilBinImage, MilBinImage, MIN_BLOB_RADIUS, MIL.M_BINARY);
MIL.MblobAllocFeatureList(MilSystem, ref MilBlobFeatureList);
MIL.MblobSelectFeature(MilBlobFeatureList, MIL.M_CENTER_OF_GRAVITY);
MIL.MblobSelectFeature(MilBlobFeatureList, MIL.M_MIN_PIXEL);
MIL.MblobAllocResult(MilSystem, ref MilBlobResult);
MIL.MblobCalculate(MilBinImage, MilDepthMap, MilBlobFeatureList, MilBlobResult);
MIL.MblobGetNumber(MilBlobResult, ref TotalBlobs);
Console.WriteLine("Number of defects: {0}", TotalBlobs);
CogX = new double[TotalBlobs];
CogY = new double[TotalBlobs];
MinPixels = new MIL_INT[TotalBlobs];
if (CogX != null && CogY != null && MinPixels != null)
{
MIL.MblobGetResult(MilBlobResult, MIL.M_CENTER_OF_GRAVITY_X, CogX);
MIL.MblobGetResult(MilBlobResult, MIL.M_CENTER_OF_GRAVITY_Y, CogY);
MIL.MblobGetResult(MilBlobResult, MIL.M_MIN_PIXEL + MIL.M_TYPE_MIL_INT, MinPixels);
MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_RED);
MIL.MblobDraw(MIL.M_DEFAULT, MilBlobResult, MilOverlayImage, MIL.M_DRAW_BLOBS, MIL.M_INCLUDED_BLOBS, MIL.M_DEFAULT);
MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_WHITE);
for (n = 0; n < TotalBlobs; n++)
{
double DepthOfDefect;
string DepthString;
DepthOfDefect = EXPECTED_HEIGHT - (MinPixels[n] / SCALE_FACTOR);
DepthString = string.Format("{0:0.00} mm", DepthOfDefect);
Console.WriteLine("Defect #{0}: depth ={1,5:0.00} mm", n, DepthOfDefect);
Console.WriteLine();
MIL.MgraText(MIL.M_DEFAULT, MilOverlayImage, CogX[n] + TEXT_H_OFFSET_1, CogY[n] + TEXT_V_OFFSET_1, "Defect depth");
MIL.MgraText(MIL.M_DEFAULT, MilOverlayImage, CogX[n] + TEXT_H_OFFSET_2, CogY[n] + TEXT_V_OFFSET_2, DepthString);
}
}
else
{
Console.WriteLine("Error: Not enough memory.");
Console.WriteLine();
}
MIL.MblobFree(MilBlobResult);
MIL.MblobFree(MilBlobFeatureList);
MIL.MbufFree(MilBinImage);
}
const double BLUE_HUE = 171.0;
const double RED_HUE = 0.0;
const int FULL_SATURATION = 255;
const int HALF_LUMINANCE = 128;
static void SetupColorDisplay(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_INT SizeBit)
{
MIL_ID MilRampLut1Band = MIL.M_NULL;
MIL_ID MilRampLut3Band = MIL.M_NULL;
MIL_ID MilColorImage = MIL.M_NULL;
MIL_INT DefectGrayLevel = 0;
MIL_INT ExpectedGrayLevel = 0;
MIL_INT NbGrayLevels;
NbGrayLevels = (MIL_INT)(1 << (int)SizeBit);
MIL.MbufAlloc1d(MilSystem, NbGrayLevels, 8 + MIL.M_UNSIGNED, MIL.M_LUT, ref MilRampLut1Band);
DefectGrayLevel = (MIL_INT)((EXPECTED_HEIGHT - SATURATED_DEFECT) * SCALE_FACTOR);
ExpectedGrayLevel = (MIL_INT)(EXPECTED_HEIGHT * SCALE_FACTOR);
MIL.MgenLutRamp(MilRampLut1Band, 0, RED_HUE, DefectGrayLevel, RED_HUE);
MIL.MgenLutRamp(MilRampLut1Band, DefectGrayLevel, RED_HUE, ExpectedGrayLevel, BLUE_HUE);
MIL.MgenLutRamp(MilRampLut1Band, ExpectedGrayLevel, BLUE_HUE, NbGrayLevels - 1, BLUE_HUE);
MIL.MbufAllocColor(MilSystem, 3, NbGrayLevels, 1, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE, ref MilColorImage);
MIL.MbufClear(MilColorImage, MIL.M_RGB888(0, FULL_SATURATION, HALF_LUMINANCE));
MIL.MbufCopyColor2d(MilRampLut1Band, MilColorImage, 0, 0, 0, 0, 0, 0, NbGrayLevels, 1);
MIL.MimConvert(MilColorImage, MilColorImage, MIL.M_HSL_TO_RGB);
MIL.MbufAllocColor(MilSystem, 3, NbGrayLevels, 1, 8 + MIL.M_UNSIGNED, MIL.M_LUT, ref MilRampLut3Band);
MIL.MbufCopy(MilColorImage, MilRampLut3Band);
MIL.MdispLut(MilDisplay, MilRampLut3Band);
MIL.MbufFree(MilRampLut1Band);
MIL.MbufFree(MilRampLut3Band);
MIL.MbufFree(MilColorImage);
}
const string GRID_FILENAME = MIL.M_IMAGE_PATH + "GridForLaser.mim";
const string LASERLINE_FILENAME = MIL.M_IMAGE_PATH + "LaserLine.mim";
const string OBJECT2_SEQUENCE_FILE = MIL.M_IMAGE_PATH + "Cookie.avi";
static readonly MIL_INT GRID_NB_ROWS = 13;
static readonly MIL_INT GRID_NB_COLS = 12;
const double GRID_ROW_SPACING = 5.0;
const double GRID_COL_SPACING = 5.0;
const double CONVEYOR_SPEED = -0.2;
static readonly MIL_INT DEPTH_MAP_SIZE_X = 480;
static readonly MIL_INT DEPTH_MAP_SIZE_Y = 480;
const double GAP_DEPTH = 1.5;
static readonly MIL_INT D3D_DISPLAY_SIZE_X = 640;
static readonly MIL_INT D3D_DISPLAY_SIZE_Y = 480;
static readonly MIL_INT PEAK_WIDTH_NOMINAL_2 = 9;
static readonly MIL_INT PEAK_WIDTH_DELTA_2 = 7;
static readonly MIL_INT MIN_CONTRAST_2 = 75;
const double MIN_HEIGHT_THRESHOLD = 1.0;
static void CalibratedCameraExample(MIL_ID MilSystem, MIL_ID MilDisplay)
{
MIL_ID MilOverlayImage = MIL.M_NULL;
MIL_ID MilImage = MIL.M_NULL;
MIL_ID MilCalibration = MIL.M_NULL;
MIL_ID DepthMapId = MIL.M_NULL;
MIL_ID LaserId = MIL.M_NULL;
MIL_ID CalibScanId = MIL.M_NULL;
MIL_ID ScanId = MIL.M_NULL;
MIL_INT CalibrationStatus = 0;
MIL_INT SizeX = 0;
MIL_INT SizeY = 0;
MIL_INT NumberOfImages = 0;
MIL_INT n = 0;
double FrameRate = 0.0;
double StartTime = 0.0;
double EndTime = 0.0;
double WaitTime = 0.0;
double Volume = 0.0;
double VolumeError = 0.0;
Console.WriteLine();
Console.WriteLine("3D PROFILING AND VOLUME ANALYSIS:");
Console.WriteLine("---------------------------------");
Console.WriteLine();
Console.WriteLine("This program generates fully corrected 3d data of a");
Console.WriteLine("scanned cookie and computes its volume.");
Console.WriteLine("The laser (sheet-of-light) profiling system uses a");
Console.WriteLine("3d-calibrated camera.");
Console.WriteLine();
MIL.MbufRestore(GRID_FILENAME, MilSystem, ref MilImage);
MIL.MdispSelect(MilDisplay, MilImage);
Console.WriteLine("Calibrating the camera...");
Console.WriteLine();
MIL.MbufInquire(MilImage, MIL.M_SIZE_X, ref SizeX);
MIL.MbufInquire(MilImage, MIL.M_SIZE_Y, ref SizeY);
MIL.McalAlloc(MilSystem, MIL.M_TSAI_BASED, MIL.M_DEFAULT, ref MilCalibration);
MIL.McalGrid(MilCalibration, MilImage, 0.0, 0.0, 0.0, GRID_NB_ROWS, GRID_NB_COLS, GRID_ROW_SPACING, GRID_COL_SPACING, MIL.M_DEFAULT, MIL.M_CHESSBOARD_GRID);
MIL.McalInquire(MilCalibration, MIL.M_CALIBRATION_STATUS + MIL.M_TYPE_MIL_INT, ref CalibrationStatus);
if (CalibrationStatus != MIL.M_CALIBRATED)
{
MIL.McalFree(MilCalibration);
MIL.MbufFree(MilImage);
Console.WriteLine("Camera calibration failed.");
Console.WriteLine("Press <Enter> to end.");
Console.WriteLine();
Console.ReadKey();
return;
}
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY, MIL.M_ENABLE);
MIL.MdispInquire(MilDisplay, MIL.M_OVERLAY_ID, ref MilOverlayImage);
MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_GREEN);
MIL.McalDraw(MIL.M_DEFAULT, MilCalibration, MilOverlayImage, MIL.M_DRAW_IMAGE_POINTS, MIL.M_DEFAULT, MIL.M_DEFAULT);
Console.WriteLine("The camera was calibrated using a chessboard grid.");
Console.WriteLine();
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
MIL.MdispControl(MilDisplay, MIL.M_OVERLAY, MIL.M_DISABLE);
MIL.MbufLoad(LASERLINE_FILENAME, MilImage);
MIL.M3dmapAlloc(MilSystem, MIL.M_LASER, MIL.M_CALIBRATED_CAMERA_LINEAR_MOTION, ref LaserId);
MIL.M3dmapAllocResult(MilSystem, MIL.M_LASER_CALIBRATION_DATA, MIL.M_DEFAULT, ref CalibScanId);
MIL_ID MilPeakLocator = MIL.M_NULL;
MIL.M3dmapInquire(LaserId, MIL.M_CONTEXT, MIL.M_LOCATE_PEAK_1D_CONTEXT_ID + MIL.M_TYPE_MIL_ID, ref MilPeakLocator);
MIL.MimControl(MilPeakLocator, MIL.M_PEAK_WIDTH_NOMINAL, PEAK_WIDTH_NOMINAL_2);
MIL.MimControl(MilPeakLocator, MIL.M_PEAK_WIDTH_DELTA, PEAK_WIDTH_DELTA_2);
MIL.MimControl(MilPeakLocator, MIL.M_MINIMUM_CONTRAST, MIN_CONTRAST_2);
MIL.M3dmapAddScan(LaserId, CalibScanId, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.M3dmapCalibrate(LaserId, CalibScanId, MilCalibration, MIL.M_DEFAULT);
Console.WriteLine("The laser profiling system has been calibrated using the image");
Console.WriteLine("of one laser line.");
Console.WriteLine();
Console.WriteLine("Press <Enter> to continue.");
Console.WriteLine();
Console.ReadKey();
MIL.M3dmapFree(CalibScanId);
CalibScanId = MIL.M_NULL;
MIL.M3dmapAllocResult(MilSystem, MIL.M_POINT_CLOUD_CONTAINER, MIL.M_DEFAULT, ref ScanId);
MIL.M3dmapControl(LaserId, MIL.M_DEFAULT, MIL.M_SCAN_SPEED, CONVEYOR_SPEED);
MIL.MbufDiskInquire(OBJECT2_SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref NumberOfImages);
MIL.MbufDiskInquire(OBJECT2_SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate);
MIL.MbufImportSequence(OBJECT2_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN);
Console.WriteLine("The cookie is being scanned to generate 3d data.");
Console.WriteLine();
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
for (n = 0; n < NumberOfImages; n++)
{
MIL.MbufImportSequence(OBJECT2_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ);
MIL.M3dmapAddScan(LaserId, ScanId, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_POINT_CLOUD_LABEL(1), MIL.M_DEFAULT);
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref EndTime);
WaitTime = (1.0 / FrameRate) - (EndTime - StartTime);
if (WaitTime > 0)
{
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref WaitTime);
}
MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime);
}
MIL.MbufImportSequence(OBJECT2_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE);
MIL.MbufAlloc2d(MilSystem, DEPTH_MAP_SIZE_X, DEPTH_MAP_SIZE_Y, 16 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref DepthMapId);
MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_AUTO_SCALE_XY, MIL.M_CLIP);
MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_FILL_MODE, MIL.M_X_THEN_Y);
MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_FILL_SHARP_ELEVATION, MIL.M_MIN);
MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_FILL_SHARP_ELEVATION_DEPTH, GAP_DEPTH);
MIL.M3dmapSetBox(ScanId, MIL.M_EXTRACTION_BOX, MIL.M_BOUNDING_BOX, MIL.M_ALL, MIL.M_DEFAULT, MIL.M_DEFAULT,
MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.M3dmapExtract(ScanId, DepthMapId, MIL.M_NULL, MIL.M_CORRECTED_DEPTH_MAP, MIL.M_DEFAULT, MIL.M_DEFAULT);
MIL.M3dmapStat(DepthMapId, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_VOLUME, MIL.M_DEFAULT, MIL.M_DEFAULT, ref Volume);
MIL.M3dmapStat(DepthMapId, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_VOLUME, MIN_HEIGHT_THRESHOLD,
MIL.M_DEFAULT, ref VolumeError);
Volume -= VolumeError;
Console.WriteLine("Fully corrected 3d data of the cookie is displayed.");
Console.WriteLine();
IntPtr DispHandle;
DispHandle = MdepthD3DAlloc(DepthMapId, MIL.M_NULL, D3D_DISPLAY_SIZE_X, D3D_DISPLAY_SIZE_Y, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, IntPtr.Zero);
if (DispHandle != IntPtr.Zero)
{
MIL.MdispControl(MilDisplay, MIL.M_WINDOW_SHOW, MIL.M_DISABLE);
MdispD3DShow(DispHandle);
Console.WriteLine("D3D display controls:");
Console.WriteLine(" .Left click\tmove object");
Console.WriteLine(" .Right click\trotate object");
Console.WriteLine(" .Scroll wheel\tzoom");
Console.WriteLine(" .R\t\tstart/stop animation");
Console.WriteLine(" .P\t\tenable/disable point cloud");
Console.WriteLine();
}
else
{
MIL.MdispControl(MilDisplay, MIL.M_VIEW_MODE, MIL.M_AUTO_SCALE);
MIL.MdispSelect(MilDisplay, DepthMapId);
}
Console.WriteLine("Volume of the cookie is {0,4:0.0} cm^3.", -Volume / 1000.0);
Console.WriteLine();
Console.WriteLine("Press <Enter> to end.");
Console.WriteLine();
Console.ReadKey();
if (DispHandle != IntPtr.Zero)
{
MdispD3DHide(DispHandle);
MdispD3DFree(DispHandle);
}
MIL.M3dmapFree(ScanId);
MIL.M3dmapFree(LaserId);
MIL.McalFree(MilCalibration);
MIL.MbufFree(DepthMapId);
MIL.MbufFree(MilImage);
}
}
}