Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Go Back  Xtreme Visual Basic Talk > > > Image warping using custom per pixel interpolation - needs performance tuning


Reply
 
Thread Tools Display Modes
  #1  
Old 10-27-2012, 07:13 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default Image warping using custom per pixel interpolation - needs performance tuning


In regard to warping using VB.Net

You can do it with DrawImage but its slow and limited:
Quote:
Originally Posted by Cags
As far as I'm aware the DrawImage overloads that accept a point array can only be used to draw a parallelogram (i.e. both vertical and both horizontal lines have to be parallel with each other).

If you are attempting to draw a parallelogram then 3 points will be entirely accurate since the sides in both pairs will be exactly equal in length a 4th point isn't required.

If you wish to draw a shape which isn't a parallelogram, then I believe you are out of luck as far as the DrawImage method goes.
..from this post in a thread asking about 4 point distortion.

Of course Cags is absolutely (but regrettably) correct.
The thread does include some C#.net code for trapezoidal warping but no VB.net code.

There does exist a working demo of trapezoidal warping using VB.Net code.
Here is the link.

Unfortunately it uses DrawImage in combination with the .Net Warping,
so it's totally slow and the only way it could real time speed is to be totally re-written
(I wonder if there is anyone on the forum that could do a multi-threaded version..possibly using APM and the IAsyncResult design pattern).

The best I could do with it is add grab handles to shape the trapezoid (see attachment below).

Some off forum links:
vbHelper Image Warping using DrawImage
vbHelper Image Warping using GetPixel/SetPixel
vbHelper - Drag points to warp an image in VB .NET using DrawImage
The last link is really the closest to what I need in terms of have a polygon shaped by grab handles but it only uses 3, not 4. points.
Rod Stevens even says on that page:
Quote:
Originally Posted by vbHelper site
[It would have been better if it (also) let the programmer specify where to put all four points.
Then you could perform the more useful mappings needed for three-dimensional graphics. Alas.]
Alas indeed, RS!


Of course there is a GraphicsPath.Warp method, but unfortunately the description
spells out the limitation:
Quote:
Applies a warp transform, defined by a rectangle and a parallelogram, to this GraphicsPath.
So what if you want a trapezoidal warp, or a an nonparallel diamond warp or (heaven forbid) an ovoid warp?
Quote:
Originally Posted by Me (but important!)
Here's the main point or "concern" of this thread:
Basically there is no way to do a polygon warp with 4 or more points without writing your own custom per pixel interpolation code
(or some awkward combination of DrawImage along with warp method patching as the trapezoidal attached below uses).
Which brings us to this Goggy Bi-lerping (Bilinear Interpolation) thread.
Of course the thread remains unresolved to this day.

Quote:
Important note: The .Net Warp method linked to above has a flaw.
If you look at post#12 (the last post) of the Goggy thread you'll see a link to some C++ code that fixes/patches the flaw with some "CureWrap" code
but also has an improved "QWrapper" code that bypasses the .Net Warp method entirely.

Also the C++ code doesn't work in the C++.Net express edition.
I think this is because the C++.Net doesn't included the MFC/ATL libraries that Sjaak's code needs.
If anyone has a non-Express version of C++.Net and wants to attempt a VB.Net translation it might help with the solution to this thread.

Some other C++ code can be found in combination with this CodeProject article:
"Transforming Images for Fun: A Local Grid-based Image Warper".
However in this post of that thread Goggy does make note of some C#.Net code that does provide such perpixel bi-lerping.

I looked around for the VB.Net equivalent of that C#.Net code and came up empty (the vbHelper per pixel warping code really doesn't
support as many point as you might thing once you look at the code carefully).

So I decided it was worth my time to attempt a Vb.Net translation.

It was challenging!
The C#.Net code uses unsafe pointers and code like "System.Void" which has no direct VB.Net equivalent,
however I persevered and somehow managed to get it working with just VB.net code.

