Click here to show toolbars of the Web Online Help System: show toolbars |
'''**************************************************************************** ' ' File name: MimWarp.vb ' 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-2020. ' All Rights Reserved '***************************************************************************** Imports Microsoft.VisualBasic Imports System Imports System.Collections.Generic Imports System.Text Imports Matrox.MatroxImagingLibrary Namespace MImWarp Friend Class Program ' Target image specifications. Private Const IMAGE_FILE As String = MIL.M_IMAGE_PATH & "BaboonMono.mim" Private Const INTERPOLATION_MODE As Integer = MIL.M_NEAREST_NEIGHBOR Private Shared ReadOnly Property FIXED_POINT_PRECISION() As Integer Get Return MIL.M_FIXED_POINT + (If((INTERPOLATION_MODE = MIL.M_NEAREST_NEIGHBOR), 0, 6)) End Get End Property Private Shared Function FLOAT_TO_FIXED_POINT(ByVal x As Double) As Integer Return CInt(Fix((If((INTERPOLATION_MODE = MIL.M_NEAREST_NEIGHBOR), 1, 64)) * x)) End Function Private Const ROTATION_STEP As Integer = 1 Shared Sub Main(ByVal args() As String) Dim MilApplication As MIL_ID = MIL.M_NULL ' Application identifier. Dim MilSystem As MIL_ID = MIL.M_NULL ' System identifier. Dim MilDisplay As MIL_ID = MIL.M_NULL ' Display identifier. Dim MilDisplayImage As MIL_ID = MIL.M_NULL ' Image buffer identifier. Dim MilSourceImage As MIL_ID = MIL.M_NULL ' Image buffer identifier. Dim Mil4CornerArray As MIL_ID = MIL.M_NULL ' Coefficients buffer identifier. Dim MilLutX As MIL_ID = MIL.M_NULL ' Lut buffer identifier. Dim MilLutY As MIL_ID = MIL.M_NULL ' Lut buffer identifier. Dim ChildWindow As MIL_ID = MIL.M_NULL ' Child Image identifier. Dim FourCornerMatrix() As Single = {0.0F, 0.0F, 456.0F, 62.0F, 333.0F, 333.0F, 100.0F, 500.0F, 0.0F, 0.0F, 511.0F, 511.0F} ' Y coordinate of rectangle's bottom-right corner Dim Precision As MIL_INT = FIXED_POINT_PRECISION Dim Interpolation As MIL_INT = INTERPOLATION_MODE Dim MilLutXPtr(), MilLutYPtr() As Short Dim OffsetX As MIL_INT = 0 Dim ImageWidth As MIL_INT = 0 Dim ImageHeight As MIL_INT = 0 Dim ImageType As MIL_INT = 0 Dim i As MIL_INT = 0 Dim j As MIL_INT = 0 Dim FramesPerSecond As Double = 0.0 Dim Time As Double = 0.0 Dim NbLoop As Double = 0.0 ' Allocate defaults. MIL.MappAllocDefault(MIL.M_DEFAULT, MilApplication, MilSystem, MilDisplay, CType(MIL.M_NULL, IntPtr), CType(MIL.M_NULL, IntPtr)) ' Restore the source image. MIL.MbufRestore(IMAGE_FILE, MilSystem, MilSourceImage) ' Allocate a display buffers and show the source image. MIL.MbufAlloc2d(MilSystem, _ MIL.MbufInquire(MilSourceImage, MIL.M_SIZE_X, ImageWidth), _ MIL.MbufInquire(MilSourceImage, MIL.M_SIZE_Y, ImageHeight), _ MIL.MbufInquire(MilSourceImage, MIL.M_TYPE, ImageType), _ MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, MilDisplayImage) MIL.MbufCopy(MilSourceImage, MilDisplayImage) MIL.MdispSelect(MilDisplay, MilDisplayImage) ' Print a message. Console.Write(Constants.vbLf + "WARPING:" + Constants.vbLf) Console.Write("--------" + Constants.vbLf + Constants.vbLf) Console.Write("This image will be warped using different methods." + Constants.vbLf) Console.Write("Press <Enter> to continue." + Constants.vbLf + Constants.vbLf) Console.ReadKey() ' Four-corner LUT warping '------------------------- ' Allocate 2 LUT buffers. MIL.MbufAlloc2d(MilSystem, ImageWidth, ImageHeight, 16 + MIL.M_SIGNED, MIL.M_LUT, MilLutX) MIL.MbufAlloc2d(MilSystem, ImageWidth, ImageHeight, 16 + MIL.M_SIGNED, MIL.M_LUT, MilLutY) ' Allocate the coefficient buffer. MIL.MbufAlloc2d(MilSystem, 12, 1, 32 + MIL.M_FLOAT, MIL.M_ARRAY, 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." + Constants.vbLf) Console.Write("Press <Enter> to continue." + Constants.vbLf + Constants.vbLf) Console.ReadKey() ' Sinusoidal LUT warping '------------------------ ' Allocate user-defined LUTs. MilLutXPtr = New Short(CInt(ImageHeight * ImageWidth - 1)) {} MilLutYPtr = New Short(CInt(ImageHeight * ImageWidth - 1)) {} ' Fill the LUT with a sinusoidal waveforms with a 6-bit precision. For j = 0 To CInt(ImageHeight - 1) For i = 0 To CInt(ImageWidth - 1) MilLutYPtr(CInt(i + (j * ImageWidth))) = CShort(Fix(FLOAT_TO_FIXED_POINT(((CDbl(j)) + CInt(Fix((20 * Math.Sin(0.03 * CDbl(i))))))))) MilLutXPtr(CInt(i + (j * ImageWidth))) = CShort(Fix(FLOAT_TO_FIXED_POINT(((CDbl(i)) + CInt(Fix((20 * Math.Sin(0.03 * CDbl(j))))))))) Next i Next 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." + Constants.vbLf) Console.Write("Press <Enter> to continue." + Constants.vbLf + Constants.vbLf) 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, 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, 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." + Constants.vbLf) Console.Write("Press <Enter> to stop." + Constants.vbLf + Constants.vbLf) MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_RESET + MIL.M_SYNCHRONOUS, CType(MIL.M_NULL, IntPtr)) ' Create a child in the buffer containing the two images. MIL.MbufChild2d(MilSourceImage, OffsetX, 0, ImageWidth, ImageHeight, ChildWindow) ' Warp the image continuously. Do While ((Not Console.KeyAvailable) Or (OffsetX <> (ImageWidth / 4))) ' Create a child in the buffer containing the two images. 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 Then OffsetX = 0 End If NbLoop += 1 ' Calculate and print the number of frames per second processed. MIL.MappTimer(MIL.M_DEFAULT, MIL.M_TIMER_READ + MIL.M_SYNCHRONOUS, Time) FramesPerSecond = NbLoop / Time Console.Write("Processing speed: {0:0} Images/Sec." & Constants.vbCr, FramesPerSecond) YieldToGUI() Loop Console.ReadKey() Console.Write(Constants.vbLf + "Press <Enter> to end." + Constants.vbLf) 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) End Sub ' Generate two custom LUTs used to map the image on a sphere. ' ----------------------------------------------------------- Private Shared Sub GenerateSphericLUT(ByVal ImageWidth As MIL_INT, ByVal ImageHeight As MIL_INT, ByVal MilLutXPtr() As Short, ByVal MilLutYPtr() As Short) Dim i, j, k As MIL_INT Dim utmp, vtmp, tmp As Double Dim v As Short ' Set the radius of the sphere Dim Radius As Double = 200.0 ' Generate the X and Y buffers For j = 0 To ImageHeight - 1 k = j * ImageWidth ' Check that still in the sphere (in the Y axis). vtmp = (CDbl(j - (ImageHeight / 2)) / Radius) If Math.Abs(vtmp) < 1.0 Then ' We scan from top to bottom, so reverse the value obtained above ' and obtain the angle. vtmp = Math.Acos(-vtmp) If vtmp = 0.0 Then vtmp = 0.0000001 End If ' Compute the position to fetch in the source. v = CShort(Fix((vtmp / 3.1415926) * CDbl(ImageHeight - 1) + 0.5)) ' Compute the Y coordinate of the sphere. tmp = Radius * Math.Sin(vtmp) For i = 0 To ImageWidth - 1 ' Check that still in the sphere. utmp = (CDbl(i - (ImageWidth / 2)) / tmp) If Math.Abs(utmp) < 1.0 Then utmp = Math.Acos(-utmp) ' Compute the position to fetch (fold the image in four). MilLutXPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(((utmp / 3.1415926) * CDbl((ImageWidth / 2) - 1) + 0.5)))) MilLutYPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(v))) Else ' Default position (fetch outside the buffer to ' activate the clear overscan). MilLutXPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(ImageWidth))) MilLutYPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(ImageHeight))) End If Next i Else For i = 0 To ImageWidth - 1 ' Default position (fetch outside the buffer for clear overscan). MilLutXPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(ImageWidth))) MilLutYPtr(CInt(i + k)) = CShort(Fix(FLOAT_TO_FIXED_POINT(ImageHeight))) Next i End If Next j End Sub ' 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. Private Shared Sub YieldToGUI() #If M_MIL_USE_CE Then System.Threading.Thread.Sleep(0) #End If End Sub End Class End Namespace