Page 1 of 1

Bug in polynomial distortion

Posted: 2019-09-10T05:06:31-07:00
by reichemi

I believe I discovered a bug in ImageMagick's polynomial distort function. Here is what I do:

Code: Select all

convert input.png -matte -virtual-pixel transparent -distort Polynomial "3   0,0 893,1523   826,0 1218,1523   1653,0 1543,1523   2480,0 1866,1523   0,582 848,1751   826,582 1200,1751   1653,582 1520,1751   2480,582 1811,1751   0,1164 793,1917   826,1164 1152,1917   1653,1164 1474,1917   2480,1164 1765,1917   0,1747 744,2059   826,1747 1076,2059   1653,1747 1425,2059   2480,1747 1730,2059" output.png

But the output contains two times the input image, one with the correct coordinates (on the bottom) and the other does not (on the top). If I somehow change the points then it happens that the wrong image on the top disappears.

What goes wrong here?

Code: Select all

convert -v

Version: ImageMagick 6.9.10-62 Q16 x86 2019-08-24
Copyright: Copyright (C) 1999-2015 ImageMagick Studio LLC
Visual C++: 180040629
Features: Cipher DPC Modules OpenCL OpenMP(2.0)
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg lcms lqr lzma openexr pangocairo png ps raw rsvg tiff webp xml zlib
I'm using it on Windows 10.


Re: Bug in polynomial distortion

Posted: 2019-09-10T06:11:57-07:00
by snibgo
Insert "-verbose" before the distort. The text output is:

Code: Select all

Polynomial (order 3, terms 10), FX Equivelent
  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;
       xx = +3340.671647 +4.713454*ii -10.397771*jj -0.000084*ii*jj
          -0.001877*ii*ii +0.005396*jj*jj +0.000000*ii*ii*ii +0.000001*ii*ii*jj
          -0.000000*ii*jj*jj -0.000001*jj*jj*jj;
       yy = +7076.604911 +0.000000*ii -13.261499*jj -0.000000*ii*jj
          +0.000000*ii*ii +0.007001*jj*jj -0.000000*ii*ii*ii -0.000000*ii*ii*jj
          +0.000000*ii*jj*jj -0.000001*jj*jj*jj;
       p{ xx-page.x-.5, yy-page.y-.5 }' \
IwKYVMX.png=>x.png PNG 2480x2059 2480x2059+0+0 8-bit Gray 54584B 22.016u 0:05.092
We see this includes terms up to the cube, though the last few terms are close to zero.

These terms, beyond order 1, mean that each input pixel may map to more than one output pixel. Hence your double image. Use order 1 to get the result you expect.

EDIT to add: This is a typical problem with polynomials. Your over-specified coordinates are not 100% accurate (in general, they cannot be) but the calculated polynomial passes exactly through those coordinates, with weird results elsewhere.

A spline distortion would give better results. But this is harder to implement.

Re: Bug in polynomial distortion

Posted: 2019-09-10T22:43:05-07:00
by reichemi
Thank you snibgo for your answer!

I tried it with order 1, 1.5 and 2, but they all do not create the expected output. Order 1/1.5 creates no "curved" edges, and order 2 has the same "bug" as order 3.

So you do not specify this as a bug? I named it like this, because I expected that the input image will be transformed so that it matches the given coordinates the best it could get (it will not match them perfectly, like you said). But of course it should not produce a "phantom" image somewhere else (the wrong image on the top) that completely does not belong to the given coordinates.

As a workaround for me, I will probably cut out the image after the transformation. But nevertheless I thought it would be good if this could be "fixed" in ImageMagick directly.

kind regards,

Re: Bug in polynomial distortion

Posted: 2019-09-11T08:38:29-07:00
by snibgo
Is it a bug? I don't know. I can see it doesn't do what you want. But I don't know how to fix that, or even if it can be fixed within ImageMagick.

Where did the coordinates come from? As a workaround for this case, you can subtract 1523 from the output y-coordinates. Then insert 1523 blank rows after the distortion. Windows BAT syntax:

Code: Select all

set COORDS=0,0,893,0,^

%IM%convert ^
  IwKYVMX.png ^
  -matte -virtual-pixel transparent -distort Polynomial ^
  "3 %COORDS%" ^
  -repage +0+1523 ^
  -background None -layers Flatten ^

Re: Bug in polynomial distortion

Posted: 2019-09-11T23:04:14-07:00
by reichemi
Where did the coordinates come from?
The coordinates come from a graphical template that should be reproduced via ImageMagick.
As a workaround for this case, you can subtract 1523 from the output y-coordinates. Then insert 1523 blank rows after the distortion.
That is a great idea, I can also automate this by looking at the smallest X/Y coordinates and repage the image afterwards accordingly. Thanks for that hint :idea: :wink:

Re: Bug in polynomial distortion

Posted: 2019-09-12T08:46:07-07:00
by snibgo
Yes, you can do the same trick with x, though that isn't needed in this example.

For some sets of coordinates, a second unwanted copy might occur below or to the right of the wanted copy. You could find the maximum x and y output coords, and crop the result there.

In extreme cases, that won't work: a second image might occur within the bounding box of the required image.