The VB.Net version is slower than the C#.Net version so I decided to use
boops boops' FastPix GetPixel/SetPixel Lockbits wrapper class to speed things up but
(you guessed it) the FastPix code doesn't work.
It maybe something simple - the FastPix code requires a 32bpp image
(it's designed around alpha-containing ARGB graphics),
and maybe at some point the code is down converting it to 24bpp
but I can't catch it if that's the issue.

So..anyway..help required..but at least you have something that works, to performance tune,
and at this point, even if its slow,
its probably the best VB.Net warping code around,
(not just around the xvbt forum but around the whole internet - if you know of something like this that's better,
then please feel free to post a link).

The "big picture" reason this is important - controlled image warping (using custom pixel interpolation) will allow
WinForms texturemapping to 3D objects using a Point3D extender class
to the System.Drawing.Drawing2D namespace (without needed DirectX, OpenGL, or WPF).

Quote:
Edit1:
Found Paul Heckbert's nice Masters Thesis as a pdf "Fundamentals of Texture Mapping and Image Warping"
that has some of the math behind affine, projection and bilinear warping or "projection".

Also found this "Image Warping" pdf that lists some matrix math equations for the following warping functions:
Euclidean / Procrustes
Affine / 1st order polynomial
Bilinear
Perspective
2nd order polynomial / Biquadratic
General polynomial

This "Projective Mappings for Image Warping" pdf has some interesting math for "Inferring Projective Mappings" on page 3.

This FourCornerImageWarping pdf shows the math for a 1.5 order polynomial warping on page 3 along with some nice pictures of Bilinear Transformation and Perspective Transformation.

One of the best way to warp distort an image was something called the "Kai Power Goo",
part of the Kai Power Tools (KPT) plugins for Photoshop made by a company called MetaCreations.
Here's some links to what the interface looked like (1, 2, 3)
Of course MetaCreations got bought up by Corel and became part of the Corel KPT Collection.

Last edited by surfR2911; 10-28-2012 at 10:37 AM.
Reply With Quote
  #2  
Old 10-29-2012, 12:56 AM
passel's Avatar
passelImage warping using custom per pixel interpolation - needs performance tuning passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Well I had some old vb6 code that use PlgBlt to allow some simple four-corner stretching of a texture, only taking the X axis into consideration at this time and doesn't protect itself from corners being reversed.
Easily copied to a VB.Net project with the PlgBlt call replace with DrawImage. Only had about a half hour to mess with it, so no comments to speak of. Busy at work the next few months.
Not much to it, so nothing great.
{edit} Oh, click and drag near the corners of the image to move the corners.
Attached Files
File Type: zip FourCornerDistort.zip (261.5 KB, 46 views)
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #3  
Old 10-29-2012, 09:27 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default DrawImage: 3 point to 4 point warping conversion

Quote:
..so no comments to speak of. Busy at work the next few months.
Not much to it, so nothing great.
I will take your "not so great" code over anyone else's in the world anytime!

Even though the code makes a wholes series of DrawImage calls (inside a For..Next loop) it's plenty fast enough to be considered real time.

Of course "Dim pts(3) As Point" defines the four draggable points
and the "Dim ppnts(2) As Point" in the updatedrawing sub defines
the "down converted" array of three points (necessary to use DrawImage).

For an visual insight into how the code works change this line:
Code:
For X = 0 To rx Step ss
to this line:
Quote:
For X = 0 To rx - 299 Step ss
..then mousedown near the top of the pixel strip and
drag down and to the left.
You get the image in the first screenshot attached below,
showing a "band gapping" interpolation artifact.

These artifacts also show up in the unchanged code when dragging out of the graphics context at extreme angles (see screenshot2).

For a typical 3D cube mapping this is unimportant, but for any knife edge walls (like the corners in a 3D maze), it might be a limiting factor that will require some additional pixel interpolation "shimming".

Note I also changed this line:
Code:
dsG.DrawImage(srcBmp, ppnts, New Rectangle(CInt(sx), 0, 1, CInt(rx)), GraphicsUnit.Pixel)
to this line:
Code:
dsG.DrawImage(srcBmp, ppnts, New Rectangle(CInt(sx), 0, 1, 300), GraphicsUnit.Pixel)
..to get rid of "300" being used as a magic number.


Since the image is loaded as a resource in this line:
Code:
Dim srcBmp As New Bitmap(My.Resources.seemls4)
..if should be possible to set the four points using:
Code:
Dim intWidth As Integer = My.Resources.seemls4.Width
Dim intHeight As Integer = My.Resources.seemls4.Height
Dim intOffSetX As Integer = 150
Dim intOffSetY As Integer = 150
This means that means this code:
Code:
pts(0) = New Point(150, 150)
pts(1) = New Point(450, 150)
pts(2) = New Point(450, 450)
pts(3) = New Point(150, 450)
..can probably be replaced with this code:
Code:
pts(0) = New Point(intOffSetX, intOffSetY)
pts(1) = New Point(intOffSetX + intWidth, intOffSetY)
pts(2) = New Point(intOffSetX + intWidth, intOffSetY + intHeight)
pts(3) = New Point(intOffSetX, intOffSetY + intHeight)
..and not only does this cut down on some other magic numbers,
but the graphics offsetting can be variable adjusted at runtime.

I still like the "visual cue-ing" provided by the type of grab handles used in the vbHelper examples but it should be no problem to add them.

Thanks passel for some unique DrawImage warping 3 pt to 4 pt conversion code,
(of which I don't believe any other examples exist anywhere on the internet).

Hopefully your work for the next few months won't entirely keep you from posting on the forum.
You are one of the forum's "treasures".

Last edited by surfR2911; 10-29-2012 at 09:39 AM.
Reply With Quote
  #4  
Old 10-29-2012, 01:51 PM
passel's Avatar
passelImage warping using custom per pixel interpolation - needs performance tuning passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

dsG.DrawImage(srcBmp, ppnts, New Rectangle(CInt(sx), 0, 1, CInt(rx)), GraphicsUnit.Pixel)

rx is not a good number to use there. rx is the largest change in X (rangeX) of the "Top" line, or the "Bottom" line.
The 300 that was there was the height of the source bitmap, so CInt(rx) should be replaced with intHeight.

I believe that the artifacts you show are worse for the use of rx. But, there are artifacts for sure easily enough, which is why I mentioned that currently it is only taking X ranges into consideration. To better avoid artifacts, both X and Y and the position of the points relative to one another would have to be considered, and then the direction of the "blits" would be adjusted to give the best results.
Right now it is only "blitting" lines vertically (possibly slanted) from points along the Top X axis to points along the Bottom X axis.
When the X deltas are shorter than the Y deltas, it would probably make sense to switch to blitting "horizontal" lines along the Y axis instead.
Also, as the angle changes the parallelogram should be "rotating", which means the Y value should be adjusted slightly depending on the slope.

A quick patch which improves things, but is not the total solution, since it still doesn't switch to using horizontal when that would work better, is to offset the Y value depending on slope. There should still probably be a yOff = 0 zone for when the slope is mostly vertical, but this clears up a lot of the artifacts.
Code:
'The loop in updatedrawing sub.
    ss = 2
    For X = 0 To rx Step ss
      ppnts(0).X = CInt(ssx)
      ppnts(0).Y = CInt(sy)

      If (ppnts(2).X - ppnts(0).X) > (ppnts(2).Y - ppnts(0).Y) Then 'Compensate Y for left leaning shallow angles
        yOff = -2
      ElseIf ppnts(0).X - ppnts(2).X > (ppnts(2).Y - ppnts(0).Y) Then 'Compensate Y for right leaning shallow angles
        yOff = 2
      ElseIf (ppnts(1).X < ppnts(2).X) Then                           'left leaning, not shallow
        yOff = -1
      Else                                                            'right leaning, not shallow
        yOff = 1
      End If

      ppnts(1).X = CInt(ssx + ss + 1)
      ppnts(1).Y = CInt(sy + yOff)

      ppnts(2).X = CInt(eex + ss + 1)
      ppnts(2).Y = CInt(ey + yOff)

      dsG.DrawImage(srcBmp, ppnts, New Rectangle(CInt(sx), 0, 1, intHeight), GraphicsUnit.Pixel)

      ssx = ssx + sdx * ss
      eex = eex + eDx * ss

      sx = sx + dx * ss
      sy = sy + sdy * ss
      ey = ey + eDy * ss
    Next
    PictureBox1.Refresh()
They closed the facility about an hour ago because of the winds and rains associated with "Sandy", so I should've been out of here already, so I guess I'm heading home.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #5  
Old 10-30-2012, 04:14 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default DI4Warp and DI4WarpB

Quote:
Originally Posted by passel
rx is not a good number to use there. rx is the largest change in X (rangeX) of the "Top" line, or the "Bottom" line.
The 300 that was there was the height of the source bitmap, so CInt(rx) should be replaced with intHeight.
Actually when I use intHeight it seems to cut the image in half,
so I tried intHeight * 2 and it cut it to 25%
so I tried intHeight /2 and for some strange reason this seems to
warp the image at full height - don't really understand why though?

Quote:
Originally Posted by passel (excerpted for brevity)
I believe that the artifacts you show are worse for the use of rx..to better avoid artifacts..adjusted to give the best results..switch to blitting "horizontal" lines along the Y axis instead..as the angle changes the parallelogram should be "rotating", which means the Y value should be adjusted slightly depending on the slope.
I guess this makes sense.

I had already converted your "updatedrawing()" into a sub that feeds the
points in directly:
Code:
Private Sub DI4Warp(ByVal x1 As Integer, ByVal y1 As Integer, ByVal x2 As Integer, ByVal y2 As Integer, _
                    ByVal x3 As Integer, ByVal y3 As Integer, ByVal x4 As Integer, ByVal y4 As Integer)
The new version (with the patch) is a sub named "DI4WarpB"
The patched version seems to work better but I'm still getting artifacts.
I'll post the latest version with screenshots below.

Maybe there needs to be some kind of "cross fill overlay".
Potentially using painter algorithm ordering, rendering the "filler" for any potential gaps first,
(possibly rotated to the right angle to produce the optimal cross fill), then
the image warped for the final right angle overlaid on top with (hopefully)
an gaps "pre-filled" with the lower layer of drawing.

Quote:
Originally Posted by passel
They closed the facility about an hour ago because of the winds and rains associated with "Sandy", so I should've been out of here already, so I guess I'm heading home.
Anyway, thanks for the patch and you should find a place to ride out the storm.

I heard its going to be a slow moving one..that there's going to be lots of rain (potential flooding)
in addition to the high winds, so take care (and hopefully your home isn't in one of those areas that lost power).

Quote:
edit1:
I also posted the working code for doing 3D texturemapping using a texturebrush fill
attached to post #63 of the Viewer thread. Here's the screenshot of that from earlier in post #48.

I know you can't do warping of a texturebrush but maybe there is a way
to calculate the angle of the cube edges (slope?),
so that some kind of matrix rotational transform could be done
to align the texturebrush fill parallel with the cube face it is applied to.
(the points for the FillPolygon could easily be converted to a graphicspath for clipping purposes also).

This could be the "backup" in case the blit-gapping and/or moire issues aren't able to be resolved fully.
Attached Images
File Type: jpg screenshop_3D_cube_with_DrawImage_4_point_warp_texturemapping.JPG (16.7 KB, 19 views)
Attached Files
File Type: zip _3DRotatingCube_w-texturemapping.zip (1.09 MB, 37 views)

Last edited by surfR2911; 10-30-2012 at 04:50 AM.
Reply With Quote
  #6  
Old 10-30-2012, 09:44 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Quote:
Originally Posted by surfR2911 View Post
The VB.Net version is slower than the C#.Net version so I decided to use
boops boops' FastPix GetPixel/SetPixel Lockbits wrapper class to speed things up but
(you guessed it) the FastPix code doesn't work.
Thank you for trying FastPix. I did try to make it idiot proof, but apparently I failed in your case. Joking aside, you are correct in understanding that it is for use with 32-bit bitmaps. An exception stating that is thrown when you feed it a 24-bit bitmap such as the Mona Lisa. In fact it's easy to convert an image to a 32-bit bitmap like this:
Code:
Dim bmp As New Bitmap(image)
'e.g.
Dim bmp As New Bitmap(My.Resources.005)
Note that the bitmap constructor with a filename argument, doesn't change the pixel format, nor does casting from an image with CType etc.

The reason for placing the 32 bit restriction on FastPix was to keep it simple. It also supports image processing as an Integer array, which is much faster than working with bytes for certain kinds of work. Deforming a quadrilateral is a good example where the FastPix integer processing is possible, because you don't need to do anything with the colour bytes. If you want faster processing of 24 bit images without changing the pixel format, you can find countless examples on the web.

I downloaded the ImageWarper code and made a few changes to get the fast warping working using an integer array. I can post the changed form code if you are still interest in that.

About the GraphicsPath Warp. Msdn (if I understand it correctly) states that the points used to warp the path must form a parallelogram. Surprisingly, this turns out not to be true when you specify all four corners of the warp polygon. I've attached a demo below which just deforms an ellipse path. You can drag on all four corners of the quadrilateral to any position, including self-intersecting shapes. Choose either bilinear or perspective mode: both produce some rather interesting effects. It works well with graphic texts too (use GraphicsPath.AddString). What a pity it doesn't work with images.

Here's a pic:
DeformEllipse.png

PerspectiveDeformEllipse.zip

Last edited by boops boops; 10-30-2012 at 10:10 PM.
Reply With Quote
  #7  
Old 10-31-2012, 07:06 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default The creater of FastPix posts!

Quote:
Originally Posted by boops boops
I downloaded the ImageWarper code and made a few changes to get the fast warping working using an integer array.
I can post the changed form code if you are still interest in that.
Yes please..I'm definitely interested.

Did you see the fuzzy lines thread?
I brought up the FastPix code in post#14 and successfully integrated it into some of the latter attachments of that thread.
It makes a great way to do per pixel alpha masking!

In this bobpowell site Lockbits page it has code for using lockbits with very low bits per pixel formats.

Was that your intention with the ConvertFormat sub inside FastPix..that it should handle all the way down to 1bpp images?

Quote:
Originally Posted by boops boops
Choose either bilinear or perspective mode: both produce some rather interesting effects.
But not always the desired warping effects..and Microsoft designed it in such a way that there are no parameters to adjust things or make other choices (like the internal flattening of 2.2 it chooses by default (according to the article I cited above) --or what if you wanted to use "Drawing2D.WarpMode.Affine" instead of perspective/bilinear).

Maybe the Microsoft .Net framework programmers never though it would be necessary to have
the system.drawing namespace do different types of map projections like Gnomonic and Craig retroazimuthal.

I'm hoping that by extending the System.Drawing.Drawing2D namespace to support Point3D in such a way
that platonic solids that could be drawn in VB6 could be drawn in VB.Net as well.

There should be an in-built way to use the .Net Warp method to do a mesh deformation warp (similar to the ImageWarper attachment I posted),
which would just let you designate the image as well as the array overlay of mesh warp points...maybe with a scale and offset and have it (as a function) just return the warped image.

Ultimately, though, I'd want to also have a way to do custom interpolations,
not just deal with a limited set of default InterpolationMode enumerations.

Quote:
Originally Posted by boops boops
It works well with graphic texts too (use GraphicsPath.AddString).
However if you want each letter to be warped in a different direction of by a different amount
you basically have to isolate each individual letter as a sub-path.
Pre-flattening can also affect the output.

Quote:
Originally Posted by boops boops

What a pity it doesn't work with images.
Yes, a great pity.

It should be noted that warping and "liquifying" an image was an issue way back in the old VB Classic days as well.

Does anyone remember this old "Warp/Liquify an image" thread?
It cited two posts with working attachments for distorting an image.
1.) The rpgnewbie "trapezoidal stretchblt" post
2.) The passel "gather" demo post which created skewing by adjusting lines of pixels

I looked at your attachment.
It had no .sln file and the project files seemed to be damaged or corrupted (see screenshot).
I wish all the time that VB.Net's IDE was as robust as VB6..it's very annoying how "difficult" it can be sometimes!
Like putting these couple of lines before the Form Class lines
Code:
Public Class Something

End Class
..suddenly causes a call stack violation when trying to use the "View Designer" for a form, just because the form class code isn't first.
So, anyway, I created a new VB.Net Express 2010 project/solution and imported the form files into it
to make the IDE happy..then was able to play around with it (the PDE_recreated project is attached below).

The way the perspective warping seems to "flip" the ellipse had me thinking:
"if only it could have a little curl as it flips".

I've also attached a screenshot of the "butterfly" the perspective warping can produce by dragging the upper right drag handle down and to the left.

Note: The LinearGradientBrush coloration of the fillpath basically stops being a gradient in this configuration
and minor positioning changes to this upper right handle corner drag handle produce either solid red, solid blue, or purplish-mixed solid color

Last edited by surfR2911; 10-31-2012 at 08:46 AM.
Reply With Quote
  #8  
Old 10-31-2012, 05:14 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Quote:
Originally Posted by surfR2911 View Post
Yes please..I'm definitely interested.
OK. I'm attaching new code for Form1. The main changes are:

1. I changed the name of img to bmp, because it's going to be a bitmap.
2. bmp is converted to 32bit in the form Load sub, using the bitmap constructor.
3. The main change is to the OffsetFilterFastPix sub. It now uses the FastPix PixelArray (integers) instead of the much slower GetPixel and SetPixel.
4. To make things clearer, I got rid of a lot of unnecessary stuff: the dead code, the Imports statements, the DoubleBufferedPanel class, zeroizing the G array in the Load sub and a few other odds and ends.
You'll see that the fast warping now works practically instantly instead of after a pause. The program is still far from ideal, because it's necessary to reinstatiate the FastPix object in every Paint call. Locking and Unlocking a bitmap has an overhead, so it would be much better to just do it once in the Load sub. But that would mean a totally different design to the rest of the code.

Quote:
Did you see the fuzzy lines thread?
I brought up the FastPix code in post#14 and successfully integrated it into some of the latter attachments of that thread.
It makes a great way to do per pixel alpha masking!
Maybe someone should have mentioned SmoothingMode.HighQuality right from the start.

Quote:
In this bobpowell site Lockbits page it has code for using lockbits with very low bits per pixel formats.

Was that your intention with the ConvertFormat sub inside FastPix..that it should handle all the way down to 1bpp images?
The ConvertFormat sub only works for images you can draw with Graphics.DrawImage. I don't know much about low-bits pixel formats, but many of them can't be drawn with DrawImage. For myself, I always use the New Bitmap method, but then I never deal with anything except 24bpp (photos) and 32bpp (drawings).

Quote:
But not always the desired warping effects..and Microsoft designed it in such a way that there are no parameters to adjust things or make other choices (like the internal flattening of 2.2 it chooses by default (according to the article I cited above) --or what if you wanted to use "Drawing2D.WarpMode.Affine" instead of perspective/bilinear).
Maybe the Microsoft .Net framework programmers never though it would be necessary to have
the system.drawing namespace do different types of map projections like Gnomonic and Craig retroazimuthal.

I'm hoping that by extending the System.Drawing.Drawing2D namespace to support Point3D in such a way
that platonic solids that could be drawn in VB6 could be drawn in VB.Net as well.

There should be an in-built way to use the .Net Warp method to do a mesh deformation warp (similar to the ImageWarper attachment I posted),
which would just let you designate the image as well as the array overlay of mesh warp points...maybe with a scale and offset and have it (as a function) just return the warped image.

Ultimately, though, I'd want to also have a way to do custom interpolations,
not just deal with a limited set of default InterpolationMode enumerations.
You can't expect everything to be built into the .net framework for you. Besides, you can manipulate the PathPoints data in a GraphicsPath whatever way you like, so in theory you could do any of those things for yourself -- assuming you have the necessary mathematics.
Quote:
However if you want each letter to be warped in a different direction of by a different amount
you basically have to isolate each individual letter as a sub-path.
Pre-flattening can also affect the output.
There are some interesting articles on text warping on the web. Maybe that's another topic for the moment.
Quote:
It should be noted that warping and "liquifying" an image was an issue way back in the old VB Classic days as well.

Does anyone remember this old "Warp/Liquify an image" thread?
It cited two posts with working attachments for distorting an image.
1.) The rpgnewbie "trapezoidal stretchblt" post
2.) The passel "gather" demo post which created skewing by adjusting lines of pixels
The VB Classic days passed me by. I'm not sure whether to be glad or sad about that.

