Page 1 of 1

BilinearForward producing blank image in some cases

Posted: 2010-09-04T03:46:24-07:00
by niraj
For some odd reason, the BilinearForward distort is only working in some cases for me. Here's an example where it doesn't work:
out-interim.png wrote:Image
Command:

Code: Select all

convert "out-interim.png"
   -mattecolor none   -matte -virtual-pixel transparent
   -distort BilinearForward "0,0 241,29   400,0 165,41   400,31 166,52   0,31 241,39"
   -gravity NorthWest   -crop 242x53+0+0
   "out.png"
The result is a 242x53 blank image. Seems to be transparent black.

There is a warning in the distort usage docs about this happening in versions before 6.5.7. Not sure if it's related.

Using Windows 7 32-bit with ImageMagick-6.6.3-10-Q16-windows-dll, also saw the same thing with ImageMagick-6.6.2-0-Q16-windows-dll

Am I doing something wrong or is this a bug?

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-04T10:40:51-07:00
by fmw42
try adding +repage after your crop to remove the virtual canvas

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-04T21:08:28-07:00
by niraj
Tried it but it didn't work either. :(

Code: Select all

convert "out-interim.png"
   -mattecolor none   -matte -virtual-pixel transparent
   -distort BilinearForward "0,0 241,29   400,0 165,41   400,31 166,52   0,31 241,39"
   -gravity NorthWest   -crop 242x53+0+0
   +repage
   "out.png"

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-04T21:36:09-07:00
by fmw42
How are you specifying these coordinates? 0,0 241,29 400,0 165,41 400,31 166,52 0,31 241,39"

srcx,srxy dstx,dsty ....

It does not look like it! see http://www.imagemagick.org/Usage/distor ... rol_points

If so, then I think your destination coordinates are not what you expect or appropriate. Where are you getting the destination coordinates? Looks like you are mapping the source UL corner further to the right (241 destination) than the UR corner (165 desitination). Likewise the bottom coordinates. This cross over is probably messing you up.

What are you expecting for an output?

Try the example at http://www.imagemagick.org/Usage/distor ... ar_forward

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-05T01:38:12-07:00
by niraj
Interesting, I wasn't aware of that constraint. It works if I swap the L and R values so that UL maps to UL, etc.

What I was expecting to see was the source image horizonally flipped and then distorted. I assumed the distort operation would do that if I specified the coordinates with the L and R values swapped. Is there a good way to do that assuming the source and destination coordinates may be any quad?

Edit: Just noticed that this works with a perspective distort... of course perspective distort isn't what I want. But that makes me wonder if it's a bug or if I'm just using it wrong.

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-05T10:27:12-07:00
by fmw42
BilinearForward is a very special transformation that is not just one simple equation. A quadratic equation has to be solved in the middle of other equations. I am not sure if that is the issue, but possibly it is taking the wrong sign in this case. Your case was not anticipated. Anthony will have to look into this further when he gets time.

But why not just use -flip first and then bilinearforward with the appropriate order for the control points

Re: BilinearForward producing blank image in some cases

Posted: 2010-09-05T17:59:18-07:00
by anthony
To start with remove the final crop, it should be irrelevent to the problem and just may cover up details. You can include the crop directly in the distorting (and even use floating point offsets) using the distort viewport expert option


Now your input image has a virtual canvas! That is the actual image may not be where you are expecting it to be!

Code: Select all

  identify out-interim.png
out-interim.png PNG 401x74 1430x1734+0+42 8-bit DirectClass 616B 0.000u 0:00.000
This is caused by using -crop without a final +repage when the virtual canvas of the crop is not relevant.

Remember Distort is designed to preserve and work with virtual canvas images. As such it distorts the virtual canvas and not the actual image. That was done on purpose!

However adding a +repage before the distort does not seem to help in this case, though changing the final coordinate from 39 to 0 does make the resulting image at least partially visible!

Code: Select all

convert "out-interim.png" \
   -mattecolor none   -matte -virtual-pixel transparent \
   -distort BilinearForward "0,0 241,29   400,0 165,41   400,31 166,52   0,31 241,0" \
  show:
Second you have twisted the image so you are looking at its backside! It has been flipped in some way.

Bilinear Distortions were never really meant to be use in a situation where you get hour-glass or flipped images.

Basically the input image and coordinates just really do not make much sense. so you get a non-sense result.

I would like to repeat a previous question -- What generated this image and these coordinates?

--------------------------------------------------
Implementation Explanation
--------------------------------------------------


Lets have a look at flipped images to see what IM is doing...

Hour-glass like shapes are an intermediate form that will at least keep some of the image visible, even though they are not really 'sensible'. For example swapping the left coordinates of a rose image...

Code: Select all

convert rose:  -mattecolor blue -background dodgerblue  -virtual-pixel background \
   -distort BilinearForward "0,0 0,46   0,46 0,0    70,0 70,0   70,46 70,46" \
   rose_leftswap.png
Image

However forming an hourglass by swapping the two top coordinates makes the top half the hourglass 'disappear'

Code: Select all

convert rose:  -mattecolor blue -background dodgerblue  -virtual-pixel background \
   -distort BilinearForward "0,0 70,0   0,46 0,46    70,0 0,0   70,46 70,46" \
   rose_topswap.png
Image

If the bottom two coordinates were also then swapped, then the whole image disappears as the image becomes 'flipped over' from left to right.

The image does not disappear if all the coordinates were flipped top to bottom!

This I would regard as a bug But one that will need some work to resolve.

The reason for the different results is due to the need to solve a quadratic function. There are two valid ways to solving the quadratic Y first then substitute for X, or X first then substitute for Y, but only one is implemented. You can see what is implemented by turning on -verbose

Code: Select all

 convert rose:  -mattecolor blue -background dodgerblue  -virtual-pixel background \
   -verbose -distort BilinearForward "0,0 70,0   0,46 0,46    70,0 0,0   70,46 70,46" \
   +verbose null:

Code: Select all

BilinearForward Mapping Equations:
    i = -1.000000*x -1.521739*y +0.043478*x*y +70.000000;
    j = +0.000000*x +1.000000*y +0.000000*x*y +0.000000;
BilinearForward Distort, FX Equivelent:
  -fx 'ii=i+page.x-69.500000; jj=j+page.y+0.500000;
       bb=0.000000*ii -0.043478*jj -1.000000;
       rt=bb*bb -0.173913*(0.000000*ii+1.000000*jj);
       yy=( -bb + sqrt(rt) ) / 0.086957;
       xx=(ii +1.521739*yy)/(-1.000000 +0.043478*yy);
       (rt < 0 ) ? red : p{ xx-page.x-.5, yy-page.x-.5 }'
As you can see from the FX equivelent code currently we solve Y first, the substitute to solve for X. If we did it the other way, the the image would disappear on a one side top-bottom flip.

If we can determine when it is better to solve it one way, over the other way then we can fix this problem by solving for the appropriate case. Fred Weinhaus may be able to figure out when to do this, and how we can correct our implementation.

ASIDE: I would still like to get a proper bilinear distort of any-quad to any-quad sorted out, though I really just have no time for programming due to heavy work commitments.