Click here to show toolbars of the Web Online Help System: show toolbars |
///**************************************************************************** // // File name: MimWarp.cs // Location: See Matrox Example Launcher in the MIL Control Center // // // Synopsis: : This program performs three types of warp transformations. // First the image is stretched according to four specified // reference points. Then it is warped on a sinusoid, and // finally, the program loops while warping the image on a // sphere. // // Copyright (C) Matrox Electronic Systems Ltd., 1992-2016. // All Rights Reserved //***************************************************************************** using System; using System.Collections.Generic; using System.Text; using Matrox.MatroxImagingLibrary; namespace MImWarp { class Program { // Target image specifications. private const string IMAGE_FILE = MIL.M_IMAGE_PATH + "BaboonMono.mim"; private const int INTERPOLATION_MODE = MIL.M_NEAREST_NEIGHBOR; private static int FIXED_POINT_PRECISION { get { return MIL.M_FIXED_POINT + ((INTERPOLATION_MODE == MIL.M_NEAREST_NEIGHBOR) ? 0 : 6); } } private static int FLOAT_TO_FIXED_POINT(double x) { return (int)(((INTERPOLATION_MODE == MIL.M_NEAREST_NEIGHBOR) ? 1 : 64) * x); } private const int ROTATION_STEP = 1; 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 MIL_INT Precision = FIXED_POINT_PRECISION; MIL_INT Interpolation = INTERPOLATION_MODE; short[] MilLutXPtr, MilLutYPtr; MIL_INT OffsetX = 0; MIL_INT ImageWidth = 0; MIL_INT ImageHeight = 0; MIL_INT ImageType = 0; MIL_INT i = 0; MIL_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.MbufAlloc2d(MilSystem, 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.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); // Create a child in the buffer containing the two images. MIL.MbufChild2d(MilSourceImage, OffsetX, 0, ImageWidth, ImageHeight, ref ChildWindow); // Warp the image continuously. while ((!Console.KeyAvailable) || (OffsetX != (ImageWidth / 4))) { // Move the child to the new position MIL.MbufChildMove(ChildWindow, OffsetX, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT); // 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; } 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(); Console.Write("\nPress <Enter> to end.\n"); Console.ReadKey(); // Free objects. MIL.MbufFree(ChildWindow); 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); } // Generate two custom LUTs used to map the image on a sphere. // ----------------------------------------------------------- static void GenerateSphericLUT(MIL_INT ImageWidth, MIL_INT ImageHeight, short[] MilLutXPtr, short[] MilLutYPtr) { MIL_INT i, j, k; double utmp, vtmp, tmp; short v; // Set the radius of the sphere double Radius = 200.0; // Generate the X and Y buffers for (j = 0; j < ImageHeight; j++) { k = j * ImageWidth; // Check that still in the sphere (in the Y axis). if (Math.Abs(vtmp = ((double)(j - (ImageHeight / 2)) / Radius)) < 1.0) { // We scan from top to bottom, so reverse the value obtained above // and obtain the angle. vtmp = Math.Acos(-vtmp); if (vtmp == 0.0) { vtmp = 0.0000001; } // Compute the position to fetch in the source. v = (short)((vtmp / 3.1415926) * (double)(ImageHeight - 1) + 0.5); // Compute the Y coordinate of the sphere. tmp = Radius * Math.Sin(vtmp); for (i = 0; i < ImageWidth; i++) { // Check that still in the sphere. if (Math.Abs(utmp = ((double)(i - (ImageWidth / 2)) / tmp)) < 1.0) { utmp = Math.Acos(-utmp); // Compute the position to fetch (fold the image in four). MilLutXPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(((utmp / 3.1415926) * (double)((ImageWidth / 2) - 1) + 0.5)); MilLutYPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(v); } else { // Default position (fetch outside the buffer to // activate the clear overscan). MilLutXPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(ImageWidth); MilLutYPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(ImageHeight); } } } else { for (i = 0; i < ImageWidth; i++) { // Default position (fetch outside the buffer for clear overscan). MilLutXPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(ImageWidth); MilLutYPtr[i + k] = (short)FLOAT_TO_FIXED_POINT(ImageHeight); } } } } // Windows Embedded Compact GUI Scheduling Adjustment Handling // --------------------------------------------- // NOTE: Under Windows Embedded Compact, YieldToGUI function improves system responsiveness // in case a normal Windows Embedded Compact console application thread is processing // in a while loop. static void YieldToGUI() { #if M_MIL_USE_CE System.Threading.Thread.Sleep(0); #endif } } }