Quote:
I looked at your attachment.
It had no .sln file and the project files seemed to be damaged or corrupted (see screenshot).
I wish all the time that VB.Net's IDE was as robust as VB6..it's very annoying how "difficult" it can be sometimes!
Like putting these couple of lines before the Form Class lines
Code:
Public Class Something

End Class
..suddenly causes a call stack violation when trying to use the "View Designer" for a form, just because the form class code isn't first.
So, anyway, I created a new VB.Net Express 2010 project/solution and imported the form files into it
to make the IDE happy..then was able to play around with it (the PDE_recreated project is attached below).

The way the perspective warping seems to "flip" the ellipse had me thinking:
"if only it could have a little curl as it flips".

I've also attached a screenshot of the "butterfly" the perspective warping can produce by dragging the upper right drag handle down and to the left.

Note: The LinearGradientBrush coloration of the fillpath basically stops being a gradient in this configuration
and minor positioning changes to this upper right handle corner drag handle produce either solid red, solid blue, or purplish-mixed solid color
Sorry, not sure what happened about the zipped project. All the code is in the main form anyway. The weird results show what happens when you scramble the quadrilateral so much it flips into an unknown dimension. If you don't like it, don't go there.
BB
Attached Files
File Type: zip Form1_mod.zip (723.7 KB, 23 views)

