/// <summary> /// Pattern Maching으로 Mark의 위치를 검색함 /// </summary> /// <param name="iCam"></param> /// <param name="pSdata"></param> /// <param name="pRData"></param> /// <returns></returns> public int SearchByNGC(int iCamNo, CVisionPatternData pSdata, out CResultData pRData) { MIL_ID m_MilImage = m_pDisplay[iCamNo].GetImage(); MIL_ID m_DisplayGraph = m_pDisplay[iCamNo].GetViewGraph(); CResultData pResult = new CResultData(); Point RectOffset = new Point(); // Mark Search Timer Reset MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Mark Search Command MIL.MpatFindModel(m_MilImage, pSdata.m_milModel, m_SearchResult); // Mark Search Timer Check MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref pResult.m_dTime); if (MIL.MpatGetNumber(m_SearchResult) == 1L) { // Display Mark Area //MIL.MgraClear(MIL.M_DEFAULT, m_DisplayGraph); m_pDisplay[iCamNo].ClearOverlay(); MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_GREEN); MIL.MpatDraw(MIL.M_DEFAULT, m_SearchResult, m_DisplayGraph, MIL.M_DRAW_BOX, MIL.M_DEFAULT, MIL.M_DEFAULT); //DisplaySearchResult(); MIL.MpatGetResult(m_SearchResult, MIL.M_POSITION_X, ref pResult.m_dPixelX); MIL.MpatGetResult(m_SearchResult, MIL.M_POSITION_Y, ref pResult.m_dPixelY); MIL.MpatGetResult(m_SearchResult, MIL.M_SCORE, ref pResult.m_dScore); RectOffset.X = (int)pResult.m_dPixelX - pSdata.m_pointReference.X - pSdata.m_rectSearch.X; RectOffset.Y = (int)pResult.m_dPixelY - pSdata.m_pointReference.Y - pSdata.m_rectSearch.Y; pResult.m_rectFindedModel = pSdata.m_rectModel; pResult.m_rectFindedModel.Offset(RectOffset); pResult.m_rectSearch = pSdata.m_rectSearch; if (pResult.m_dScore > pSdata.m_dAcceptanceThreshold) { pResult.m_bSearchSuccess = true; // Result Data 전달 pRData = pResult; return(SUCCESS); } } // Search Data를 초기화 한다. pResult.m_bSearchSuccess = false; pResult.m_dPixelX = 0.0; pResult.m_dPixelY = 0.0; pResult.m_rectSearch = new Rectangle(0, 0, 0, 0); pResult.m_rectFindedModel = new Rectangle(0, 0, 0, 0); // Result Data 전달 pRData = pResult; return(GenerateErrorCode(ERR_VISION_PATTERN_SEARCH_FAIL)); }
//***************************************************************************** // Benchmark function. //***************************************************************************** private static void Benchmark(ref PROC_PARAM ProcParamPtr, ref double Time, ref double FramesPerSecond) { MIL_INT EstimatedNbLoop = DEFAULT_NB_LOOP; double StartTime = 0.0; double EndTime = 0.0; double MinTime = 0; MIL_INT n; // Wait for the completion of all functions in this thread. MIL.MthrWait(MIL.M_DEFAULT, MIL.M_THREAD_WAIT, MIL.M_NULL); // Call the processing once before benchmarking for a more accurate time. // This compensates for Dll load time, etc. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref StartTime); ProcessingExecute(ref ProcParamPtr); MIL.MthrWait(MIL.M_DEFAULT, MIL.M_THREAD_WAIT, MIL.M_NULL); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref EndTime); MinTime = EndTime - StartTime; // Estimate the number of loops required to benchmark the processing for // the specified minimum time. for (n = 0; n < ESTIMATION_NB_LOOP; n++) { MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref StartTime); ProcessingExecute(ref ProcParamPtr); MIL.MthrWait(MIL.M_DEFAULT, MIL.M_THREAD_WAIT, MIL.M_NULL); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref EndTime); Time = EndTime - StartTime; MinTime = (Time < MinTime) ? Time : MinTime; } if (MinTime > 0) { EstimatedNbLoop = (MIL_INT)(MINIMUM_BENCHMARK_TIME / MinTime) + 1; } // Benchmark the processing according to the estimated number of loops. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref StartTime); for (n = 0; n < EstimatedNbLoop; n++) { ProcessingExecute(ref ProcParamPtr); } MIL.MthrWait(MIL.M_DEFAULT, MIL.M_THREAD_WAIT, MIL.M_NULL); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref EndTime); Time = EndTime - StartTime; FramesPerSecond = EstimatedNbLoop / Time; Time = Time * 1000 / EstimatedNbLoop; }
/// <summary> /// Call Back 함수로 Image가 새로 들어올때 마다 Event를 발생시킴. /// </summary> /// <param Camera="callBackOwner"></param> /// <param name="image"></param> /// <returns></returns> public int ImageCallback(object callBackOwner, ref BGAPI.Image image) { // get image to IntPtr image.get(ref m_ImageBuffer); // Copy to Byte[] Marshal.Copy(m_ImageBuffer, m_ImgBits, 0, m_CameraWidth * m_CameraHeight); // MIL Buffer에 Copy MIL.MbufPut(m_MilImage, m_ImgBits); MIL.MbufControl(m_MilImage, MIL.M_MODIFIED, MIL.M_DEFAULT); // Timer 확인 MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref dGrabInterval); String strResult = String.Format(" Scan Time : {0:0.00} ", dGrabInterval); // Timer Reset MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, ref dGrabInterval); // new image 호출 (Image Grab 지령) m_pCamera.GetCamera().setImage(ref image); return(SUCCESS); }
static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilOverlayImage = MIL.M_NULL; // Overlay image. MIL_ID MilStrContext = MIL.M_NULL; // String context identifier. MIL_ID MilStrResult = MIL.M_NULL; // String result buffer identifier. MIL_INT NumberOfStringRead = 0; // Total number of strings to read. double Score = 0.0; // String score. StringBuilder StringResult = new StringBuilder(STRING_MAX_SIZE + 1); // String of characters read. double Time = 0.0; // Time variable. // Print module name. Console.Write("\nSTRING READER MODULE:\n"); Console.Write("---------------------\n\n"); // Allocate defaults MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Restore the font definition image MIL.MbufRestore(IMAGE_FILE_DEFINITION, MilSystem, ref MilImage); // Display the image and prepare for overlay annotations. MIL.MdispSelect(MilDisplay, MilImage); MIL.MdispControl(MilDisplay, MIL.M_OVERLAY, MIL.M_ENABLE); MIL.MdispInquire(MilDisplay, MIL.M_OVERLAY_ID, ref MilOverlayImage); // Allocate a new empty String Reader context. MIL.MstrAlloc(MilSystem, MIL.M_FONT_BASED, MIL.M_DEFAULT, ref MilStrContext); // Allocate a new empty String Reader result buffer. MIL.MstrAllocResult(MilSystem, MIL.M_DEFAULT, ref MilStrResult); MIL.MstrControl(MilStrContext, MIL.M_CONTEXT, MIL.M_ENCODING, MIL.M_UNICODE); // Add a new empty user defined font to the context. MIL.MstrControl(MilStrContext, MIL.M_CONTEXT, MIL.M_FONT_ADD, MIL.M_USER_DEFINED); // Add user defined characters from the license plate mosaic image. MIL.MstrEditFont(MilStrContext, MIL.M_FONT_INDEX(0), MIL.M_CHAR_ADD, MIL.M_USER_DEFINED + MIL.M_FOREGROUND_BLACK, MilImage, TEXT_DEFINITION); // Draw all the characters in the font in the overlay image. MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_GREEN); MIL.MstrDraw(MIL.M_DEFAULT, MilStrContext, MilOverlayImage, MIL.M_DRAW_CHAR, MIL.M_FONT_INDEX(0), MIL.M_ORIGINAL); // Normalize the characters of the font to an appropriate size. MIL.MstrEditFont(MilStrContext, MIL.M_FONT_INDEX(0), MIL.M_CHAR_NORMALIZE, MIL.M_SIZE_Y, NORMALIZATION_SIZE_Y); // Add 2 new empty strings models to the context for the 2 valid types of // plates (3 letters followed by 3 numbers or 3 numbers followed by 3 letters) // Note that the read time increases with the number of strings in the context. MIL.MstrControl(MilStrContext, MIL.M_CONTEXT, MIL.M_STRING_ADD, MIL.M_USER_DEFINED); MIL.MstrControl(MilStrContext, MIL.M_CONTEXT, MIL.M_STRING_ADD, MIL.M_USER_DEFINED); // Set number of strings to read. MIL.MstrControl(MilStrContext, MIL.M_CONTEXT, MIL.M_STRING_NUMBER, 1); // Set number of expected characters for all string models to 6 characters. MIL.MstrControl(MilStrContext, MIL.M_STRING_INDEX(MIL.M_ALL), MIL.M_STRING_SIZE_MIN, 6); MIL.MstrControl(MilStrContext, MIL.M_STRING_INDEX(MIL.M_ALL), MIL.M_STRING_SIZE_MAX, 6); // Set default constraint to uppercase letter for all string models MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(0), MIL.M_DEFAULT, MIL.M_LETTER + MIL.M_UPPERCASE, IntPtr.Zero); MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(1), MIL.M_DEFAULT, MIL.M_LETTER + MIL.M_UPPERCASE, IntPtr.Zero); // Set constraint of 3 last characters to digit for the first string model MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(0), 3, MIL.M_DIGIT, IntPtr.Zero); MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(0), 4, MIL.M_DIGIT, IntPtr.Zero); MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(0), 5, MIL.M_DIGIT, IntPtr.Zero); // Set constraint of 3 first characters to digit for the second string model MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(1), 0, MIL.M_DIGIT, IntPtr.Zero); MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(1), 1, MIL.M_DIGIT, IntPtr.Zero); MIL.MstrSetConstraint(MilStrContext, MIL.M_STRING_INDEX(1), 2, MIL.M_DIGIT, IntPtr.Zero); // Pause to show the font definition. Console.Write("This program has defined a font with this Quebec plates mosaic image.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Clear the display overlay. MIL.MdispControl(MilDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT); // Load image to read into image buffer. MIL.MbufLoad(IMAGE_FILE_TO_READ, MilImage); // Preprocess the String Reader context. MIL.MstrPreprocess(MilStrContext, MIL.M_DEFAULT); // Dummy first call for bench measure purpose only (bench stabilization, cache effect, etc...). This first call is NOT required by the application. MIL.MstrRead(MilStrContext, MilImage, MilStrResult); // Reset the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Perform the read operation on the specified target image. MIL.MstrRead(MilStrContext, MilImage, MilStrResult); // Read the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // Get number of strings read and show the result. MIL.MstrGetResult(MilStrResult, MIL.M_GENERAL, MIL.M_STRING_NUMBER + MIL.M_TYPE_MIL_INT, ref NumberOfStringRead); if (NumberOfStringRead >= 1) { Console.Write("The license plate was read successfully ({0:#.##} ms)\n\n", Time * 1000); // Draw read result. MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_BLUE); MIL.MstrDraw(MIL.M_DEFAULT, MilStrResult, MilOverlayImage, MIL.M_DRAW_STRING, MIL.M_ALL, MIL.M_DEFAULT); MIL.MgraColor(MIL.M_DEFAULT, MIL.M_COLOR_GREEN); MIL.MstrDraw(MIL.M_DEFAULT, MilStrResult, MilOverlayImage, MIL.M_DRAW_STRING_BOX, MIL.M_ALL, MIL.M_DEFAULT); // Print the read result. Console.Write(" String Score\n"); Console.Write(" -----------------------------------\n"); MIL.MstrGetResult(MilStrResult, 0, MIL.M_STRING + MIL.M_TYPE_TEXT_CHAR, StringResult); MIL.MstrGetResult(MilStrResult, 0, MIL.M_STRING_SCORE, ref Score); Console.Write(" {0} {1:0.0}\n", StringResult.ToString(), Score); } else { Console.Write("Error: Plate was not read.\n"); } // Pause to show results. Console.Write("\nPress <Enter> to end.\n\n"); Console.ReadKey(); // Free all allocations. MIL.MstrFree(MilStrContext); MIL.MstrFree(MilStrResult); MIL.MbufFree(MilImage); // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
// Main function. static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID[] MilImage = new MIL_ID[2]; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID Default = MIL.M_DEFAULT; int NbProc = 0; int n = 0; double Time = 0.0; StringBuilder Text = new StringBuilder("0", STRING_LENGTH_MAX); UserDataObject userObject = new UserDataObject(); // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, ref MilImageDisp); // Allocate 2 grab buffers. for (n = 0; n < 2; n++) { MIL.MbufAlloc2d(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL), MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[n]); } // Hook a function to the start of each frame to print the current frame index. userObject.NbGrabStart = 0; GCHandle userObjectHandle = GCHandle.Alloc(userObject); MIL_DIG_HOOK_FUNCTION_PTR grabStartDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(GrabStart); MIL.MdigHookFunction(MilDigitizer, MIL.M_GRAB_START, grabStartDelegate, GCHandle.ToIntPtr(userObjectHandle)); // Print a message. Console.WriteLine(); Console.WriteLine("DOUBLE BUFFERING ACQUISITION AND PROCESSING:"); Console.WriteLine("--------------------------------------------"); Console.WriteLine(); Console.WriteLine("Press <Enter> to stop."); Console.WriteLine(); // Put the digitizer in asynchronous mode to be able to process while grabbing. MIL.MdigControl(MilDigitizer, MIL.M_GRAB_MODE, MIL.M_ASYNCHRONOUS); // Grab the first buffer. MIL.MdigGrab(MilDigitizer, MilImage[0]); // Process one buffer while grabbing the other. n = 0; do { // Grab the other buffer while processing the previous one. MIL.MdigGrab(MilDigitizer, MilImage[1 - n]); // Synchronize and start the timer. if (NbProc == 0) { MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); } // Write the frame counter. MIL.MgraText(Default, MilImage[n], 32, 32, string.Format("{0}", NbProc + 1)); // Process the first buffer already grabbed. MIL.MimArith(MilImage[n], MIL.M_NULL, MilImageDisp, MIL.M_NOT); // Count processed buffers. NbProc++; // Toggle grab buffers. n = 1 - n; } while (!Console.KeyAvailable); // Wait until the end of the last grab and stop the timer. MIL.MdigGrabWait(MilDigitizer, MIL.M_GRAB_END); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); Console.ReadKey(); // Print statistics. Console.WriteLine("{0} frames grabbed, at a frame rate of {1:0.00} frames/sec ({2:0.00} ms/frame).", NbProc, NbProc / Time, 1000.0 * Time / NbProc); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.ReadKey(); // Unhook the function at the start of each frame. MIL.MdigHookFunction(MilDigitizer, MIL.M_GRAB_START + MIL.M_UNHOOK, grabStartDelegate, GCHandle.ToIntPtr(userObjectHandle)); // Free GCHandle to allow the garbage collector to reclaim the object. userObjectHandle.Free(); // Free allocations. for (n = 0; n < 2; n++) { MIL.MbufFree(MilImage[n]); } MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MilImageDisp); }
static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilDisplayImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilKernel = MIL.M_NULL; // Custom kernel identifier. int n = 0; double Time = 0.0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Restore source image into an automatically allocated image buffers. MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilImage); MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilDisplayImage); // Zoom display to see the result of image processing better. MIL.MdispZoom(MilDisplay, ZOOM_VALUE, ZOOM_VALUE); // Display the image buffer. MIL.MdispSelect(MilDisplay, MilDisplayImage); // Pause to show the original image. Console.Write("\nIMAGE PROCESSING:\n"); Console.Write("-----------------\n\n"); Console.Write("This program performs a convolution on the displayed image.\n"); Console.Write("It uses a custom smoothing kernel.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Allocate a MIL kernel. MIL.MbufAlloc2d(MilSystem, KERNEL_WIDTH, KERNEL_HEIGHT, KERNEL_DEPTH + MIL.M_UNSIGNED, MIL.M_KERNEL, ref MilKernel); // Put the custom data in it. MIL.MbufPut(MilKernel, KernelData); // Set a normalization (divide) factor to have a kernel with // a sum equal to one. MIL.MbufControlNeighborhood(MilKernel, MIL.M_NORMALIZATION_FACTOR, 16); // Convolve the image using the kernel. MIL.MimConvolve(MilImage, MilDisplayImage, MilKernel); // Now time the convolution (MimConvolve()): // Overscan calculation is disabled and a destination image that // is not displayed is used to have the real convolution time. Also the // function must be called once before the timing loop for more accurate // time (dll load, ...). MIL.MbufControlNeighborhood(MilKernel, MIL.M_OVERSCAN, MIL.M_DISABLE); MIL.MimConvolve(MilDisplayImage, MilImage, MilKernel); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); for (n = 0; n < NB_LOOP; n++) { MIL.MimConvolve(MilDisplayImage, MilImage, MilKernel); } MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // Pause to show the result. Console.Write("Convolve time: {0:0.000} ms.\n", Time * 1000 / NB_LOOP); Console.Write("Press <Enter> to terminate.\n"); Console.ReadKey(); // Free all allocations. MIL.MbufFree(MilKernel); MIL.MbufFree(MilImage); MIL.MbufFree(MilDisplayImage); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
// Main function: // -------------- static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifiers. MIL_ID MilOrgImage = MIL.M_NULL; THREAD_PARAM TParTopLeft = new THREAD_PARAM(); // Parameters passed to top left thread. THREAD_PARAM TParBotLeft = new THREAD_PARAM(); // Parameters passed to bottom left thread. THREAD_PARAM TParTopRight = new THREAD_PARAM(); // Parameters passed to top right thread. THREAD_PARAM TParBotRight = new THREAD_PARAM(); // Parameters passed to bottom right thread. double Time = 0.0; // Timer variables. double FramesPerSecond = 0.0; MIL_INT LicenseModules = 0; // List of available MIL modules. // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Allocate and display the main image buffer. MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilImage); MIL.MbufClear(MilImage, 0); MIL.MdispSelect(MilDisplay, MilImage); // Allocate an image buffer to keep the original. MIL.MbufAlloc2d(MilSystem, IMAGE_WIDTH, IMAGE_HEIGHT, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilOrgImage); // Allocate a destination child buffer for each thread. MIL.MbufChild2d(MilImage, 0, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopLeft.SrcImage); MIL.MbufChild2d(MilImage, 0, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotLeft.DstImage); MIL.MbufChild2d(MilImage, IMAGE_WIDTH, 0, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParTopRight.SrcImage); MIL.MbufChild2d(MilImage, IMAGE_WIDTH, IMAGE_HEIGHT, IMAGE_WIDTH, IMAGE_HEIGHT, ref TParBotRight.DstImage); // Allocate synchronization events. MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopLeft.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotLeft.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParTopRight.DoneEvent); MIL.MthrAlloc(MilSystem, MIL.M_EVENT, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, ref TParBotRight.DoneEvent); // Inquire MIL licenses. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); // Initialize remaining thread parameters. TParTopLeft.System = MilSystem; TParTopLeft.OrgImage = MilOrgImage; TParTopLeft.DstImage = TParTopLeft.SrcImage; TParTopLeft.ReadyEvent = TParBotLeft.DoneEvent; TParTopLeft.NumberOfIteration = 0; TParTopLeft.Radius = 0; TParTopLeft.Exit = 0; TParTopLeft.LicenseModules = LicenseModules; TParTopLeft.SlaveThreadParam = TParBotLeft; TParBotLeft.System = MilSystem; TParBotLeft.OrgImage = 0; TParBotLeft.SrcImage = TParTopLeft.DstImage; TParBotLeft.ReadyEvent = TParTopLeft.DoneEvent; TParBotLeft.NumberOfIteration = 0; TParBotLeft.Radius = 0; TParBotLeft.Exit = 0; TParBotLeft.LicenseModules = LicenseModules; TParBotLeft.SlaveThreadParam = null; TParTopRight.System = MilSystem; TParTopRight.OrgImage = MilOrgImage; TParTopRight.DstImage = TParTopRight.SrcImage; TParTopRight.ReadyEvent = TParBotRight.DoneEvent; TParTopRight.NumberOfIteration = 0; TParTopRight.Radius = 0; TParTopRight.Exit = 0; TParTopRight.LicenseModules = LicenseModules; TParTopRight.SlaveThreadParam = TParBotRight; TParBotRight.System = MilSystem; TParBotRight.OrgImage = 0; TParBotRight.SrcImage = TParTopRight.DstImage; TParBotRight.ReadyEvent = TParTopRight.DoneEvent; TParBotRight.NumberOfIteration = 0; TParBotRight.Radius = 0; TParBotRight.Exit = 0; TParBotRight.LicenseModules = LicenseModules; TParBotRight.SlaveThreadParam = null; // Initialize the original image to process. MIL.MbufLoad(IMAGE_FILE, MilOrgImage); // Start the 4 threads. MIL_THREAD_FUNCTION_PTR TopThreadDelegate = new MIL_THREAD_FUNCTION_PTR(TopThread); MIL_THREAD_FUNCTION_PTR BotLeftThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotLeftThread); MIL_THREAD_FUNCTION_PTR BotRightThreadDelegate = new MIL_THREAD_FUNCTION_PTR(BotRightThread); GCHandle TParTopLeftHandle = GCHandle.Alloc(TParTopLeft); GCHandle TParBotLeftHandle = GCHandle.Alloc(TParBotLeft); GCHandle TParTopRightHandle = GCHandle.Alloc(TParTopRight); GCHandle TParBotRightHandle = GCHandle.Alloc(TParBotRight); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopLeftHandle), ref TParTopLeft.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotLeftThreadDelegate, GCHandle.ToIntPtr(TParBotLeftHandle), ref TParBotLeft.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, TopThreadDelegate, GCHandle.ToIntPtr(TParTopRightHandle), ref TParTopRight.Id); MIL.MthrAlloc(MilSystem, MIL.M_THREAD, MIL.M_DEFAULT, BotRightThreadDelegate, GCHandle.ToIntPtr(TParBotRightHandle), ref TParBotRight.Id); // Start the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Set events to start operation of top left and top right threads. MIL.MthrControl(TParTopLeft.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED); MIL.MthrControl(TParTopRight.ReadyEvent, MIL.M_EVENT_SET, MIL.M_SIGNALED); // Report that the threads are started and wait for a key press to stop them. Console.Write("\nMULTI-THREADING:\n"); Console.Write("----------------\n\n"); Console.Write("4 threads running...\n"); Console.Write("Press <Enter> to stop.\n\n"); Console.ReadKey(); // Signal the threads to exit. TParTopLeft.Exit = 1; TParTopRight.Exit = 1; // Wait for all threads to terminate. MIL.MthrWait(TParTopLeft.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParBotLeft.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParTopRight.Id, MIL.M_THREAD_END_WAIT); MIL.MthrWait(TParBotRight.Id, MIL.M_THREAD_END_WAIT); // Stop the timer and calculate the number of frames per second processed. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); FramesPerSecond = (TParTopLeft.NumberOfIteration + TParBotLeft.NumberOfIteration + TParTopRight.NumberOfIteration + TParBotRight.NumberOfIteration) / Time; // Print statistics. Console.Write("Top left iterations done: {0,4}.\n", TParTopLeft.NumberOfIteration); Console.Write("Bottom left iterations done: {0,4}.\n", TParBotLeft.NumberOfIteration); Console.Write("Top right iterations done: {0,4}.\n", TParTopRight.NumberOfIteration); Console.Write("Bottom right iterations done: {0,4}.\n\n", TParBotRight.NumberOfIteration); Console.Write("Processing speed for the 4 threads: {0:0.0} Images/Sec.\n\n", FramesPerSecond); Console.Write("Press <Enter> to end.\n\n"); Console.ReadKey(); // Free threads. MIL.MthrFree(TParTopLeft.Id); MIL.MthrFree(TParBotLeft.Id); MIL.MthrFree(TParTopRight.Id); MIL.MthrFree(TParBotRight.Id); // Free events. MIL.MthrFree(TParTopLeft.DoneEvent); MIL.MthrFree(TParBotLeft.DoneEvent); MIL.MthrFree(TParTopRight.DoneEvent); MIL.MthrFree(TParBotRight.DoneEvent); // Free buffers. MIL.MbufFree(TParTopLeft.SrcImage); MIL.MbufFree(TParTopRight.SrcImage); MIL.MbufFree(TParBotLeft.DstImage); MIL.MbufFree(TParBotRight.DstImage); MIL.MbufFree(MilOrgImage); MIL.MbufFree(MilImage); // Free the GCHandles TParTopLeftHandle.Free(); TParBotLeftHandle.Free(); TParTopRightHandle.Free(); TParBotRightHandle.Free(); // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
static void SingleModelExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID GraphicList = MIL.M_NULL; // Graphic list indentifier. MIL_ID MilSearchContext = MIL.M_NULL; // Search context. MIL_ID MilResult = MIL.M_NULL; // Result identifier. double ModelDrawColor = MIL.M_COLOR_RED; // Model draw color. MIL_INT[] Model = new MIL_INT[MODEL_MAX_OCCURRENCES]; // Model index. MIL_INT NumResults = 0; // Number of results found. double[] Score = new double[MODEL_MAX_OCCURRENCES]; // Model correlation score. double[] XPosition = new double[MODEL_MAX_OCCURRENCES]; // Model X position. double[] YPosition = new double[MODEL_MAX_OCCURRENCES]; // Model Y position. double[] Angle = new double[MODEL_MAX_OCCURRENCES]; // Model occurrence angle. double[] Scale = new double[MODEL_MAX_OCCURRENCES]; // Model occurrence scale. double Time = 0.0; // Bench variable. int i = 0; // Loop variable. // Restore the model image and display it. MIL.MbufRestore(SINGLE_MODEL_IMAGE, MilSystem, ref MilImage); MIL.MdispSelect(MilDisplay, MilImage); // Allocate a graphic list to hold the subpixel annotations to draw. MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref GraphicList); // Associate the graphic list to the display for annotations. MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); // Allocate a Geometric Model Finder context. MIL.MmodAlloc(MilSystem, MIL.M_GEOMETRIC, MIL.M_DEFAULT, ref MilSearchContext); // Allocate a result buffer. MIL.MmodAllocResult(MilSystem, MIL.M_DEFAULT, ref MilResult); // Define the model. MIL.MmodDefine(MilSearchContext, MIL.M_IMAGE, MilImage, MODEL_OFFSETX, MODEL_OFFSETY, MODEL_SIZEX, MODEL_SIZEY); // Set the search speed. MIL.MmodControl(MilSearchContext, MIL.M_CONTEXT, MIL.M_SPEED, SINGLE_MODEL_SEARCH_SPEED); // Preprocess the search context. MIL.MmodPreprocess(MilSearchContext, MIL.M_DEFAULT); // Draw box and position it in the source image to show the model. MIL.MgraColor(MIL.M_DEFAULT, ModelDrawColor); MIL.MmodDraw(MIL.M_DEFAULT, MilSearchContext, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, 0, MIL.M_ORIGINAL); // Pause to show the model. Console.Write("\nGEOMETRIC MODEL FINDER:\n"); Console.Write("-----------------------\n\n"); Console.Write("A model context was defined with the model in the displayed image.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Clear annotations. MIL.MgraClear(MIL.M_DEFAULT, GraphicList); // Load the single model target image. MIL.MbufLoad(SINGLE_MODEL_TARGET_IMAGE, MilImage); // Dummy first call for bench measure purpose only (bench stabilization, cache effect, etc...). This first call is NOT required by the application. MIL.MmodFind(MilSearchContext, MilImage, MilResult); // Reset the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Find the model. MIL.MmodFind(MilSearchContext, MilImage, MilResult); // Read the find time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // Get the number of models found. MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref NumResults); // If a model was found above the acceptance threshold. if ((NumResults >= 1) && (NumResults <= MODEL_MAX_OCCURRENCES)) { // Get the results of the single model. MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_INDEX + MIL.M_TYPE_MIL_INT, Model); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_POSITION_X, XPosition); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_POSITION_Y, YPosition); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_ANGLE, Angle); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_SCALE, Scale); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_SCORE, Score); // Print the results for each model found. Console.Write("The model was found in the target image:\n\n"); Console.Write("Result Model X Position Y Position Angle Scale Score\n\n"); for (i = 0; i < NumResults; i++) { Console.Write("{0,-9}{1,-8}{2,-13:0.00}{3,-13:0.00}{4,-8:0.00}{5,-8:0.00}{6,-5:0.00}%\n", i, Model[i], XPosition[i], YPosition[i], Angle[i], Scale[i], Score[i]); } Console.Write("\nThe search time is {0:0.0} ms\n\n", Time * 1000.0); // Draw edges, position and box over the occurrences that were found. for (i = 0; i < NumResults; i++) { MIL.MgraColor(MIL.M_DEFAULT, ModelDrawColor); MIL.MmodDraw(MIL.M_DEFAULT, MilResult, GraphicList, MIL.M_DRAW_EDGES + MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, i, MIL.M_DEFAULT); } } else { Console.Write("The model was not found or the number of models found is greater than\n"); Console.Write("the specified maximum number of occurrence !\n\n"); } // Wait for a key to be pressed. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Free MIL objects. MIL.MgraFree(GraphicList); MIL.MbufFree(MilImage); MIL.MmodFree(MilSearchContext); MIL.MmodFree(MilResult); }
const double MIN_HEIGHT_THRESHOLD = -1.0; // in mm static void CalibratedCameraExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilOverlayImage = MIL.M_NULL; // Overlay image buffer identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier (for processing). MIL_ID MilCalibration = MIL.M_NULL; // Calibration context. MIL_ID DepthMapId = MIL.M_NULL; // Image buffer identifier (for results). MIL_ID LaserId = MIL.M_NULL; // 3dmap laser profiling context identifier. MIL_ID ScanId = MIL.M_NULL; // 3dmap result buffer identifier. MIL_INT CalibrationStatus = 0; // Used to ensure if McalGrid() worked. MIL_INT SizeX = 0; // Width of grabbed images. MIL_INT SizeY = 0; // Height of grabbed images. MIL_INT NumberOfImages = 0; // Number of frames for scanned objects. MIL_INT n = 0; // Counter. double FrameRate = 0.0; // Number of grabbed frames per second (in AVI). double StartTime = 0.0; // Time at the beginning of each iteration. double EndTime = 0.0; // Time after processing for each iteration. double WaitTime = 0.0; // Time to wait for next frame. double Volume = 0.0; // Volume of scanned object. Console.WriteLine(); Console.WriteLine("3D PROFILING AND VOLUME ANALYSIS:"); Console.WriteLine("---------------------------------"); Console.WriteLine(); Console.WriteLine("This program generates fully corrected 3d data of a scanned"); Console.WriteLine("cookie and computes its volume.The laser profiling system uses"); Console.WriteLine("a 3d-calibrated camera."); Console.WriteLine(); // Load grid image for camera calibration. MIL.MbufRestore(GRID_FILENAME, MilSystem, ref MilImage); // Select display. 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); // Allocate calibration context in 3D mode. MIL.McalAlloc(MilSystem, MIL.M_TSAI_BASED, MIL.M_DEFAULT, ref MilCalibration); // Calibrate the camera. 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; } // Prepare for overlay annotations. 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); // Draw camera calibration points. 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(); // Disable overlay. MIL.MdispControl(MilDisplay, MIL.M_OVERLAY, MIL.M_DISABLE); // Load laser line image. MIL.MbufLoad(LASERLINE_FILENAME, MilImage); // Allocate 3dmap objects. MIL.M3dmapAlloc(MilSystem, MIL.M_LASER, MIL.M_CALIBRATED_CAMERA_LINEAR_MOTION, ref LaserId); MIL.M3dmapAllocResult(MilSystem, MIL.M_LASER_DATA, MIL.M_DEFAULT, ref ScanId); // Set laser line extraction options. MIL.M3dmapControl(LaserId, MIL.M_DEFAULT, MIL.M_PEAK_WIDTH, MAX_LINE_WIDTH_2); MIL.M3dmapControl(LaserId, MIL.M_DEFAULT, MIL.M_MIN_INTENSITY, MIN_INTENSITY_2); // Calibrate laser profiling context. MIL.M3dmapAddScan(LaserId, ScanId, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT); MIL.M3dmapCalibrate(LaserId, ScanId, 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(); // Empty all result buffer contents. // It will now be reused for extracting 3d points. MIL.M3dmapAddScan(MIL.M_NULL, ScanId, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_RESET); // Set speed of scanned object (speed in mm/frame is constant). MIL.M3dmapControl(LaserId, MIL.M_DEFAULT, MIL.M_SCAN_SPEED, CONVEYOR_SPEED); // Inquire characteristics of the input sequence. MIL.MbufDiskInquire(OBJECT2_SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref NumberOfImages); MIL.MbufDiskInquire(OBJECT2_SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate); // Open the object sequence file for reading. 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(); // Read and process all images in the input sequence. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime); for (n = 0; n < NumberOfImages; n++) { // Read image from sequence. MIL.MbufImportSequence(OBJECT2_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ); // Analyze the image to extract laser line and correct its depth. MIL.M3dmapAddScan(LaserId, ScanId, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT); // Wait to have a proper frame rate, if necessary. 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); } // Close the object sequence file. 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); // Allocate image for the fully corrected depth map. 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); // Set fully corrected depth map generation parameters. 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.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_PIXEL_SIZE_X, SCALE_X); MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_PIXEL_SIZE_Y, SCALE_Y); MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_GRAY_LEVEL_SIZE_Z, SCALE_Z); MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_WORLD_POS_X, WORLD_OFFSET_X); MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_WORLD_POS_Y, WORLD_OFFSET_Y); MIL.M3dmapControl(ScanId, MIL.M_DEFAULT, MIL.M_WORLD_POS_Z, WORLD_OFFSET_Z); // Get fully corrected depth map from accumulated information in the result buffer. MIL.M3dmapExtract(ScanId, DepthMapId, MIL.M_NULL, MIL.M_CORRECTED_DEPTH_MAP, MIL.M_DEFAULT, MIL.M_DEFAULT); // Remove noise. // Set all small values to 0, so that all remaining non-zeros are part of the cookie. MIL.MimClip(DepthMapId, DepthMapId, MIL.M_LESS, (MIN_HEIGHT_THRESHOLD - WORLD_OFFSET_Z) / SCALE_Z, MIL.M_NULL, 0.0, MIL.M_NULL); // Compute the volume of the cookie. MIL.M3dmapStat(DepthMapId, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_VOLUME, MIL.M_DEFAULT, MIL.M_DEFAULT, ref Volume); Console.WriteLine("Fully corrected 3d data of the cookie is displayed."); Console.WriteLine(); // Try to allocate D3D display. IntPtr DispHandle; DispHandle = MdepthD3DAlloc(DepthMapId, MIL.M_NULL, D3D_DISPLAY_SIZE_X, D3D_DISPLAY_SIZE_Y, SCALE_X, SCALE_Y, -SCALE_Z, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, IntPtr.Zero); if (DispHandle != IntPtr.Zero) { // Hide Mil Display. 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); } // Free all allocations. MIL.M3dmapFree(ScanId); MIL.M3dmapFree(LaserId); MIL.McalFree(MilCalibration); MIL.MbufFree(DepthMapId); MIL.MbufFree(MilImage); }
// Main function. // -------------- static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; MIL_ID MilRemoteApplication = MIL.M_NULL; // Remote Application identifier if running on a remote computer MIL_ID MilSystem = MIL.M_NULL; MIL_ID MilDigitizer = MIL.M_NULL; MIL_ID MilDisplay = MIL.M_NULL; MIL_ID MilImageDisp = MIL.M_NULL; MIL_ID[] MilGrabImages = new MIL_ID[NB_GRAB_IMAGE_MAX]; MIL_ID MilCompressedImage = MIL.M_NULL; ConsoleKeyInfo Selection = new ConsoleKeyInfo('1', ConsoleKey.D1, false, false, false); int NbFrames = 0; int n = 0; int NbFramesReplayed = 0; double FrameRate = 0; double TimeWait = 0; double TotalReplay = 0; double GrabScale = GRAB_SCALE; HookDataObject UserHookData = new HookDataObject(); MIL_INT LicenseModules = 0; MIL_INT FrameCount = 0; MIL_INT FrameMissed = 0; MIL_INT CompressAttribute = 0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, ref MilDigitizer, MIL.M_NULL); // Allocate an image and display it. MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X) * GrabScale), (MIL_INT)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_DISP, ref MilImageDisp); MIL.MbufClear(MilImageDisp, 0x0); MIL.MdispSelect(MilDisplay, MilImageDisp); // Grab continuously on display at the specified scale. MIL.MdigControl(MilDigitizer, MIL.M_GRAB_SCALE, GrabScale); MIL.MdigGrabContinuous(MilDigitizer, MilImageDisp); // Print a message Console.WriteLine(); Console.WriteLine("SEQUENCE ACQUISITION:"); Console.WriteLine("--------------------"); Console.WriteLine(); // Inquire MIL licenses. MIL.MsysInquire(MilSystem, MIL.M_OWNER_APPLICATION, ref MilRemoteApplication); MIL.MappInquire(MilRemoteApplication, MIL.M_LICENSE_MODULES, ref LicenseModules); // If sequence is saved to disk, select between grabbing an // uncompressed, JPEG or JPEG2000 sequence. if (SAVE_SEQUENCE_TO_DISK && ((LicenseModules & (MIL.M_LICENSE_JPEGSTD | MIL.M_LICENSE_JPEG2000)) != 0)) { Console.WriteLine("Choose the sequence format:"); Console.WriteLine("1) Uncompressed images."); if ((LicenseModules & MIL.M_LICENSE_JPEGSTD) != 0) { Console.WriteLine("2) Compressed images with a lossy JPEG algorithm."); } if ((LicenseModules & MIL.M_LICENSE_JPEG2000) != 0) { Console.WriteLine("3) Compressed images with a lossy JPEG 2000 algorithm."); } Selection = Console.ReadKey(); } else { Console.WriteLine("Press <Enter> to record images."); Console.ReadKey(); } // Set the buffer attribute. switch (Selection.Key) { case ConsoleKey.NumPad1: case ConsoleKey.D1: case ConsoleKey.Enter: Console.WriteLine(); Console.WriteLine("Recording uncompressed images..."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; break; case ConsoleKey.NumPad2: case ConsoleKey.D2: Console.WriteLine(); Console.WriteLine("Recording JPEG images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG_LOSSY; break; case ConsoleKey.NumPad3: case ConsoleKey.D3: Console.WriteLine(); Console.WriteLine("Recording JPEG 2000 images..."); Console.WriteLine(); CompressAttribute = MIL.M_COMPRESS + MIL.M_JPEG2000_LOSSY; break; default: Console.WriteLine(); Console.WriteLine("Invalid selection !."); Console.WriteLine(); Console.WriteLine("Using uncompressed images."); Console.WriteLine(); CompressAttribute = MIL.M_NULL; while (Console.KeyAvailable) { Console.ReadKey(); } break; } // Allocate a compressed buffer if required. if (CompressAttribute != MIL.M_NULL) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + CompressAttribute, ref MilCompressedImage); MIL.MbufControl(MilCompressedImage, MIL.M_Q_FACTOR, COMPRESSION_Q_FACTOR); } // Allocate the grab buffers to hold the sequence buffering. MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE); for (NbFrames = 0, n = 0; n < NB_GRAB_IMAGE_MAX; n++) { MIL.MbufAllocColor(MilSystem, MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_BAND, MIL.M_NULL), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_X, MIL.M_NULL) * GrabScale), (int)(MIL.MdigInquire(MilDigitizer, MIL.M_SIZE_Y, MIL.M_NULL) * GrabScale), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_GRAB, ref MilGrabImages[n]); if (MilGrabImages[n] != MIL.M_NULL) { NbFrames++; MIL.MbufClear(MilGrabImages[n], 0xFF); } else { break; } } MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE); // Free buffers to leave some space for possible temporary buffers. for (n = 0; n < 2 && NbFrames > 0; n++) { NbFrames--; MIL.MbufFree(MilGrabImages[NbFrames]); } // Halt continuous grab. MIL.MdigHalt(MilDigitizer); // Open the AVI file if required. if (SAVE_SEQUENCE_TO_DISK) { Console.WriteLine("Saving the sequence to an AVI file..."); Console.WriteLine(); MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_OPEN); } // Initialize User's archiving function hook data structure. UserHookData.MilSystem = MilSystem; UserHookData.MilDisplay = MilDisplay; UserHookData.MilImageDisp = MilImageDisp; UserHookData.MilCompressedImage = MilCompressedImage; UserHookData.SaveSequenceToDisk = SAVE_SEQUENCE_TO_DISK; UserHookData.NbGrabbedFrames = 0; UserHookData.NbArchivedFrames = 0; // get a handle to the DigHookUserData object in the managed heap, we will use this // handle to get the object back in the callback function GCHandle UserHookDataHandle = GCHandle.Alloc(UserHookData); MIL_DIG_HOOK_FUNCTION_PTR UserHookFunctionDelegate = new MIL_DIG_HOOK_FUNCTION_PTR(ArchiveFunction); // Acquire the sequence. The processing hook function will // be called for each image grabbed to archive and display it. // If sequence is not saved to disk, stop after NbFrames. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, SAVE_SEQUENCE_TO_DISK ? MIL.M_START : MIL.M_SEQUENCE, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Wait for a key press. Console.WriteLine("Press <Enter> to continue."); Console.WriteLine(); Console.ReadKey(true); // Stop the sequence acquisition. MIL.MdigProcess(MilDigitizer, MilGrabImages, NbFrames, MIL.M_STOP, MIL.M_DEFAULT, UserHookFunctionDelegate, GCHandle.ToIntPtr(UserHookDataHandle)); // Free the GCHandle when no longer used UserHookDataHandle.Free(); // Read and print final statistics. MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_COUNT, ref FrameCount); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_RATE, ref FrameRate); MIL.MdigInquire(MilDigitizer, MIL.M_PROCESS_FRAME_MISSED, ref FrameMissed); Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames archived ({1} missed), at {2:0.0} frames/sec ({3:0.0}ms/frame).", UserHookData.NbArchivedFrames, FrameMissed, FrameRate, 1000.0 / FrameRate); // Sequence file closing if required. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufExportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, FrameRate, MIL.M_CLOSE); } // Playback the sequence until a key is pressed. if (UserHookData.NbArchivedFrames > 0) { do { // If sequence must be loaded. if (SAVE_SEQUENCE_TO_DISK) { // Inquire information about the sequence. Console.WriteLine(); Console.WriteLine("Playing back sequence from the AVI file..."); Console.WriteLine(); Console.WriteLine("Press <Enter> to end."); Console.WriteLine(); Console.WriteLine(); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref FrameCount); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_COMPRESSION_TYPE, ref CompressAttribute); // Open the sequence file. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN); } // Copy the images to the screen respecting the sequence frame rate. TotalReplay = 0.0; NbFramesReplayed = 0; for (n = 0; n < FrameCount; n++) { // Reset the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, MIL.M_NULL); // If image was saved to disk. if (SAVE_SEQUENCE_TO_DISK) { // Load image directly to the display. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImageDisp, n, 1, MIL.M_READ); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } else { // Copy the grabbed image to the display. MIL.MbufCopy(MilGrabImages[n], MilImageDisp); NbFramesReplayed++; Console.Write("Frame #{0} \r", NbFramesReplayed); } // Check for a pressed key to exit. if (Console.KeyAvailable && (n >= (NB_GRAB_IMAGE_MAX - 1))) { Console.ReadKey(true); break; } // Wait to have a proper frame rate. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref TimeWait); TotalReplay += TimeWait; TimeWait = (1 / FrameRate) - TimeWait; MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_WAIT, ref TimeWait); TotalReplay += (TimeWait > 0) ? TimeWait : 0.0; } // Close the sequence file. if (SAVE_SEQUENCE_TO_DISK) { MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE); } // Print statistics. Console.WriteLine(); Console.WriteLine(); Console.WriteLine("{0} frames replayed, at a frame rate of {1:0.0} frames/sec ({2:0.0} ms/frame).", NbFramesReplayed, n / TotalReplay, 1000.0 * TotalReplay / n); Console.WriteLine(); Console.WriteLine("Press <Enter> to end (or any other key to playback again)."); Console.WriteLine(); }while (Console.ReadKey(true).Key != ConsoleKey.Enter); } // Free all allocated buffers. MIL.MbufFree(MilImageDisp); for (n = 0; n < NbFrames; n++) { MIL.MbufFree(MilGrabImages[n]); } if (MilCompressedImage != MIL.M_NULL) { MIL.MbufFree(MilCompressedImage); } // Free defaults. MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MilDigitizer, MIL.M_NULL); }
static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilDisplayImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilPosYImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilValImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilExtreme = MIL.M_NULL; // Result buffer identifier. double FrameRate = 0.0; int n = 0; double PreviousTime = 0.0; double StartTime = 0.0; double EndTime = 0.0; double TotalProcessTime = 0.0; double WaitTime = 0.0; MIL_INT SizeX = 0; MIL_INT SizeY = 0; MIL_INT NumberOfImages = 0; MIL_INT[] ExtremePosY = new MIL_INT[2]; ExtremePosY[0] = 0; ExtremePosY[1] = 0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Inquire characteristics of the input sequence. MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_SIZE_X, ref SizeX); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_SIZE_Y, ref SizeY); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_NUMBER_OF_IMAGES, ref NumberOfImages); MIL.MbufDiskInquire(SEQUENCE_FILE, MIL.M_FRAME_RATE, ref FrameRate); // Allocate buffers to hold images. MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilImage); MIL.MbufAlloc2d(MilSystem, SizeX, SizeY, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_DISP, ref MilDisplayImage); MIL.MbufAlloc2d(MilSystem, SizeX, NumberOfImages, 16 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilPosYImage); MIL.MbufAlloc2d(MilSystem, SizeX, NumberOfImages, 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC, ref MilValImage); // Select display. MIL.MdispSelect(MilDisplay, MilDisplayImage); // Print a message. Console.Write("\nEXTRACTING 3D IMAGE FROM A LASER LINE:\n"); Console.Write("--------------------------------------\n\n"); Console.Write("The position of a laser line is being extracted from an image\n"); Console.Write("to generate a depth image.\n\n"); // Open the sequence file for reading. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_OPEN); // The function must be called once before the timing loop for more accurate // time (dll load, ...). MIL.MimLocatePeak1d(MilImage, MilPosYImage, MilValImage, 0, MAX_LINE_WIDTH, MIN_INTENSITY, MIL.M_1D_COLUMNS + MIL.M_FIXED_POINT + NB_FIXED_POINT, MIL.M_DEFAULT); // Read and process all images in the input sequence. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref PreviousTime); TotalProcessTime = 0.0; for (n = 0; n < NumberOfImages; n++) { // Read image from sequence. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ); // Display the image. MIL.MbufCopy(MilImage, MilDisplayImage); // Locate the peak in each column of the image. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime); MIL.MimLocatePeak1d(MilImage, MilPosYImage, MilValImage, n, MAX_LINE_WIDTH, MIN_INTENSITY, MIL.M_1D_COLUMNS + MIL.M_FIXED_POINT + NB_FIXED_POINT, MIL.M_DEFAULT); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref EndTime); TotalProcessTime += EndTime - StartTime; // Wait to have a proper frame rate. WaitTime = (1.0 / FrameRate) - (EndTime - PreviousTime); 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 PreviousTime); } // Close the sequence file. MIL.MbufImportSequence(SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_CLOSE); Console.Write("{0} images processed in {1,7:0.00} s ({2,7:0.00} ms/image).\n", NumberOfImages, TotalProcessTime, TotalProcessTime / (double)NumberOfImages * 1000.0); // Pause to show the result. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); Console.Write("The reconstructed images are being displayed.\n"); // Draw extracted peak position in each column of each image. for (n = 0; n < NumberOfImages; n++) { MIL.MbufClear(MilImage, 0); MIL.MimDraw(MIL.M_DEFAULT, MilPosYImage, MilValImage, MilImage, MIL.M_DRAW_PEAKS + MIL.M_1D_COLUMNS + MIL.M_LINES, (double)n, 1, MIL.M_FIXED_POINT + NB_FIXED_POINT); // Display the result image. MIL.MbufCopy(MilImage, MilDisplayImage); } // Pause to show the result. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Try to allocate D3D display IntPtr DispHandle; DispHandle = MdepthD3DAlloc(MilPosYImage, MilValImage, D3D_DISPLAY_SIZE_X, D3D_DISPLAY_SIZE_Y, D3D_MESH_SCALING_X, D3D_MESH_SCALING_Y, D3D_MESH_SCALING_Z, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, IntPtr.Zero); if (DispHandle != IntPtr.Zero) { Console.Write("The depth buffer is displayed using D3D.\n"); // Hide Mil Display MIL.MdispControl(MilDisplay, MIL.M_WINDOW_SHOW, MIL.M_DISABLE); MdispD3DShow(DispHandle); MdispD3DPrintHelp(DispHandle); // Pause to show the result. Console.Write("Press <Enter> to end.\n"); Console.ReadKey(); MdispD3DHide(DispHandle); MdispD3DFree(DispHandle); } else { Console.Write("The depth buffer is displayed using MIL.\n"); // Find the reMIL.Mapping for result buffers. MIL.MimAllocResult(MilSystem, MIL.M_DEFAULT, MIL.M_STAT_LIST, ref MilExtreme); MIL.MimStat(MilPosYImage, MilExtreme, MIL.M_MIN + MIL.M_MAX, MIL.M_NOT_EQUAL, 0xFFFF, MIL.M_NULL); MIL.MimGetResult(MilExtreme, MIL.M_MIN + MIL.M_TYPE_MIL_INT, ref ExtremePosY[0]); MIL.MimGetResult(MilExtreme, MIL.M_MAX + MIL.M_TYPE_MIL_INT, ref ExtremePosY[1]); MIL.MimFree(MilExtreme); // Free the display and reallocate a new one of the proper dimension for results. MIL.MbufFree(MilDisplayImage); MIL.MbufAlloc2d(MilSystem, (MIL_INT)((double)SizeX * (D3D_MESH_SCALING_X > 0 ? D3D_MESH_SCALING_X : -D3D_MESH_SCALING_X)), (MIL_INT)((double)NumberOfImages * D3D_MESH_SCALING_Y), 8 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilDisplayImage); MIL.MdispSelect(MilDisplay, MilDisplayImage); // Display the height buffer. MIL.MimClip(MilPosYImage, MilPosYImage, MIL.M_GREATER, (double)ExtremePosY[1], MIL.M_NULL, (double)ExtremePosY[1], MIL.M_NULL); MIL.MimArith(MilPosYImage, (double)ExtremePosY[0], MilPosYImage, MIL.M_SUB_CONST); MIL.MimArith(MilPosYImage, ((ExtremePosY[1] - ExtremePosY[0]) / 255.0) + 1, MilPosYImage, MIL.M_DIV_CONST); MIL.MimResize(MilPosYImage, MilDisplayImage, MIL.M_FILL_DESTINATION, MIL.M_FILL_DESTINATION, MIL.M_BILINEAR); // Pause to show the result. Console.Write("Press <Enter> to end.\n"); Console.ReadKey(); } // Free all allocations. MIL.MbufFree(MilImage); MIL.MbufFree(MilDisplayImage); MIL.MbufFree(MilPosYImage); MIL.MbufFree(MilValImage); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }
static void MmodTrackingExample(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDigitizer, MIL_ID MilDisplayImage, MIL_ID MilModelImage) { MIL_ID[] MilImage = new MIL_ID[2] { MIL.M_NULL, MIL.M_NULL }; // Processing image buffer identifiers. MIL_ID SearchContext = MIL.M_NULL; // Search context identifier. MIL_ID Result = MIL.M_NULL; // Result identifier. double DrawColor = DRAW_COLOR; // Model drawing color. MIL_INT Found = 0; // Number of models found. int NbFindDone = 0; // Number of loops to find model done. double OrgX = 0.0; // Original center of model. double OrgY = 0.0; double[] Score = new double[MODEL_MAX_OCCURRENCES]; // Model correlation score. double[] x = new double[MODEL_MAX_OCCURRENCES]; // Model X position. double[] y = new double[MODEL_MAX_OCCURRENCES]; // Model Y position. double[] Angle = new double[MODEL_MAX_OCCURRENCES]; // Model occurrence angle. double[] Scale = new double[MODEL_MAX_OCCURRENCES]; // Model occurrence scale. double Time = 0.0; // Timer. // Print a start message. Console.Write("\nGEOMETRIC MODEL FINDER (scale and rotation independent):\n"); Console.Write("--------------------------------------------------------\n\n"); // Display model image. MIL.MbufCopy(MilModelImage, MilDisplayImage); // Allocate a context and define a geometric model. MIL.MmodAlloc(MilSystem, MIL.M_GEOMETRIC, MIL.M_DEFAULT, ref SearchContext); MIL.MmodDefine(SearchContext, MIL.M_IMAGE, MilModelImage, (double)MODEL_POS_X_INIT(MilModelImage) - (MODEL_WIDTH / 2), (double)MODEL_POS_Y_INIT(MilModelImage) - (MODEL_HEIGHT / 2), MODEL_WIDTH, MODEL_HEIGHT); // Allocate result. MIL.MmodAllocResult(MilSystem, MIL.M_DEFAULT, ref Result); // Draw a box around the model. MIL.MgraColor(MIL.M_DEFAULT, DrawColor); MIL.MmodDraw(MIL.M_DEFAULT, SearchContext, MilDisplayImage, MIL.M_DRAW_BOX, MIL.M_DEFAULT, MIL.M_ORIGINAL); // Set speed to VERY HIGH for fast but less precise search. MIL.MmodControl(SearchContext, MIL.M_CONTEXT, MIL.M_SPEED, MIL.M_VERY_HIGH); // Set minimum acceptance for the search. MIL.MmodControl(SearchContext, MIL.M_DEFAULT, MIL.M_ACCEPTANCE, MODEL_MIN_MATCH_SCORE); // Preprocess model. MIL.MmodPreprocess(SearchContext, MIL.M_DEFAULT); // Inquire about center of model. MIL.MmodInquire(SearchContext, MIL.M_DEFAULT, MIL.M_ORIGINAL_X, ref OrgX); MIL.MmodInquire(SearchContext, MIL.M_DEFAULT, MIL.M_ORIGINAL_Y, ref OrgY); // Print the original position. Console.Write("The Geometric target model was defined.\n"); Console.Write("Model dimensions: {0} x {1}.\n", MODEL_WIDTH, MODEL_HEIGHT); Console.Write("Model center: X={0:0.00}, Y={0:0.00}.\n", OrgX, OrgY); Console.Write("Model is scale and rotation independent.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Allocate 2 grab buffers. MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MilModelImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MilModelImage, MIL.M_SIZE_Y, MIL.M_NULL), 8, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[0]); MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MilModelImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MilModelImage, MIL.M_SIZE_Y, MIL.M_NULL), 8, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[1]); // Grab continuously grab and perform the find operation using double buffering. Console.Write("\nContinuously finding the Geometric Model.\n"); Console.Write("Press a <Enter> to stop.\n\n"); // Grab a first target image into first buffer (done twice for timer reset accuracy). MIL.MdigControl(MilDigitizer, MIL.M_GRAB_MODE, MIL.M_ASYNCHRONOUS); MIL.MdigGrab(MilDigitizer, MilImage[NbFindDone % 2]); MIL.MdigGrab(MilDigitizer, MilImage[NbFindDone % 2]); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, ref Time); // Loop, processing one buffer while grabbing the other. do { // Grab a target image into the other buffer. MIL.MdigGrab(MilDigitizer, MilImage[(NbFindDone + 1) % 2]); // Read the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref Time); // Find model. MIL.MmodFind(SearchContext, MilImage[NbFindDone % 2], Result); // Get the number of occurrences found. MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref Found); // Print a message based on the score. if ((Found >= 1) && (Found < MODEL_MAX_OCCURRENCES)) { // Get results. MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_POSITION_X, x); MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_POSITION_Y, y); MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_SCALE, Scale); MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_ANGLE, Angle); MIL.MmodGetResult(Result, MIL.M_DEFAULT, MIL.M_SCORE, Score); // Draw a box and a cross where the model was found and print the results. MIL.MmodDraw(MIL.M_DEFAULT, Result, MilImage[NbFindDone % 2], MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION + MIL.M_DRAW_EDGES, MIL.M_DEFAULT, MIL.M_DEFAULT); Console.Write("Found: X={0,6:0.0}, Y={1,6:0.0}, Angle={2,6:0.0}, Scale={3,5:0.00}, Score={4,5:0.0}% ({5,5:0.0} fps).\r", x[0], y[0], Angle[0], Scale[0], Score[0], (NbFindDone + 1) / Time); } else { // Print the "not found" message. Console.Write("Not found! (score<{0,5:0.0}%) ({1,5:0.0} fps).\r", MODEL_MIN_MATCH_SCORE, (NbFindDone + 1) / Time); } // Copy target image to the display. MIL.MbufCopy(MilImage[NbFindDone % 2], MilDisplayImage); // Increment the counter. NbFindDone++; }while (!Console.KeyAvailable); Console.ReadKey(); Console.Write("\n\n"); // Wait for the end of last grab. MIL.MdigGrabWait(MilDigitizer, MIL.M_GRAB_END); // Free all allocations. MIL.MmodFree(Result); MIL.MmodFree(SearchContext); MIL.MbufFree(MilImage[1]); MIL.MbufFree(MilImage[0]); }
//**************************************************************************** // Tracking object with pattern matching module. //**************************************************************************** static void MpatTrackingExample(MIL_ID MilSystem, MIL_ID MilDisplay, MIL_ID MilDigitizer, MIL_ID MilDisplayImage, MIL_ID MilModelImage) { MIL_ID[] MilImage = new MIL_ID[2] { MIL.M_NULL, MIL.M_NULL }; // Processing image buffer identifiers. MIL_ID Model = MIL.M_NULL; // Model identifier. MIL_ID Result = MIL.M_NULL; // Result identifier. double DrawColor = DRAW_COLOR; // Model drawing color. MIL_INT Found = 0; // Number of found models. int NbFindDone = 0; // Number of loops to find model done. double OrgX = 0.0; // Original center of model. double OrgY = 0.0; double x = 0.0; // Result variables. double y = 0.0; double Score = 0.0; double Time = 0.0; // Timer. // Print a start message. Console.Write("\nGRAYSCALE PATTERN MATCHING:\n"); Console.Write("---------------------------\n\n"); // Display the model image. MIL.MbufCopy(MilModelImage, MilDisplayImage); // Allocate normalized grayscale type model. MIL.MpatAllocModel(MilSystem, MilModelImage, MODEL_POS_X_INIT(MilModelImage) - (MODEL_WIDTH / 2), MODEL_POS_Y_INIT(MilModelImage) - (MODEL_HEIGHT / 2), MODEL_WIDTH, MODEL_HEIGHT, MIL.M_NORMALIZED, ref Model); // Allocate result. MIL.MpatAllocResult(MilSystem, 1, ref Result); // Draw box around the model. MIL.MgraColor(MIL.M_DEFAULT, DrawColor); MIL.MpatDraw(MIL.M_DEFAULT, Model, MilDisplayImage, MIL.M_DRAW_BOX, MIL.M_DEFAULT, MIL.M_ORIGINAL); // Set minimum acceptance for search. MIL.MpatSetAcceptance(Model, MODEL_MIN_MATCH_SCORE); // Set speed. MIL.MpatSetSpeed(Model, MIL.M_HIGH); // Set accuracy. MIL.MpatSetAccuracy(Model, MIL.M_LOW); // Preprocess model. MIL.MpatPreprocModel(MilModelImage, Model, MIL.M_DEFAULT); // Inquire about center of model. MIL.MpatInquire(Model, MIL.M_ORIGINAL_X, ref OrgX); MIL.MpatInquire(Model, MIL.M_ORIGINAL_Y, ref OrgY); // Print the original position. Console.Write("A Grayscale Model was defined.\n"); Console.Write("Model dimensions: {0} x {1}.\n", MODEL_WIDTH, MODEL_HEIGHT); Console.Write("Model center: X={0:0.00}, Y={0:0.00}.\n", OrgX, OrgY); Console.Write("Model is scale and rotation dependant.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Allocate 2 grab buffers. MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MilModelImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MilModelImage, MIL.M_SIZE_Y, MIL.M_NULL), 8, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[0]); MIL.MbufAlloc2d(MilSystem, MIL.MbufInquire(MilModelImage, MIL.M_SIZE_X, MIL.M_NULL), MIL.MbufInquire(MilModelImage, MIL.M_SIZE_Y, MIL.M_NULL), 8, MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC, ref MilImage[1]); // Grab continuously and perform the find operation using double buffering. Console.Write("\nContinuously finding the Grayscale model.\n"); Console.Write("Press <Enter> to stop.\n\n"); // Grab a first target image into first buffer (done twice for timer reset accuracy). MIL.MdigControl(MilDigitizer, MIL.M_GRAB_MODE, MIL.M_ASYNCHRONOUS); MIL.MdigGrab(MilDigitizer, MilImage[NbFindDone % 2]); MIL.MdigGrab(MilDigitizer, MilImage[NbFindDone % 2]); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET, ref Time); // Loop, processing one buffer while grabbing the other. do { // Grab a target image into the other buffer. MIL.MdigGrab(MilDigitizer, MilImage[(NbFindDone + 1) % 2]); // Read the time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ, ref Time); // Find model. MIL.MpatFindModel(MilImage[NbFindDone % 2], Model, Result); // Get results. MIL.MpatGetNumber(Result, ref Found); MIL.MpatGetResult(Result, MIL.M_POSITION_X, ref x); MIL.MpatGetResult(Result, MIL.M_POSITION_Y, ref y); MIL.MpatGetResult(Result, MIL.M_SCORE, ref Score); // Print a message based upon the score. if (Found > 0) { // Draw a box around the model and print the results. MIL.MpatDraw(MIL.M_DEFAULT, Result, MilImage[NbFindDone % 2], MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, MIL.M_DEFAULT, MIL.M_DEFAULT); Console.Write("Found: X={0,7:0.00}, Y={1,7:0.00}, Score={2,5:0.0}% ({3:0.0} fps). \r", x, y, Score, (NbFindDone + 1) / Time); } else { // Print the "not found" message. Console.Write("Not found ! (score<{0,5:0.0}%) ({1:0.0} fps). \r", MODEL_MIN_MATCH_SCORE, (NbFindDone + 1) / Time); } // Copy target image to the display. MIL.MbufCopy(MilImage[NbFindDone % 2], MilDisplayImage); // Increment find count NbFindDone++; }while (!Console.KeyAvailable); Console.ReadKey(); Console.Write("\n\n"); // Wait for end of last grab. MIL.MdigGrabWait(MilDigitizer, MIL.M_GRAB_END); // Free all allocated objects. MIL.MpatFree(Result); MIL.MpatFree(Model); MIL.MbufFree(MilImage[1]); MIL.MbufFree(MilImage[0]); }
static void DepthCorrectionExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilOverlayImage = MIL.M_NULL; // Overlay image buffer identifier. MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier (for processing). MIL_ID MilDepthMap = MIL.M_NULL; // Image buffer identifier (for results). MIL_ID MilLaser = MIL.M_NULL; // 3dmap laser profiling context identifier. MIL_ID MilScan = MIL.M_NULL; // 3dmap result buffer identifier. MIL_INT SizeX = 0; // Width of grabbed images. MIL_INT SizeY = 0; // Height of grabbed images. MIL_INT NbReferencePlanes = 0; // Number of reference planes of known heights. MIL_INT NbObjectImages = 0; // Number of frames for scanned objects. MIL_INT n = 0; // Counter. double FrameRate = 0.0; // Number of grabbed frames per second (in AVI). double StartTime = 0.0; // Time at the beginning of each iteration. double EndTime = 0.0; // Time after processing for each iteration. double WaitTime = 0.0; // Time to wait for next frame. // Inquire characteristics of the input sequences. 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); // Allocate buffer to hold images. 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 profiling system."); Console.WriteLine(); Console.WriteLine("Press <Enter> to continue."); Console.WriteLine(); Console.ReadKey(); // Select display. MIL.MdispSelect(MilDisplay, MilImage); // Prepare for overlay annotations. 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); // Allocate 3dmap objects. MIL.M3dmapAlloc(MilSystem, MIL.M_LASER, MIL.M_DEPTH_CORRECTION, ref MilLaser); MIL.M3dmapAllocResult(MilSystem, MIL.M_LASER_DATA, MIL.M_DEFAULT, ref MilScan); // Set laser line extraction options. MIL.M3dmapControl(MilLaser, MIL.M_DEFAULT, MIL.M_PEAK_WIDTH, MAX_LINE_WIDTH); MIL.M3dmapControl(MilLaser, MIL.M_DEFAULT, MIL.M_MIN_INTENSITY, MIN_INTENSITY); // Open the calibration sequence file for reading. 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); // Read and process all images in the input sequence. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref StartTime); for (n = 0; n < NbReferencePlanes; n++) { string CalibString; // Read image from sequence. MIL.MbufImportSequence(REFERENCE_PLANES_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ); // Annotate the image with the calibration height. 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); // Set desired corrected depth of next reference plane. MIL.M3dmapControl(MilLaser, MIL.M_DEFAULT, MIL.M_CORRECTED_DEPTH, CORRECTED_DEPTHS[n] * SCALE_FACTOR); // Analyze the image to extract laser line. MIL.M3dmapAddScan(MilLaser, MilScan, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT); // Wait to have a proper frame rate, if necessary. 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); } // Close the calibration sequence file. 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); // Calibrate the laser profiling context using reference planes of known heights. MIL.M3dmapCalibrate(MilLaser, MilScan, 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(); // Empty all result buffer contents. // It will now be reused for extracting corrected depths. MIL.M3dmapAddScan(MIL.M_NULL, MilScan, MIL.M_NULL, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_RESET); // Open the object sequence file for reading. 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); // Read and process all images in the input sequence. 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++) { // Read image from sequence. MIL.MbufImportSequence(OBJECT_SEQUENCE_FILE, MIL.M_DEFAULT, MIL.M_LOAD, MIL.M_NULL, ref MilImage, MIL.M_DEFAULT, 1, MIL.M_READ); // Analyze the image to extract laser line and correct its depth. MIL.M3dmapAddScan(MilLaser, MilScan, MilImage, MIL.M_NULL, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT); // Wait to have a proper frame rate, if necessary. 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); } // Close the object sequence file. 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); // Allocate the image for a partially corrected depth map. MIL.MbufAlloc2d(MilSystem, SizeX, NbObjectImages, 16 + MIL.M_UNSIGNED, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilDepthMap); // Get partially corrected depth map from accumulated information in the result buffer. MIL.M3dmapExtract(MilScan, MilDepthMap, MIL.M_NULL, MIL.M_CORRECTED_DEPTH_MAP, MIL.M_DEFAULT, MIL.M_DEFAULT); // Show partially corrected depth map and find defects. SetupColorDisplay(MilSystem, MilDisplay, MIL.MbufInquire(MilDepthMap, MIL.M_SIZE_BIT, MIL.M_NULL)); // Display partially corrected depth map. 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(); // Disassociates display LUT and clear overlay. MIL.MdispLut(MilDisplay, MIL.M_DEFAULT); MIL.MdispControl(MilDisplay, MIL.M_OVERLAY_CLEAR, MIL.M_DEFAULT); // Free all allocations. MIL.M3dmapFree(MilScan); MIL.M3dmapFree(MilLaser); MIL.MbufFree(MilDepthMap); MIL.MbufFree(MilImage); }
static void SearchRotatedModelExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilSourceImage = MIL.M_NULL; // Model image buffer identifier. MIL_ID MilTargetImage = MIL.M_NULL; // Target image buffer identifier. MIL_ID MilDisplayImage = MIL.M_NULL; // Target image buffer identifier. MIL_ID GraphicList = MIL.M_NULL; // Graphic list. MIL_ID MilModel = MIL.M_NULL; // Model identifier. MIL_ID MilResult = MIL.M_NULL; // Result identifier. double RealX = 0.0; // Model real position in x. double RealY = 0.0; // Model real position in y. double RealAngle = 0.0; // Model real angle. double X = 0.0; // Model position in x found. double Y = 0.0; // Model position in y found. double Angle = 0.0; // Model angle found. double Score = 0.0; // Model correlation score. double Time = 0.0; // Model search time. double ErrX = 0.0; // Model error position in x. double ErrY = 0.0; // Model error position in y. double ErrAngle = 0.0; // Model error angle. double SumErrX = 0.0; // Model total error position in x. double SumErrY = 0.0; // Model total error position in y. double SumErrAngle = 0.0; // Model total error angle. double SumTime = 0.0; // Model total search time. int NbFound = 0; // Number of models found. double AnnotationColor = MIL.M_COLOR_GREEN; // Drawing color. // Load target image into image buffers and display it. MIL.MbufRestore(ROTATED_FIND_IMAGE_FILE, MilSystem, ref MilSourceImage); MIL.MbufRestore(ROTATED_FIND_IMAGE_FILE, MilSystem, ref MilTargetImage); MIL.MbufRestore(ROTATED_FIND_IMAGE_FILE, MilSystem, ref MilDisplayImage); MIL.MdispSelect(MilDisplay, MilDisplayImage); // Allocate a graphic list to hold the subpixel annotations to draw. MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref GraphicList); // Associate the graphic list to the display for annotations. MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); // Allocate a normalized grayscale model. MIL.MpatAllocModel(MilSystem, MilSourceImage, ROTATED_FIND_MODEL_X_POS, ROTATED_FIND_MODEL_Y_POS, ROTATED_FIND_MODEL_WIDTH, ROTATED_FIND_MODEL_HEIGHT, MIL.M_NORMALIZED + MIL.M_CIRCULAR_OVERSCAN, ref MilModel); // Set the search model speed. MIL.MpatSetSpeed(MilModel, MIL.M_MEDIUM); // Set the position search accuracy. MIL.MpatSetAccuracy(MilModel, MIL.M_HIGH); // Activate the search model angle mode. MIL.MpatSetAngle(MilModel, MIL.M_SEARCH_ANGLE_MODE, MIL.M_ENABLE); // Set the search model range angle. MIL.MpatSetAngle(MilModel, MIL.M_SEARCH_ANGLE_DELTA_NEG, ROTATED_FIND_ANGLE_DELTA_NEG); MIL.MpatSetAngle(MilModel, MIL.M_SEARCH_ANGLE_DELTA_POS, ROTATED_FIND_ANGLE_DELTA_POS); // Set the search model angle accuracy. MIL.MpatSetAngle(MilModel, MIL.M_SEARCH_ANGLE_ACCURACY, ROTATED_FIND_MIN_ANGLE_ACCURACY); // Set the search model angle interpolation mode to bilinear. MIL.MpatSetAngle(MilModel, MIL.M_SEARCH_ANGLE_INTERPOLATION_MODE, MIL.M_BILINEAR); // Preprocess the model. MIL.MpatPreprocModel(MilSourceImage, MilModel, MIL.M_DEFAULT); // Allocate a result buffer. MIL.MpatAllocResult(MilSystem, 1, ref MilResult); // Draw the original model position MIL.MpatDraw(MIL.M_DEFAULT, MilModel, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, MIL.M_DEFAULT, MIL.M_ORIGINAL); // Pause to show the original image and model position. Console.Write("\nA {0}x{1} model was defined in the source image.\n", ROTATED_FIND_MODEL_WIDTH, ROTATED_FIND_MODEL_HEIGHT); Console.Write("It will be searched in images rotated from {0} degree to {1} degree.\n", -ROTATED_FIND_ROTATION_DELTA_ANGLE, ROTATED_FIND_ROTATION_DELTA_ANGLE); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Dummy first call for bench measure purpose only (bench stabilization, cache effect, etc...). This first call is NOT required by the application. MIL.MpatFindModel(MilSourceImage, MilModel, MilResult); // If the model was found above the acceptance threshold. if (MIL.MpatGetNumber(MilResult, MIL.M_NULL) == 1) { // Search for the model in images at different angles. RealAngle = ROTATED_FIND_ROTATION_DELTA_ANGLE; while (RealAngle >= -ROTATED_FIND_ROTATION_DELTA_ANGLE) { // Rotate the image from the model image to target image. MIL.MimRotate(MilSourceImage, MilTargetImage, RealAngle, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_BILINEAR + MIL.M_OVERSCAN_CLEAR); // Reset the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Find the model in the target image. MIL.MpatFindModel(MilTargetImage, MilModel, MilResult); // Read the time spent in MpatFindModel(). MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // Clear the annotations. MIL.MgraClear(MIL.M_DEFAULT, GraphicList); // If one model was found above the acceptance threshold. if (MIL.MpatGetNumber(MilResult) == 1) { // Read results and draw a box around model occurrence. MIL.MpatGetResult(MilResult, MIL.M_POSITION_X, ref X); MIL.MpatGetResult(MilResult, MIL.M_POSITION_Y, ref Y); MIL.MpatGetResult(MilResult, MIL.M_ANGLE, ref Angle); MIL.MpatGetResult(MilResult, MIL.M_SCORE, ref Score); MIL.MgraColor(MIL.M_DEFAULT, AnnotationColor); MIL.MpatDraw(MIL.M_DEFAULT, MilResult, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, MIL.M_DEFAULT, MIL.M_DEFAULT); MIL.MbufCopy(MilTargetImage, MilDisplayImage); // Calculate the angle error and the position errors for statistics. ErrAngle = CalculateAngleDist(Angle, RealAngle); RotateModelCenter(MilSourceImage, ref RealX, ref RealY, RealAngle); ErrX = Math.Abs(X - RealX); ErrY = Math.Abs(Y - RealY); SumErrAngle += ErrAngle; SumErrX += ErrX; SumErrY += ErrY; SumTime += Time; NbFound++; // Verify the precision for the position and the angle. if ((ErrX > ROTATED_FIND_MIN_POSITION_ACCURACY) || (ErrY > ROTATED_FIND_MIN_POSITION_ACCURACY) || (ErrAngle > ROTATED_FIND_MIN_ANGLE_ACCURACY)) { Console.Write("Model accuracy error at angle {0:0.0} !\n\n", RealAngle); Console.Write("Errors are X:{0:0.000}, Y:{1:0.000} and Angle:{2:0.00}\n\n", ErrX, ErrY, ErrAngle); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); } } else { Console.Write("Model was not found at angle {0:0.0} !\n\n", RealAngle); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); } RealAngle -= ROTATED_FIND_ROTATION_ANGLE_STEP; } // Print out the search result statistics // of the models found in rotated images. Console.Write("\nSearch statistics for the model found in the rotated images.\n"); Console.Write("------------------------------------------------------------\n"); Console.Write("The average position error is \t\tX:{0:0.000}, Y:{1:0.000}\n", SumErrX / NbFound, SumErrY / NbFound); Console.Write("The average angle error is \t\t{0:0.000}\n", SumErrAngle / NbFound); Console.Write("The average search time is \t\t{0:0.000} ms\n\n", SumTime * 1000.0 / NbFound); } else { Console.Write("Model was not found!\n\n"); } // Wait for a key to be pressed. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Free all allocations. MIL.MgraFree(GraphicList); MIL.MpatFree(MilResult); MIL.MpatFree(MilModel); MIL.MbufFree(MilTargetImage); MIL.MbufFree(MilSourceImage); MIL.MbufFree(MilDisplayImage); }
static void MultipleModelExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID GraphicList = MIL.M_NULL; // Graphic list identifier. MIL_ID MilSearchContext = MIL.M_NULL; // Search context. MIL_ID MilResult = MIL.M_NULL; // Result identifier. double[] ModelsDrawColor = new double[MODELS_ARRAY_SIZE]; // Model drawing colors. MIL_INT NumResults = 0; // Number of results found. MIL_INT[] Models = new MIL_INT[MODELS_MAX_OCCURRENCES]; // Model indices. MIL_INT[] ModelsOffsetX = new MIL_INT[MODELS_ARRAY_SIZE]; // Model X offsets array. MIL_INT[] ModelsOffsetY = new MIL_INT[MODELS_ARRAY_SIZE]; // Model Y offsets array. MIL_INT[] ModelsSizeX = new MIL_INT[MODELS_ARRAY_SIZE]; // Model X sizes array. MIL_INT[] ModelsSizeY = new MIL_INT[MODELS_ARRAY_SIZE]; // Model Y sizes array. double[] Score = new double[MODELS_MAX_OCCURRENCES]; // Model correlation scores. double[] XPosition = new double[MODELS_MAX_OCCURRENCES]; // Model X positions. double[] YPosition = new double[MODELS_MAX_OCCURRENCES]; // Model Y positions. double[] Angle = new double[MODELS_MAX_OCCURRENCES]; // Model occurrence angles. double[] Scale = new double[MODELS_MAX_OCCURRENCES]; // Model occurrence scales. double Time = 0.0; // Time variable. int i; // Loop variable. // Models array specifications. ModelsOffsetX[0] = MODEL0_OFFSETX; ModelsOffsetX[1] = MODEL1_OFFSETX; ModelsOffsetX[2] = MODEL2_OFFSETX; ModelsOffsetY[0] = MODEL0_OFFSETY; ModelsOffsetY[1] = MODEL1_OFFSETY; ModelsOffsetY[2] = MODEL2_OFFSETY; ModelsSizeX[0] = MODEL0_SIZEX; ModelsSizeX[1] = MODEL1_SIZEX; ModelsSizeX[2] = MODEL2_SIZEX; ModelsSizeY[0] = MODEL0_SIZEY; ModelsSizeY[1] = MODEL1_SIZEY; ModelsSizeY[2] = MODEL2_SIZEY; ModelsDrawColor[0] = MODEL0_DRAW_COLOR; ModelsDrawColor[1] = MODEL1_DRAW_COLOR; ModelsDrawColor[2] = MODEL2_DRAW_COLOR; // Restore the model image and display it. MIL.MbufRestore(MULTI_MODELS_IMAGE, MilSystem, ref MilImage); MIL.MdispSelect(MilDisplay, MilImage); // Allocate a graphic list to hold the subpixel annotations to draw. MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref GraphicList); // Associate the graphic list to the display for annotations. MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); // Allocate a geometric model finder. MIL.MmodAlloc(MilSystem, MIL.M_GEOMETRIC, MIL.M_DEFAULT, ref MilSearchContext); // Allocate a result buffer. MIL.MmodAllocResult(MilSystem, MIL.M_DEFAULT, ref MilResult); // Define the models. for (i = 0; i < NUMBER_OF_MODELS; i++) { MIL.MmodDefine(MilSearchContext, MIL.M_IMAGE, MilImage, (double)ModelsOffsetX[i], (double)ModelsOffsetY[i], (double)ModelsSizeX[i], (double)ModelsSizeY[i]); } // Set the desired search speed. MIL.MmodControl(MilSearchContext, MIL.M_CONTEXT, MIL.M_SPEED, MULTI_MODELS_SEARCH_SPEED); // Increase the smoothness for the edge extraction in the search context. MIL.MmodControl(MilSearchContext, MIL.M_CONTEXT, MIL.M_SMOOTHNESS, 75); // Modify the acceptance and the certainty for all the models that were defined. MIL.MmodControl(MilSearchContext, MIL.M_DEFAULT, MIL.M_ACCEPTANCE, 40); MIL.MmodControl(MilSearchContext, MIL.M_DEFAULT, MIL.M_CERTAINTY, 60); // Set the number of occurrences to 2 for all the models that were defined. MIL.MmodControl(MilSearchContext, MIL.M_DEFAULT, MIL.M_NUMBER, 2); if (NUMBER_OF_MODELS > 1) { // Change the reference point of the second model. MIL.MmodControl(MilSearchContext, 1, MIL.M_REFERENCE_X, MODEL1_REFERENCEX); MIL.MmodControl(MilSearchContext, 1, MIL.M_REFERENCE_Y, MODEL1_REFERENCEY); } if (NUMBER_OF_MODELS > 2) { // Change the reference point of the third model. MIL.MmodControl(MilSearchContext, 2, MIL.M_REFERENCE_X, MODEL2_REFERENCEX); MIL.MmodControl(MilSearchContext, 2, MIL.M_REFERENCE_Y, MODEL2_REFERENCEY); } // Preprocess the search context. MIL.MmodPreprocess(MilSearchContext, MIL.M_DEFAULT); // Draw boxes and positions in the source image to identify the models. for (i = 0; i < NUMBER_OF_MODELS; i++) { MIL.MgraColor(MIL.M_DEFAULT, ModelsDrawColor[i]); MIL.MmodDraw(MIL.M_DEFAULT, MilSearchContext, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, i, MIL.M_ORIGINAL); } // Pause to show the models. Console.Write("A model context was defined with the models in the displayed image.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Clear annotations. MIL.MgraClear(MIL.M_DEFAULT, GraphicList); // Load the complex target image. MIL.MbufLoad(MULTI_MODELS_TARGET_IMAGE, MilImage); // Dummy first call for bench measure purpose only (bench stabilization, cache effect, etc...). This first call is NOT required by the application. MIL.MmodFind(MilSearchContext, MilImage, MilResult); // Reset the timer. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Find the models. MIL.MmodFind(MilSearchContext, MilImage, MilResult); // Read the find time. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // Get the number of models found. MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_NUMBER + MIL.M_TYPE_MIL_INT, ref NumResults); // If the models were found above the acceptance threshold. if ((NumResults >= 1) && (NumResults <= MODELS_MAX_OCCURRENCES)) { // Get the results for each model. MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_INDEX + MIL.M_TYPE_MIL_INT, Models); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_POSITION_X, XPosition); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_POSITION_Y, YPosition); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_ANGLE, Angle); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_SCALE, Scale); MIL.MmodGetResult(MilResult, MIL.M_DEFAULT, MIL.M_SCORE, Score); // Print information about the target image. Console.Write("The models were found in the target image although there is:\n"); Console.Write(" Full rotation\n Small scale change\n Contrast variation\n"); Console.Write(" Specular reflection\n Occlusion\n Multiple models\n"); Console.Write(" Multiple occurrences\n\n"); // Print the results for the found models. Console.Write("Result Model X Position Y Position Angle Scale Score\n\n"); for (i = 0; i < NumResults; i++) { Console.Write("{0,-9}{1,-8}{2,-13:0.00}{3,-13:#.00}{4,-8:0.00}{5,-8:0.00}{6,-5:0.00}%\n", i, Models[i], XPosition[i], YPosition[i], Angle[i], Scale[i], Score[i]); } Console.Write("\nThe search time is {0:0.0} ms\n\n", Time * 1000.0); // Draw edges and positions over the occurrences that were found. for (i = 0; i < NumResults; i++) { MIL.MgraColor(MIL.M_DEFAULT, ModelsDrawColor[Models[i]]); MIL.MmodDraw(MIL.M_DEFAULT, MilResult, GraphicList, MIL.M_DRAW_EDGES + MIL.M_DRAW_POSITION, i, MIL.M_DEFAULT); } } else { Console.Write("The models were not found or the number of models found is greater than\n"); Console.Write("the defined value of maximum occurrences !\n\n"); } // Wait for a key to be pressed. Console.Write("Press <Enter> to end.\n\n"); Console.ReadKey(); // Free MIL objects. MIL.MgraFree(GraphicList); MIL.MbufFree(MilImage); MIL.MmodFree(MilSearchContext); MIL.MmodFree(MilResult); }
static void SearchModelExample(MIL_ID MilSystem, MIL_ID MilDisplay) { MIL_ID MilImage = MIL.M_NULL; // Image buffer identifier. MIL_ID GraphicList = MIL.M_NULL; // Graphic list identifier. MIL_ID Model = MIL.M_NULL; // Model identifier. MIL_ID Result = MIL.M_NULL; // Result identifier. double XOrg = 0.0; // Original model position. double YOrg = 0.0; double x = 0.0; // Model position. double y = 0.0; double ErrX = 0.0; // Model error position. double ErrY = 0.0; double Score = 0.0; // Model correlation score. double Time = 0.0; // Model search time. double AnnotationColor = MIL.M_COLOR_GREEN; // Drawing color. // Restore source image into an automatically allocated image buffer. MIL.MbufRestore(FIND_IMAGE_FILE, MilSystem, ref MilImage); // Display the image buffer. MIL.MdispSelect(MilDisplay, MilImage); // Allocate a graphic list to hold the subpixel annotations to draw. MIL.MgraAllocList(MilSystem, MIL.M_DEFAULT, ref GraphicList); // Associate the graphic list to the display for annotations. MIL.MdispControl(MilDisplay, MIL.M_ASSOCIATED_GRAPHIC_LIST_ID, GraphicList); // Allocate a normalized grayscale model. MIL.MpatAllocModel(MilSystem, MilImage, FIND_MODEL_X_POS, FIND_MODEL_Y_POS, FIND_MODEL_WIDTH, FIND_MODEL_HEIGHT, MIL.M_NORMALIZED, ref Model); // Set the search accuracy to high. MIL.MpatSetAccuracy(Model, MIL.M_HIGH); // Set the search model speed to high. MIL.MpatSetSpeed(Model, MIL.M_HIGH); // Preprocess the model. MIL.MpatPreprocModel(MilImage, Model, MIL.M_DEFAULT); // Draw a box around the model in the model image. MIL.MgraColor(MIL.M_DEFAULT, AnnotationColor); MIL.MpatDraw(MIL.M_DEFAULT, Model, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, MIL.M_DEFAULT, MIL.M_ORIGINAL); // Pause to show the original image and model position. Console.Write("\nA {0}x{1} model was defined in the source image.\n", FIND_MODEL_WIDTH, FIND_MODEL_HEIGHT); Console.Write("It will be found in an image shifted by {0:0.00} in X and {1:0.00} in Y.\n", FIND_SHIFT_X, FIND_SHIFT_Y); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Clear annotations. MIL.MgraClear(MIL.M_DEFAULT, GraphicList); // Translate the image on a subpixel level. MIL.MimTranslate(MilImage, MilImage, FIND_SHIFT_X, FIND_SHIFT_Y, MIL.M_DEFAULT); // Allocate result buffer. MIL.MpatAllocResult(MilSystem, 1, ref Result); // Dummy first call for bench measure purpose only (bench stabilization, cache effect, etc...). This first call is NOT required by the application. MIL.MpatFindModel(MilImage, Model, Result); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Find the model in the target buffer. MIL.MpatFindModel(MilImage, Model, Result); // Read the time spent in MpatFindModel. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); // If one model was found above the acceptance threshold. if (MIL.MpatGetNumber(Result) == 1L) { // Read results and draw a box around the model occurrence. MIL.MpatGetResult(Result, MIL.M_POSITION_X, ref x); MIL.MpatGetResult(Result, MIL.M_POSITION_Y, ref y); MIL.MpatGetResult(Result, MIL.M_SCORE, ref Score); MIL.MgraColor(MIL.M_DEFAULT, AnnotationColor); MIL.MpatDraw(MIL.M_DEFAULT, Result, GraphicList, MIL.M_DRAW_BOX + MIL.M_DRAW_POSITION, MIL.M_DEFAULT, MIL.M_DEFAULT); // Calculate the position errors in X and Y and inquire original model position. ErrX = Math.Abs((FIND_MODEL_X_CENTER + FIND_SHIFT_X) - x); ErrY = Math.Abs((FIND_MODEL_Y_CENTER + FIND_SHIFT_Y) - y); MIL.MpatInquire(Model, MIL.M_ORIGINAL_X, ref XOrg); MIL.MpatInquire(Model, MIL.M_ORIGINAL_Y, ref YOrg); // Print out the search result of the model in the original image. Console.Write("Search results:\n"); Console.Write("---------------------------------------------------\n"); Console.Write("The model is found to be shifted by \tX:{0:0.00}, Y:{1:0.00}.\n", x - XOrg, y - YOrg); Console.Write("The model position error is \t\tX:{0:0.00}, Y:{1:0.00}\n", ErrX, ErrY); Console.Write("The model match score is \t\t{0:0.0}\n", Score); Console.Write("The search time is \t\t\t{0:0.000} ms\n\n", Time * 1000.0); // Verify the results. if ((Math.Abs((x - XOrg) - FIND_SHIFT_X) > FIND_MODEL_MIN_ACCURACY) || (Math.Abs((y - YOrg) - FIND_SHIFT_Y) > FIND_MODEL_MIN_ACCURACY) || (Score < FIND_MODEL_MIN_MATCH_SCORE)) { Console.Write("Results verification error !\n"); } } else { Console.Write("Model not found !\n"); } // Wait for a key to be pressed. Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Clear annotations. MIL.MgraClear(MIL.M_DEFAULT, GraphicList); // Free all allocations. MIL.MgraFree(GraphicList); MIL.MpatFree(Result); MIL.MpatFree(Model); MIL.MbufFree(MilImage); }
static void Main(string[] args) { MIL_ID MilApplication = MIL.M_NULL; // Application identifier. MIL_ID MilSystem = MIL.M_NULL; // System identifier. MIL_ID MilDisplay = MIL.M_NULL; // Display identifier. MIL_ID MilDisplayImage = MIL.M_NULL; // Image buffer identifier. MIL_ID MilSourceImage = MIL.M_NULL; // Image buffer identifier. MIL_ID Mil4CornerArray = MIL.M_NULL; // Coefficients buffer identifier. MIL_ID MilLutX = MIL.M_NULL; // Lut buffer identifier. MIL_ID MilLutY = MIL.M_NULL; // Lut buffer identifier. MIL_ID ChildWindow = MIL.M_NULL; // Child Image identifier. float[] FourCornerMatrix = new float[12] { 0.0F, // X coordinate of quadrilateral's 1st corner 0.0F, // Y coordinate of quadrilateral's 1st corner 456.0F, // X coordinate of quadrilateral's 2nd corner 62.0F, // Y coordinate of quadrilateral's 2nd corner 333.0F, // X coordinate of quadrilateral's 3rd corner 333.0F, // Y coordinate of quadrilateral's 3rd corner 100.0F, // X coordinate of quadrilateral's 4th corner 500.0F, // Y coordinate of quadrilateral's 4th corner 0.0F, // X coordinate of rectangle's top-left corner 0.0F, // Y coordinate of rectangle's top-left corner 511.0F, // X coordinate of rectangle's bottom-right corner 511.0F }; // Y coordinate of rectangle's bottom-right corner int Precision = FIXED_POINT_PRECISION; int Interpolation = MIL.M_NEAREST_NEIGHBOR; short[] MilLutXPtr, MilLutYPtr; int OffsetX = 0; MIL_INT ImageWidth = 0; MIL_INT ImageHeight = 0; MIL_INT ImageType = 0; int i = 0; int j = 0; double FramesPerSecond = 0.0; double Time = 0.0; double NbLoop = 0.0; // Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, ref MilApplication, ref MilSystem, ref MilDisplay, MIL.M_NULL, MIL.M_NULL); // Restore the source image. MIL.MbufRestore(IMAGE_FILE, MilSystem, ref MilSourceImage); // Allocate a display buffers and show the source image. MIL.MbufInquire(MilSourceImage, MIL.M_SIZE_X, ref ImageWidth); MIL.MbufInquire(MilSourceImage, MIL.M_SIZE_Y, ref ImageHeight); MIL.MbufInquire(MilSourceImage, MIL.M_TYPE, ref ImageType); MIL.MbufAlloc2d(MilSystem, ImageWidth, ImageHeight, ImageType, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, ref MilDisplayImage); MIL.MbufCopy(MilSourceImage, MilDisplayImage); MIL.MdispSelect(MilDisplay, MilDisplayImage); // Print a message. Console.Write("\nWARPING:\n"); Console.Write("--------\n\n"); Console.Write("This image will be warped using different methods.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Four-corner LUT warping //------------------------- // Allocate 2 LUT buffers. MIL.MbufAlloc2d(MilSystem, ImageWidth, ImageHeight, 16 + MIL.M_SIGNED, MIL.M_LUT, ref MilLutX); MIL.MbufAlloc2d(MilSystem, ImageWidth, ImageHeight, 16 + MIL.M_SIGNED, MIL.M_LUT, ref MilLutY); // Allocate the coefficient buffer. MIL.MbufAlloc2d(MilSystem, 12, 1, 32 + MIL.M_FLOAT, MIL.M_ARRAY, ref Mil4CornerArray); // Put warp values into the coefficient buffer. MIL.MbufPut1d(Mil4CornerArray, 0, 12, FourCornerMatrix); // Generate LUT buffers. MIL.MgenWarpParameter(Mil4CornerArray, MilLutX, MilLutY, MIL.M_WARP_4_CORNER + Precision, MIL.M_DEFAULT, 0.0, 0.0); // Clear the destination. MIL.MbufClear(MilDisplayImage, 0); // Warp the image. MIL.MimWarp(MilSourceImage, MilDisplayImage, MilLutX, MilLutY, MIL.M_WARP_LUT + Precision, Interpolation); // Print a message. Console.Write("The image was warped from an arbitrary quadrilateral to a square.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Sinusoidal LUT warping //------------------------ // Allocate user-defined LUTs. MilLutXPtr = new short[ImageHeight * ImageWidth]; MilLutYPtr = new short[ImageHeight * ImageWidth]; // Fill the LUT with a sinusoidal waveforms with a 6-bit precision. for (j = 0; j < ImageHeight; j++) { for (i = 0; i < ImageWidth; i++) { MilLutYPtr[i + (j * ImageWidth)] = (short)FLOAT_TO_FIXED_POINT(((j) + (int)((20 * Math.Sin(0.03 * i))))); MilLutXPtr[i + (j * ImageWidth)] = (short)FLOAT_TO_FIXED_POINT(((i) + (int)((20 * Math.Sin(0.03 * j))))); } } // Put the values into the LUT buffers. MIL.MbufPut2d(MilLutX, 0, 0, ImageWidth, ImageHeight, MilLutXPtr); MIL.MbufPut2d(MilLutY, 0, 0, ImageWidth, ImageHeight, MilLutYPtr); // Clear the destination. MIL.MbufClear(MilDisplayImage, 0); // Warp the image. MIL.MimWarp(MilSourceImage, MilDisplayImage, MilLutX, MilLutY, MIL.M_WARP_LUT + Precision, Interpolation); // wait for a key Console.Write("The image was warped on two sinusoidal waveforms.\n"); Console.Write("Press <Enter> to continue.\n\n"); Console.ReadKey(); // Continuous spherical LUT warping //-------------------------------- // Allocate temporary buffer. MIL.MbufFree(MilSourceImage); MIL.MbufAlloc2d(MilSystem, ImageWidth * 2, ImageHeight, ImageType, MIL.M_IMAGE + MIL.M_PROC, ref MilSourceImage); // Reload the image. MIL.MbufLoad(IMAGE_FILE, MilSourceImage); // Fill the LUTs with a sphere pattern with a 6-bit precision. GenerateSphericLUT(ImageWidth, ImageHeight, MilLutXPtr, MilLutYPtr); MIL.MbufPut2d(MilLutX, 0, 0, ImageWidth, ImageHeight, MilLutXPtr); MIL.MbufPut2d(MilLutY, 0, 0, ImageWidth, ImageHeight, MilLutYPtr); // Duplicate the buffer to allow wrap around in the warping. MIL.MbufCopy(MilSourceImage, MilDisplayImage); MIL.MbufChild2d(MilSourceImage, ImageWidth, 0, ImageWidth, ImageHeight, ref ChildWindow); MIL.MbufCopy(MilDisplayImage, ChildWindow); MIL.MbufFree(ChildWindow); // Clear the destination. MIL.MbufClear(MilDisplayImage, 0); // Print a message and start the timer. Console.Write("The image is continuously warped on a sphere.\n"); Console.Write("Press <Enter> to stop.\n\n"); MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, MIL.M_NULL); // Warp the image continuously. while (!Console.KeyAvailable) { // Create a child in the buffer containing the two images. MIL.MbufChild2d(MilSourceImage, OffsetX, 0, ImageWidth, ImageHeight, ref ChildWindow); // Warp the child in the window. MIL.MimWarp(ChildWindow, MilDisplayImage, MilLutX, MilLutY, MIL.M_WARP_LUT + Precision, Interpolation); // Update the offset (shift the window to the right). OffsetX += ROTATION_STEP; // Reset the offset if the child is outside the buffer. if (OffsetX > ImageWidth - 1) { OffsetX = 0; } // Free the child. MIL.MbufFree(ChildWindow); NbLoop++; // Calculate and print the number of frames per second processed. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, ref Time); FramesPerSecond = NbLoop / Time; Console.Write("Processing speed: {0:0} Images/Sec.\r", FramesPerSecond); YieldToGUI(); } Console.ReadKey(); // Free objects. MIL.MbufFree(MilLutX); MIL.MbufFree(MilLutY); MIL.MbufFree(Mil4CornerArray); MIL.MbufFree(MilSourceImage); MIL.MbufFree(MilDisplayImage); MIL.MappFreeDefault(MilApplication, MilSystem, MilDisplay, MIL.M_NULL, MIL.M_NULL); }