Click here to show toolbars of the Web Online Help System: show toolbars |
//*************************************************************************************** // // File name: TireStringRead.cpp // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: Example that reads characters on a tire using 3d data. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved #include "TireStringRead.h" //**************************************************************************** // Example description. //**************************************************************************** void PrintHeader() { MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")); MosPrintf(MIL_TEXT("TireStringRead\n\n")); MosPrintf(MIL_TEXT("[SYNOPSIS]\n")); MosPrintf(MIL_TEXT("This example demonstrates the reading of strings on a tire using ") MIL_TEXT("3d\nsheet-of-light profiling. The system consists of two cameras ") MIL_TEXT("and one\nlaser. Note that during the setup of the grab, the ") MIL_TEXT("cameras were\nsynchronized so the same laser scan was provided ") MIL_TEXT("to all cameras\nat the same time.\n")); MosPrintf(MIL_TEXT("\n\n")); MosPrintf(MIL_TEXT("[MODULES USED]\n")); MosPrintf(MIL_TEXT("Modules used: Application, system, display, buffer, ") MIL_TEXT("graphic, \nimage processing, calibration,")); MosPrintf(MIL_TEXT(" 3d reconstruction, model finder, \n")); MosPrintf(MIL_TEXT("measurement, string reader. \n")); } //***************************************************************************** // Main. //***************************************************************************** int MosMain(void) { PrintHeader(); // Allocate the MIL application. MIL_ID MilApplication = MappAlloc(M_NULL, M_DEFAULT, M_NULL); // Initialization. CExampleManagerFor3D* pExampleMngrFor3D = MakeExampleManager(); if (!pExampleMngrFor3D) { MappFree(MilApplication); return -1; } MosPrintf(MIL_TEXT("Press <Enter> to start.\n\n")); MosGetch(); //....................................................................... // 1. To calibrate the setup, the first step is to calibrate the cameras. // Camera calibration specifications. const MIL_DOUBLE COL_SPACING [NUM_CAMERAS] = { 10.0, 10.0 }; const MIL_DOUBLE ROW_SPACING [NUM_CAMERAS] = { 10.0, 10.0 }; const MIL_INT NB_ROWS [NUM_CAMERAS] = { 22, 22 }; const MIL_INT NB_COLS [NUM_CAMERAS] = { 18, 18 }; const MIL_DOUBLE CORNER_HINT_X [NUM_CAMERAS] = { 1142, 1420 }; const MIL_DOUBLE CORNER_HINT_Y [NUM_CAMERAS] = { 259, 16 }; const MIL_DOUBLE OFFSET_Z [NUM_CAMERAS] = { -28.49, -28.49 }; const MIL_INT64 CALIBRATION_TYPE [NUM_CAMERAS] = { M_CHESSBOARD_GRID, M_CHESSBOARD_GRID}; const MIL_CONST_TEXT_PTR GRID_IMG_FILENAME [NUM_CAMERAS] = { EX_PATH("Cam1_grid.mim"), EX_PATH("Cam2_grid.mim") }; // Initialize data. SCameraCalibrationInfo CAMERA_CALIBRATION_INFO[NUM_CAMERAS]; for (MIL_INT c = 0; c < NUM_CAMERAS; c++) { SCameraCalibrationInfo& CCI = CAMERA_CALIBRATION_INFO[c]; CCI.CornerHintX = CORNER_HINT_X[c]; CCI.CornerHintY = CORNER_HINT_Y[c]; CCI.OffsetZ = OFFSET_Z[c]; CCI.NbRows = NB_ROWS[c]; CCI.NbCols = NB_COLS[c]; CCI.RowSpacing = ROW_SPACING[c]; CCI.ColSpacing = COL_SPACING[c]; CCI.CalibrationType = CALIBRATION_TYPE[c]; CCI.GridImageFilename = GRID_IMG_FILENAME[c]; CCI.Relocate = NO_RELOCATE; CCI.RelocatedGridImageFilename = NULL; } //................................. // 1.1 Execute cameras calibration. MIL_ID CameraCalibrations[NUM_CAMERAS]; bool CameraCalibrationOk = pExampleMngrFor3D->CalibrateCameras(CAMERA_CALIBRATION_INFO, NUM_CAMERAS, &CameraCalibrations[0]); //.................................................................. // 2. Then continue to calibrate the laser planes (sheets-of-light). if(CameraCalibrationOk) { MosPrintf(MIL_TEXT("Press <Enter> to calibrate laser planes.\n\n")); MosGetch(); // Sheet-of-Light (laser plane) calibration const MIL_INT NUM_REF_PLANES = 7; const MIL_DOUBLE CAL_MIN_CONTRAST [NUM_CAMERAS] = { 30, 30 }; const MIL_INT CAL_NB_REF_PLANES [NUM_CAMERAS] = { NUM_REF_PLANES, NUM_REF_PLANES }; const MIL_INT CAL_SCAN_ORIENTATION[NUM_CAMERAS] = { M_HORIZONTAL, M_HORIZONTAL }; const MIL_INT CAL_PEAK_WIDTH [NUM_CAMERAS] = { 15, 15 }; const MIL_INT CAL_PEAK_WIDTH_DELTA[NUM_CAMERAS] = { 14, 14 }; const MIL_INT LASER_LABELS [NUM_CAMERAS] = { 1, 1 }; const MIL_INT CAMERA_LABELS [NUM_CAMERAS] = { 1, 2 }; const MIL_DOUBLE PLANE_Z[NUM_CAMERAS][MAX_NB_REF_PLANES] = { { -5.05, -10.91, -16.77, -22.63, -28.49, -34.35, -40.21 }, { -5.05, -10.91, -16.77, -22.63, -28.49, -34.35, -40.21 } }; const SRefPlaneInfo LASER_CALIBRATION_PLANES[NUM_CAMERAS][MAX_NB_REF_PLANES] = { { // first camera // RefImageName Zs { EX_PATH("Cam1RefPlanes/Cam1_laser_h0.mim"), PLANE_Z[0][0] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h1.mim"), PLANE_Z[0][1] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h2.mim"), PLANE_Z[0][2] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h3.mim"), PLANE_Z[0][3] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h4.mim"), PLANE_Z[0][4] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h5.mim"), PLANE_Z[0][5] }, { EX_PATH("Cam1RefPlanes/Cam1_laser_h6.mim"), PLANE_Z[0][6] } }, { // second camera // RefImageName Zs { EX_PATH("Cam2RefPlanes/Cam2_laser_h0.mim"), PLANE_Z[1][0] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h1.mim"), PLANE_Z[1][1] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h2.mim"), PLANE_Z[1][2] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h3.mim"), PLANE_Z[1][3] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h4.mim"), PLANE_Z[1][4] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h5.mim"), PLANE_Z[1][5] }, { EX_PATH("Cam2RefPlanes/Cam2_laser_h6.mim"), PLANE_Z[1][6] } } }; const MIL_INT NUM_LASERS_PER_IMAGE = 1; SLineExtractionInROI CHILD_EXTRACTION_INFO; CHILD_EXTRACTION_INFO.OffsetX = 520; CHILD_EXTRACTION_INFO.OffsetY = 0; CHILD_EXTRACTION_INFO.SizeX = 370; CHILD_EXTRACTION_INFO.SizeY = 1200; SCameraLaserInfo LASER_CALIBRATION_INFO[NUM_CAMERAS * NUM_LASERS_PER_IMAGE]; for(MIL_INT c = 0; c < NUM_CAMERAS; c++) { SCameraLaserInfo& LCI = LASER_CALIBRATION_INFO[c]; LCI.NumLasersPerImage = NUM_LASERS_PER_IMAGE; LCI.NumRefPlanes = NUM_REF_PLANES; LCI.CalMinContrast = CAL_MIN_CONTRAST[c]; LCI.CalNbRefPlanes = CAL_NB_REF_PLANES[c]; LCI.CalScanOrientation = CAL_SCAN_ORIENTATION[c]; LCI.CalPeakWidthNominal= CAL_PEAK_WIDTH[c]; LCI.CalPeakWidthDelta = CAL_PEAK_WIDTH_DELTA[c]; for(MIL_INT l = 0; l < LCI.CalNbRefPlanes; l++) { LCI.LaserCalibrationPlanes[l] = LASER_CALIBRATION_PLANES[c][l]; } LCI.LaserLabel = LASER_LABELS[c]; LCI.CameraLabel = CAMERA_LABELS[c]; LCI.LineExtractionInROI = eLineChildROI; LCI.LineExtractionInROIInfo = CHILD_EXTRACTION_INFO; } //............................................................ // 2.1 Execute the calibration of the laser planes. // Generates the needed calibrated camera-laser pair contexts. MIL_ID CameraLaserCtxts[NUM_CAMERAS * NUM_LASERS_PER_IMAGE]; bool SheetOfLightOk = pExampleMngrFor3D->CalibrateSheetOfLight(&LASER_CALIBRATION_INFO[0], &CameraCalibrations[0], &CameraLaserCtxts[0]); if (SheetOfLightOk) { // Map generation specifications. const MIL_DOUBLE D3D_DISPLAY_REFRESH_PER_SEC = 0.75; // 3d Display FPS const MIL_DOUBLE D3D_DISPLAY_LOOK_AT_X = 57.31; const MIL_DOUBLE D3D_DISPLAY_LOOK_AT_Y = 160.98; const MIL_DOUBLE D3D_DISPLAY_LOOK_AT_Z = 109.49; const MIL_DOUBLE D3D_DISPLAY_EYE_DIST = 722.16; const MIL_DOUBLE D3D_DISPLAY_EYE_THETA = 32.09; const MIL_DOUBLE D3D_DISPLAY_EYE_PHI = 65.89; const MIL_INT CAMERA_MAP_MIN_CONTRAST[] = { 7, 7 }; const MIL_INT CAMERA_MAP_PEAK_WIDTH[] = { 20 , 20 }; const MIL_INT CAMERA_MAP_PEAK_DELTA[] = { 19 , 19 }; const MIL_DOUBLE CAMERA_MAP_SCAN_SPEED[] = { 0.2727, 0.2727 }; const MIL_DOUBLE CAMERA_MAX_FRAMES = 1024; const MIL_DOUBLE CAMERA_DISPLACEMENT_MODE = M_CURRENT; // Visualization volume information. SMapGeneration MapData; MapData.BoxCornerX = - 29.80; MapData.BoxCornerY = - 0.21; MapData.BoxCornerZ = 1.86; MapData.BoxSizeX = 229.00; MapData.BoxSizeY = 247.00; MapData.BoxSizeZ = - 19.00; MapData.MapSizeX = 842; MapData.MapSizeY = 906; MapData.PixelSizeX = 0.273; MapData.PixelSizeY = 0.273; MapData.GrayScaleZ = (MapData.BoxSizeZ / 65534.0); MapData.IntensityMapType = 8 + M_UNSIGNED; MapData.SetExtractOverlap= false; MapData.ExtractOverlap = M_DEFAULT; MapData.FillXThreshold = 1.0; MapData.FillYThreshold = 1.0; // Scan and analyze information. SPointCloudAcquisitionInfo SCAN_INFO = { // SD3DSysInfo { D3D_DISPLAY_REFRESH_PER_SEC, SHOW_NO_COLOR, D3D_DISPLAY_LOOK_AT_X, D3D_DISPLAY_LOOK_AT_Y, D3D_DISPLAY_LOOK_AT_Z, D3D_DISPLAY_EYE_DIST, D3D_DISPLAY_EYE_THETA, D3D_DISPLAY_EYE_PHI }, { CAMERA_MAP_MIN_CONTRAST[0] , CAMERA_MAP_MIN_CONTRAST[1] }, { CAMERA_MAP_PEAK_WIDTH[0] , CAMERA_MAP_PEAK_WIDTH[1] }, { CAMERA_MAP_PEAK_DELTA[0] , CAMERA_MAP_PEAK_DELTA[1] }, { CAMERA_MAP_SCAN_SPEED[0] , CAMERA_MAP_SCAN_SPEED[1] }, CAMERA_MAX_FRAMES, CAMERA_DISPLACEMENT_MODE, eLineOffsetOnly, // SLineExtractionInROI { CHILD_EXTRACTION_INFO, CHILD_EXTRACTION_INFO }, MapData, { // DigInfo // DigFormat SX SY SB Type NbFrames { EX_PATH("Cam1_tire1.avi"), 0, 0, 0, 0, 0 }, { EX_PATH("Cam2_tire1.avi"), 0, 0, 0, 0, 0 } }, MIL_TEXT("") // ScanDisplayText }; // Update some information from the sequences on disk. for(MIL_INT d = 0; d < NUM_CAMERAS; d++) { SCAN_INFO.DigInfo[d].UpdateInfoFromDisk(); } //.................................................... // 3. Acquire a 3d point cloud by scanning the object. // The point cloud container will hold one point cloud per camera-laser pair. MIL_ID PointCloudContainer = M_NULL; bool PointCloudOk = pExampleMngrFor3D->AcquirePointCloud(eScan, &SCAN_INFO, CameraLaserCtxts, &PointCloudContainer); //..................................................................................... // 4. Generate the depth map (orthogonal 2d-projection) of the acquired 3d point cloud. MIL_ID TireDepthmap = M_NULL; pExampleMngrFor3D->GenerateDepthMap(PointCloudContainer, SCAN_INFO.MapVisualizationData, &TireDepthmap); //.................................... // 5. Analyze the generated depth map. CTireStringRead ProbObj; pExampleMngrFor3D->AnalyzeDepthMap(&ProbObj, TireDepthmap); // Free camera-laser contexts. for (MIL_INT c = 0; c < NUM_CAMERAS; c++) { for (MIL_INT l = 0; l < NUM_LASERS_PER_IMAGE; l++) { MIL_ID& CameraLaserCtx = CameraLaserCtxts[(c*NUM_LASERS_PER_IMAGE) + l]; if (CameraLaserCtx != M_NULL) { M3dmapFree(CameraLaserCtx); CameraLaserCtx = M_NULL; } } } M3dmapFree(PointCloudContainer); if(TireDepthmap != M_NULL) { MbufFree(TireDepthmap); } } } else { // A problem occurred calibrating the cameras. MosPrintf(MIL_TEXT("Press <Enter> to end.\n\n")); MosGetch(); } // Free camera calibrations. for (MIL_INT c = 0; c < NUM_CAMERAS; c++) { if(CameraCalibrations[c] != M_NULL) { McalFree(CameraCalibrations[c]); CameraCalibrations[c] = M_NULL; } } delete pExampleMngrFor3D; pExampleMngrFor3D = NULL; // Free the MIL application. MappFree(MilApplication); return 0; } //******************************************************************************* // Function that analyzes the scanned object. //******************************************************************************* void CTireStringRead::Analyze(SCommonAnalysisObjects& CommonAnalysisObjects) { // Processing display zoom factor. const MIL_DOUBLE PROC_DISPLAY_ZOOM_FACTOR_X = 1; const MIL_DOUBLE PROC_DISPLAY_ZOOM_FACTOR_Y = 1; // Color specifications. const MIL_DOUBLE MEAS_COLOR = M_COLOR_GREEN; const MIL_DOUBLE PROC_TEXT_COLOR = M_COLOR_BLUE; const MIL_DOUBLE MEAS_RING_CENTER_X = -220; const MIL_DOUBLE MEAS_RING_CENTER_Y = 465; const MIL_DOUBLE MEAS_INNER_RADIUS = 800; const MIL_DOUBLE MEAS_OUTER_RADIUS = 870; const MIL_DOUBLE MEAS_NUM_SUB_REGIONS = 20; const MIL_DOUBLE POLAR_DELTA_RADIUS = 250; const MIL_DOUBLE POLAR_START_ANGLE = 25; const MIL_DOUBLE POLAR_END_ANGLE =-15; const MIL_INT FIRST_CHILD_OFFSET_X = -391; const MIL_INT FIRST_CHILD_OFFSET_Y = -20; const MIL_INT FIRST_CHILD_SIZE_X = 340; const MIL_INT FIRST_CHILD_SIZE_Y = 40; const MIL_INT SECOND_CHILD_OFFSET_X = 0; const MIL_INT SECOND_CHILD_OFFSET_Y = -13; const MIL_INT SECOND_CHILD_SIZE_X = 295; const MIL_INT SECOND_CHILD_SIZE_Y = 33; MIL_ID MilSystem = CommonAnalysisObjects.MilSystem; MIL_ID MilGraphics = CommonAnalysisObjects.MilGraphics; MIL_ID MilGraphicList = CommonAnalysisObjects.MilGraphicList; MIL_ID MilDepthMap = CommonAnalysisObjects.MilDepthMap; CMILDisplayManager* MilDisplayMngr = CommonAnalysisObjects.MilDisplays; MilDisplayMngr->UpdateEnabled(false); // Setup the display. MgraClear(M_DEFAULT, MilGraphicList); MilDisplayMngr->Zoom(PROC_DISPLAY_ZOOM_FACTOR_X, PROC_DISPLAY_ZOOM_FACTOR_Y); // Allocate the necessary buffers for processing. MIL_ID MilEqualizedImage, MilRemapped8BitImage; MbufAlloc2d(MilSystem, MbufInquire(MilDepthMap, M_SIZE_X, M_NULL), MbufInquire(MilDepthMap, M_SIZE_Y, M_NULL), 16 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilEqualizedImage); MbufAlloc2d(MilSystem, MbufInquire(MilDepthMap, M_SIZE_X, M_NULL), MbufInquire(MilDepthMap, M_SIZE_Y, M_NULL), 8 + M_UNSIGNED, M_IMAGE + M_PROC + M_DISP, &MilRemapped8BitImage); MbufClear(MilEqualizedImage, 0); MbufClear(MilRemapped8BitImage, 0); // Do an adaptive equalize of the depth map image. MimHistogramEqualizeAdaptive(m_MilAdaptiveEqualizeContext, MilDepthMap, MilEqualizedImage, M_DEFAULT); // Remap to 8 bit. MimShift(MilEqualizedImage, MilRemapped8BitImage, -8); // Find the arc using measurement. MmeasSetMarker(m_MilCircleMarker, M_POLARITY, M_NEGATIVE, M_NEGATIVE); MmeasSetMarker(m_MilCircleMarker, M_RING_CENTER, MEAS_RING_CENTER_X, MEAS_RING_CENTER_Y); MmeasSetMarker(m_MilCircleMarker, M_RING_RADII , MEAS_INNER_RADIUS, MEAS_OUTER_RADIUS); MmeasSetMarker(m_MilCircleMarker, M_SUB_REGIONS_NUMBER, MEAS_NUM_SUB_REGIONS, M_NULL); // Find the circle and measure its position and radius. MmeasFindMarker(M_DEFAULT, MilRemapped8BitImage, m_MilCircleMarker, M_DEFAULT); // If occurrence is found, show the results. MIL_INT NumberOccurrencesFound = 0; MmeasGetResult(m_MilCircleMarker, M_NUMBER + M_TYPE_MIL_INT, &NumberOccurrencesFound, M_NULL); if (NumberOccurrencesFound >= 1) { MIL_DOUBLE CircleCenterX, CircleCenterY, CircleRadius; MmeasSetMarker(m_MilCircleMarker, M_RESULT_OUTPUT_UNITS, M_PIXEL, M_NULL); MmeasGetResult(m_MilCircleMarker, M_POSITION, &CircleCenterX, &CircleCenterY); MmeasGetResult(m_MilCircleMarker, M_RADIUS , &CircleRadius, M_NULL); // Using the circle, unwrap with a polar transform. MIL_DOUBLE SizeRadius,SizeAngle; MimPolarTransform(MilRemapped8BitImage, M_NULL, CircleCenterX, CircleCenterY, CircleRadius-POLAR_DELTA_RADIUS, CircleRadius+POLAR_DELTA_RADIUS, POLAR_START_ANGLE, POLAR_END_ANGLE, M_RECTANGULAR_TO_POLAR, M_NEAREST_NEIGHBOR + M_OVERSCAN_ENABLE, &SizeAngle, &SizeRadius); MIL_INT SizeX = (MIL_INT)ceil(SizeAngle); MIL_INT SizeY = (MIL_INT)ceil(SizeRadius); MIL_ID MilUnWrappedImage = MbufAlloc2d(MilSystem, SizeX, SizeY, 8, M_IMAGE + M_PROC + M_DISP, M_NULL); MbufClear(MilUnWrappedImage, 0); MimPolarTransform(MilRemapped8BitImage, MilUnWrappedImage, CircleCenterX, CircleCenterY, CircleRadius-POLAR_DELTA_RADIUS, CircleRadius+POLAR_DELTA_RADIUS, POLAR_START_ANGLE, POLAR_END_ANGLE, M_RECTANGULAR_TO_POLAR, M_NEAREST_NEIGHBOR + M_OVERSCAN_ENABLE, &SizeAngle, &SizeRadius); MilDisplayMngr->Show(MilUnWrappedImage); // Clear the graphics list. MgraClear(M_DEFAULT, MilGraphicList); MilDisplayMngr->UpdateEnabled(true); // Find the model shape around the second string. MmodFind(m_MilModel, MilUnWrappedImage, m_MilModelResult); MIL_INT NumOfOccurences = 0; MmodGetResult(m_MilModelResult, M_DEFAULT, M_NUMBER + M_TYPE_MIL_INT, &NumOfOccurences); if (NumOfOccurences >= 1) { // Get the reference point position. MIL_DOUBLE RefPointX, RefPointY; MmodControl(m_MilModelResult, M_DEFAULT, M_RESULT_OUTPUT_UNITS, M_PIXEL); MmodGetResult(m_MilModelResult, M_DEFAULT, M_POSITION_X + M_TYPE_MIL_DOUBLE, &RefPointX); MmodGetResult(m_MilModelResult, M_DEFAULT, M_POSITION_Y + M_TYPE_MIL_DOUBLE, &RefPointY); // Create a child around the two strings relative to the reference point. MIL_INT FirstOffsetX = (MIL_INT)(RefPointX + FIRST_CHILD_OFFSET_X); MIL_INT FirstOffsetY = (MIL_INT)(RefPointY + FIRST_CHILD_OFFSET_Y); MIL_ID MilFirstStringChildImage = MbufChild2d(MilUnWrappedImage, FirstOffsetX, FirstOffsetY, FIRST_CHILD_SIZE_X, FIRST_CHILD_SIZE_Y, M_NULL); MIL_INT SecondOffsetX = (MIL_INT)RefPointX + SECOND_CHILD_OFFSET_X; MIL_INT SecondOffsetY = (MIL_INT)(RefPointY + SECOND_CHILD_OFFSET_Y); MIL_ID MilSecondStringChildImage = MbufChild2d(MilUnWrappedImage, SecondOffsetX, SecondOffsetY, SECOND_CHILD_SIZE_X, SECOND_CHILD_SIZE_Y, M_NULL); // Read the first string. MstrRead(m_MilFirstStringReader, MilFirstStringChildImage, m_MilFirstStringReaderResult); // Read the second string. MstrRead(m_MilSecondStringReader, MilSecondStringChildImage, m_MilSecondStringReaderResult); MIL_INT NumberOfStringRead = 0; MstrGetResult(m_MilFirstStringReaderResult, M_GENERAL, M_STRING_NUMBER + M_TYPE_MIL_INT, &NumberOfStringRead); MgraControl(MilGraphics, M_BACKGROUND_MODE, M_OPAQUE); MgraColor(MilGraphics, M_COLOR_GREEN); MgraControl(MilGraphics, M_FONT_SIZE, TEXT_FONT_SIZE_SMALL); MgraText(MilGraphics, MilGraphicList, TEXT_OFFSET_X, TEXT_OFFSET_Y, MIL_TEXT("Read strings in unwrapped depth map")); // Show the wrapped tire zoomed out in the top right corner. const MIL_DOUBLE ZoomFactor = 0.3; MIL_INT ZoomSizeX = (MIL_INT)(MbufInquire(MilRemapped8BitImage, M_SIZE_X, M_NULL) * ZoomFactor); MIL_INT ZoomSizeY = (MIL_INT)(MbufInquire(MilRemapped8BitImage, M_SIZE_Y, M_NULL) * ZoomFactor); MIL_ID MilResizedImage = MbufAlloc2d(MilSystem, ZoomSizeX, ZoomSizeY, 8, M_IMAGE + M_PROC, M_NULL); MimResize(MilRemapped8BitImage, MilResizedImage, M_FILL_DESTINATION, M_FILL_DESTINATION, M_BICUBIC); MIL_ID MilRotatedImage = MbufAlloc2d(MilSystem, ZoomSizeY, ZoomSizeX, 8, M_IMAGE + M_PROC, M_NULL); MimRotate(MilResizedImage, MilRotatedImage, 90, (MIL_DOUBLE)(ZoomSizeX/2), (MIL_DOUBLE)(ZoomSizeY/2), (MIL_DOUBLE)(ZoomSizeY/2), (MIL_DOUBLE)(ZoomSizeX/2), M_BICUBIC); const MIL_INT TireOffsetY = 50; const MIL_INT TireSizeY = 550; MIL_ID MilUnWrappedImageChild = MbufChild2d(MilUnWrappedImage, MbufInquire(MilUnWrappedImage, M_SIZE_X, M_NULL)-ZoomSizeY, 0, ZoomSizeY, (MIL_INT)(TireSizeY*ZoomFactor), M_NULL); MbufCopyColor2d(MilRotatedImage, MilUnWrappedImageChild, M_ALL_BANDS, 0, (MIL_INT)(TireOffsetY*ZoomFactor), M_ALL_BANDS, 0, 0, ZoomSizeY, (MIL_INT)(TireSizeY*ZoomFactor)); MbufFree(MilResizedImage); MbufFree(MilRotatedImage); // Annotate the acquired depth map. MgraControl(MilGraphics, M_BACKGROUND_MODE, M_OPAQUE); MgraColor(MilGraphics, M_COLOR_GREEN); MgraControl(MilGraphics, M_FONT_SIZE, TEXT_FONT_SIZE_SMALL); MgraText(MilGraphics, MilGraphicList, MbufInquire(MilUnWrappedImage, M_SIZE_X, M_NULL)-ZoomSizeY+TEXT_OFFSET_X, TEXT_OFFSET_Y, MIL_TEXT("Acquired depth map")); MgraControl(MilGraphics, M_BACKGROUND_MODE, M_TRANSPARENT); if(NumberOfStringRead >= 1) { // Draw the first string. MgraColor(MilGraphics, PROC_TEXT_COLOR); MgraText(MilGraphics, MilGraphicList, FirstOffsetX, FirstOffsetY-30, MIL_TEXT("Embossed")); MgraControl(MilGraphics, M_DRAW_OFFSET_X, -FirstOffsetX); MgraControl(MilGraphics, M_DRAW_OFFSET_Y, -FirstOffsetY); MstrDraw(MilGraphics, m_MilFirstStringReaderResult, MilGraphicList, M_DRAW_STRING, M_ALL, M_NULL, M_DEFAULT); } else { MosPrintf(MIL_TEXT("Required string was not found.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } NumberOfStringRead = 0; MstrGetResult(m_MilSecondStringReaderResult, M_GENERAL, M_STRING_NUMBER + M_TYPE_MIL_INT, &NumberOfStringRead); if( NumberOfStringRead >= 1) { // Draw the second string. MgraControl(MilGraphics, M_DRAW_OFFSET_X, M_DEFAULT); MgraControl(MilGraphics, M_DRAW_OFFSET_Y, M_DEFAULT); MgraColor(MilGraphics, PROC_TEXT_COLOR); MgraText(MilGraphics, MilGraphicList, SecondOffsetX, SecondOffsetY-30, MIL_TEXT("Imprinted")); MgraControl(MilGraphics, M_DRAW_OFFSET_X, -SecondOffsetX); MgraControl(MilGraphics, M_DRAW_OFFSET_Y, -SecondOffsetY); MstrDraw(MilGraphics, m_MilSecondStringReaderResult, MilGraphicList, M_DRAW_STRING, M_ALL, M_NULL, M_DEFAULT); MosPrintf(MIL_TEXT("A polar transform was done to unroll the tire's ") MIL_TEXT("sidewall and\nthe two strings have been read.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } else { MosPrintf(MIL_TEXT("Required string was not found.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } MbufFree(MilUnWrappedImageChild); MbufFree(MilFirstStringChildImage); MbufFree(MilSecondStringChildImage); } else { MosPrintf(MIL_TEXT("Required model was not found.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } MbufFree(MilUnWrappedImage); } else { MosPrintf(MIL_TEXT("Required circle was not found.\n")); MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n")); MosGetch(); } MbufFree(MilEqualizedImage); MbufFree(MilRemapped8BitImage); } //******************************************************************************* // Function that allocates processing objects. //******************************************************************************* void CTireStringRead::AllocProcessingObjects(MIL_ID MilSystem) { const MIL_TEXT_CHAR* FIRST_STRING_FONT = EX_PATH("FirstStringFont.msr"); const MIL_TEXT_CHAR* SECOND_STRING_FONT = EX_PATH("SecondStringFont.msr"); const MIL_TEXT_CHAR* SECOND_STRING_MODEL = EX_PATH("SecondStringModel.mmf"); MimAlloc(MilSystem, M_HISTOGRAM_EQUALIZE_ADAPTIVE_CONTEXT, M_DEFAULT, &m_MilAdaptiveEqualizeContext); MmeasAllocMarker(MilSystem, M_CIRCLE, M_DEFAULT, &m_MilCircleMarker); MmodAllocResult(MilSystem, M_DEFAULT, &m_MilModelResult); MmodRestore(SECOND_STRING_MODEL, MilSystem, M_DEFAULT, &m_MilModel); MmodPreprocess(m_MilModel, M_DEFAULT); // Restore the first string reader context. MstrRestore(FIRST_STRING_FONT, MilSystem, M_DEFAULT, &m_MilFirstStringReader); MstrAllocResult(MilSystem, M_DEFAULT, &m_MilFirstStringReaderResult); MstrPreprocess(m_MilFirstStringReader, M_DEFAULT); // Restore the second string reader context. MstrRestore(SECOND_STRING_FONT, MilSystem, M_DEFAULT, &m_MilSecondStringReader); MstrAllocResult(MilSystem, M_DEFAULT, &m_MilSecondStringReaderResult); MstrPreprocess(m_MilSecondStringReader, M_DEFAULT); } //******************************************************************************* // Function that frees processing objects. //******************************************************************************* void CTireStringRead::FreeProcessingObjects() { MimFree(m_MilAdaptiveEqualizeContext); m_MilAdaptiveEqualizeContext = M_NULL; MmeasFree(m_MilCircleMarker); m_MilCircleMarker = M_NULL; MmodFree(m_MilModel); m_MilModel = M_NULL; MmodFree(m_MilModelResult); m_MilModelResult = M_NULL; MstrFree(m_MilFirstStringReader); m_MilFirstStringReader = M_NULL; MstrFree(m_MilFirstStringReaderResult); m_MilFirstStringReaderResult = M_NULL; MstrFree(m_MilSecondStringReader); m_MilSecondStringReader = M_NULL; MstrFree(m_MilSecondStringReaderResult); m_MilSecondStringReaderResult = M_NULL; }