Last edited by boops boops; 10-31-2012 at 05:33 PM.
Reply With Quote
  #9  
Old 11-01-2012, 09:44 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default

Quote:
Originally Posted by boops boops
OK. I'm attaching new code for Form1.
I download and unzipped you attachment but all it had in it was one file: "Form1_mod.resx".

Resx files usually just save images connected with a form.
The code for a form would probably be in something like a Form1.vb file.

So if you had modified the original code for the Form1.vb file,
shouldn't there be a "Form1_mod.vb" file accompanying the resx file in the zip?

I looked at the resx file in notepad and using SharpDevelop (see attached screenshot),
and there is no VB.Net code inside the resx file, just "pb1.Image" (which is the Mona Lisa graphic).

So I guess I'm still interested in seeing how exactly you implemented the changes 1-4 you cited in your last post.
Quote:
Originally Posted by =boops boops
The program is still far from ideal, because it's necessary to re-instantiate the FastPix object in every Paint call.
One of the things I was thinking -- could a Parallel.For be substituted for the For..Then looping when using the FastPix code?
The MSDN TPL (Task Parallel Library) docs have a "Data Parallelism" page that might be relevant.
Quote:
Originally Posted by boops boops

The weird results show what happens when you scramble the quadrilateral so much it flips into an unknown dimension. If you don't like it, don't go there
Actually it's very interesting - the way the LinearGradientBrush "collapses" when used in this way.
Maybe there is some clever animation effect buried in that behavior.

There are always tons of little "gotchas" that you never learn about by reading the MSDN.
The MSDN is only oriented to what something is "designed" to do (by the .Net Framework development team),
and not what it actually does when "pushed" to its limits by advanced expert programmers such as yourself.
Quote:
Originally Posted by boops boops

..so in theory you could do any of those things for yourself -- assuming you have the necessary mathematics
Yes, that's always the rub.

If I knew (could calculate) the points I could crank out every platonic solid imaginable,
but I skipped out of geometry/trig classes a lot
because the high school I went to had a computer lab and I wanted to teach myself APL.

Quote:
Originally Posted by boops boops
The VB Classic days passed me by.
Unfortunately not many languages have passed me by..I've had to deal with just about every
language imaginable over the years: Assembly (Masm/Nasm), COBOL, FORTRAN, Intercal,
RPG, Smalltalk, Pascal, Java, Php, Lisp, Prolog, RoR, C++ and a whole bunch of C variants..

The only programming languages that were formally taught when I was going through high school
were Logo and ArtSpeak - everything else I've had to learn on my own along the way.
Quote:
Originally Posted by boops boops
You can't expect everything to be built into the .net framework for you.
Maybe not, but for me the learning curve for VB.Net is at least twice as steep as VB6,
(partly because I'm still trying to unlearn the VB classic way of coding),
and it certainly doesn't do twice as as much as I used to be able to do under VB6.

Thanks for posting though.

Last edited by surfR2911; 11-01-2012 at 10:16 AM.
Reply With Quote
  #10  
Old 11-01-2012, 01:04 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Aargh! I plead exhaustion. It takes a lot of work dealing with all those questions. And then there's life etc. Here's the .vb file.
BB
Attached Files
File Type: vb Form1_mod.vb (5.4 KB, 8 views)
Reply With Quote
  #11  
Old 11-01-2012, 01:49 PM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

As to your other questions:
Quote:
Originally Posted by surfR2911 View Post
One of the things I was thinking -- could a Parallel.For be substituted for the For..Then looping when using the FastPix code?
I very much doubt it. The amount of processing in the For loop is practically trivial: a few integer operations and comparisons, plus some array referencing which probably accounts for the lion's share. I should think the overhead of organizing the parallelism would vastly outweigh that.

Quote:
The MSDN TPL (Task Parallel Library) docs have a "Data Parallelism" page that might be relevant.
Actually it's very interesting - the way the LinearGradientBrush "collapses" when used in this way.
Maybe there is some clever animation effect buried in that behavior.
I think I can guess what's happening. The framework doesn't waste time checking for a "valid" perspective (fortunately, because that would be boring) with the result that at a certain point the ellipse transforms suddenly into a different conic section, the hyperbola (which you call the "butterfly" shape). In theory the asymptotes tail off to infinity. In practice the end points will be swanning around in some far flung corner of Single.MinValue to Single.MaxValue. The gradient is stretched to "fill" the hyperbola, so all you see on the screen is a tiny segment somewhere along the gradient, effectively a solid colour. When you move the quadrilateral, the view shifts to a different bit of the gradient. Or something like that...
Quote:
There are always tons of little "gotchas" that you never learn about by reading the MSDN.
The MSDN is only oriented to what something is "designed" to do (by the .Net Framework development team),
and not what it actually does when "pushed" to its limits by advanced expert programmers such as yourself.
Yes, that's always the rub.
I suppose you could call the ability of GraphicsPath to do real perspective warps an "undocumented feature". There's no guarantee that it won't crash (actually it does in some situations, but they are easy to bypass) or that the ability will be retained in a new release of the Framework. Still, I doubt that they'll change it now.

Quote:
If I knew (could calculate) the points I could crank out every platonic solid imaginable,
but I skipped out of geometry/trig classes a lot
because the high school I went to had a computer lab and I wanted to teach myself APL.
There are only five Platonic solids so it shouldn't be too hard.

BB
Reply With Quote
  #12  
Old 11-01-2012, 03:12 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default rev1

Quote:
Originally Posted by boops boops
Here's the .vb file.
We'll there's good news and bad news.

The good news is that I was able to cleanly substitute the Form1_mod file in for Form1 and the IDE reported no errors.

It's also good news that when you select the FastWarp option something actually happens how (i.e. the FastPix code is effecting the image now).
Quote:
You'll see that the fast warping now works practically instantly instead of after a pause.
Yes, it is real time without any noticeable delay.

That's all good news (definitely) --so progress is being made.

The bad news is the difference between what is produced by SlowWarp versus what is produced by FastWarp.
I'll attach the different screenshots so you can see the difference.

Of course they should be basically the same (with only the rendering being faster) but the FastWarp produces
a rather different effect -- I don't know what to call it - smearing?

I'll bundle up the revised code package - maybe I did some wrong in the merging..

Quote:
Edit1: I'm sure passel is still trying to work out the exact 4 pt DrawImage code that doesn't present artifacts
when used for texturemapping but I had a thought.

What if we just used DrawImage as intended with 3 pts but consider the cube face as
two sets of vertices which form two triangles.
Then adjust the images by slicing them into triangles to match this triangle form of texturemapping.
What would happen then?
Would those artifacts disappear.

As it turns out the triangularly sliced images don't show the artifacts when using 3 pt DrawImage code.
Of course which triangle point mates to which vertex point - well that's another issue, but I'll attach my little experiment.
Attached Images
File Type: jpg screenshot_imagewaper_rev1_slow_warp.JPG (74.3 KB, 12 views)
File Type: jpg screenshot_imagewaper_rev1_fast_warp.JPG (73.0 KB, 17 views)
File Type: jpg screenshot_texturemapping_3D_cube_with_3pt_images.JPG (35.9 KB, 22 views)
Attached Files
File Type: zip _Imagewarper_rev1.zip (1.39 MB, 20 views)
File Type: zip texturemapping_3D_cube_with_3pt_images.zip (1.42 MB, 12 views)

Last edited by surfR2911; 11-01-2012 at 03:35 PM.
Reply With Quote
  #13  
Old 11-02-2012, 09:21 PM
passel's Avatar
passelImage warping using custom per pixel interpolation - needs performance tuning passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Actually, I haven't looked at the code any further. I have more important things to get accomplished.
I haven't looked at the code you've done, but if I had to hazard a guess, I would say you're modifying your source image, so you're warping the warp, which will eventually end up just be a smudgy pool of pixels.
You have to leave the original source alone and just warp it, based on the control lines, to the destination.
If you put all the warping lines back to the original grid, you should end up with the original picture, and you can't do that if you're modifying the original.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #14  
Old 11-04-2012, 03:51 AM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default smudgey pool of pixels and almost a pure VB.net raytracer

Quote:
Originally Posted by passel
I haven't looked at the code you've done, but if I had to hazard a guess, I would say you're modifying your source image, so you're warping the warp, which will eventually end up just be a smudgy pool of pixels.
I assume by the use of "you're" that you are addressing boops boops, who was the one that provided the code to get FastPix working with the ImageWarper project.

Hopefully boops boops will eventually be posting again to provide further guidance of why this is happening..(probably are a lot of people in Sandy Super Storm recovery mode).

In the meantime I've been working on a Perlin Noise wrapper class.

Perlin noise doesn't have the directionality of other types of textures so I figure it would be a good candidate for 3D texture wrapping even if no one comes up with a way to align texturebrushing with the angle of the cube faces.

Towards that end I have been playing around with the only working VB.Net example in existence from this thread.

The code (translated from C# by me) uses Parallel For (in addition to Marshal Copying the Lockbits):
Code:
    Dim bmp As New Bitmap(ImageSize, ImageSize)
    System.Threading.Tasks.Parallel.[For](0, ImageSize - 1, New Action(Of Integer)(AddressOf CalcRow))
    Dim data As BitmapData = bmp.LockBits(New Rectangle(0, 0, ImageSize, ImageSize), _
         System.Drawing.Imaging.ImageLockMode.[WriteOnly], System.Drawing.Imaging.PixelFormat.Format32bppArgb)
    System.Runtime.InteropServices.Marshal.Copy(bytes, 0, data.Scan0, data.Stride * data.Height)
    bmp.UnlockBits(data)
Do you remember a while back I mention Microsoft's VB.Net ray tracing samples in this post.
I could never get them to run without errors and after a while I finally found out why.

Microsoft cheated!
The VB.Net ray tracing sample is not entirely done in VB.Net.
It uses something called ParallelExtensionExtras done in C#.Net.

The VB.Net solution is set up in a way that merely referencing the C# dll from the VB solution doesn't clear the errors related to ObjectPools:
Code:
Private _freeBuffers As ObjectPool(Of Int32())
So I a couple of days ago I sent the code over to my friend that has a full copy of VS.Net 2010 and he was able to get it to compile without errors.

If only the ObjectPool code could be fully converted to VB.Net then we could have a pure VB.net ray tracer with 3D texturemapping!

I attach the mouthwatering screenshot my friend sent me.
Note for passel: This is NOT WPF!
This is VB.Net WinForms with code classes to extend the .Net Framework like:
Ray/RayTrace (with functions like "Shade" and "GetReflectionColor")
Sphere
Scene/SceneObject
Vector (directional and positional)
Surface/Surfaces
Plane/Camera/Lighting

I don't know if I can ever get that C#.Net ParallelExtensionsExtras code converted to VB.Net
It probably uses unsafe pointers for speed optimization.
Maybe I can extract/convert of the C#.Net ObjectPool code to get the VB.Net sample working or find some other ObjectPooling code written in VB.Net and do a mash-up (didn't find any such code with some preliminary google searching however).
Attached Images
File Type: jpg screenshot_the_microsoft_vb_dot_net_ray_tracer_sample.JPG (191.4 KB, 13 views)

Last edited by surfR2911; 11-04-2012 at 04:13 AM.
Reply With Quote
  #15  
Old 11-04-2012, 04:50 AM
boops boops's Avatar
boops boops boops boops is offline
Centurion
 
Join Date: Dec 2006
Location: Holland and France
Posts: 146
Default

Hi Surf,

I've been keeping an eye on the thread but replying always takes a lot of time. I agree with Passel about the cause of the smearing and it's easy to fix. I was hoping you'd try it yourself. This works:

1. define an array at form level to hold a "safety" copy of the pixels:
Code:
Dim sourcePixels() As Integer
2. Fill it when you read the image, presently in the Load sub:
Code:
Using fp As New FastPix(bmp)
      sourcePixels = fp.PixelArray
End Using
3. In the OffsetFilterFastPix sub, read from the sourcePixels array instead of the pixels array:
Code:
pixels(x + y * nWidth) = sourcePixels((x + xOffset) + (y + yOffset) * nWidth)
I'll look at the rest of your message later.

BB
Reply With Quote
  #16  
Old 11-04-2012, 01:01 PM
surfR2911 surfR2911 is offline
Contributor
 
Join Date: Oct 2009
Posts: 719
Default The five line anti-smearing FastPix warp fix

Thanks for posting the fix.
Now the SlowWarp and FastWarp produce identical results so
my translated OffsetFilterSlow sub is basically worthless,
but as Martha Stewart is fond of saying "It's a good thing".

The next evolution of the Imagewarper code will be to try to get it into shape to
possibly adapt to 3D texturemapping.

I've played around with altering the grid of lines so that there are only four lines which cross at the four corners of the image,
so the four mesh warp adjust points represent (and align with) the corners that define the picture's outer "rect".

Then the lines are no longer needed and the warp points can be changed to coincide with the four vertices of each cube face.

I'm not sure if the warping subsequently produced can follow the angle defined by the cube's edges though..especially as they rotate (and reverse) in 3D space.

However, unless passel comes up with some ideas for revising the 4 pt DrawImage warp code to cover the gapping shown in the screenshot of post #5,
I'm inclined to say the thread's initial question on performance tweaking the Imagewarper code is Resolved.
Thanks to all who contributed in this thread.

Quote:
edit1:
In regard to the Perlin Noise wrapper class, mentioned in post #14 of this thread,
I just posted the preliminary PNoiz class working attachment to post #65 of the Viewer thread.

Last edited by surfR2911; 11-04-2012 at 02:11 PM.
Reply With Quote
Reply

Tags
blinear interpolation, warping


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
 
Image warping using custom per pixel interpolation - needs performance tuning
Image warping using custom per pixel interpolation - needs performance tuning
 
-->