WEIRD: convert -distort Affine producing black images

Post any defects you find in the released or beta versions of the ImageMagick software here. Include the ImageMagick version, OS, and any command-line required to reproduce the problem. Got a patch for a bug? Post it here.
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

WEIRD: convert -distort Affine producing black images

Post by tsanders »

I want to do a distortion with two controlpoints on a 2816x2112 pixel image.

Code: Select all

convert 001.jpg -distort Affine "369.5,1060.5 700,1100 2405.5,1077.5 2000,1100" 002.jpg
- image is all black :shock:

Code: Select all

convert 001.jpg -distort Affine "368.5,1060.5 700,1100 2405.5,1077.5 2000,1100" 002.jpg
- image is OK.

Please note that the only difference is a one pixel x-shift in the first control point. In a script doing a series of 25 conversions with different control points, always 1 to 5 resulting pictures are black!

The problem is on Ubuntu 12.04 with IM version 6.6.9-7 (distribution) but persists after upgrading to 6.8.0-7
On Windows there is no problem.

Any help is very much appreciated. Thanks.
Tom
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: WEIRD: convert -distort Affine producing black images

Post by fmw42 »

It may work with only two control points, but -distort Affine generally requires 3 control points. I am not sure why it works on one platform and not the other. See http://www.imagemagick.org/Usage/distorts/#affine

However, you can do a shift with 2 control points use -distort SRT. see http://www.imagemagick.org/Usage/distorts/#srt
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

Re: WEIRD: convert -distort Affine producing black images

Post by tsanders »

Thanks for your input. The Affine method should work with two control points. See http://www.imagemagick.org/Usage/distor ... rol_points.

I cannot see how to use SRT with two controlpoints. AFAIK rotation must always be there. This was my main reason to switch to Affine.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: WEIRD: convert -distort Affine producing black images

Post by fmw42 »

tsanders wrote:Thanks for your input. The Affine method should work with two control points. See http://www.imagemagick.org/Usage/distor ... rol_points.

I cannot see how to use SRT with two controlpoints. AFAIK rotation must always be there. This was my main reason to switch to Affine.

specify 0 for rotation and 1 for scale and the input coordinate and corresponding output coordinate for a shift, if that was what you were trying to do.

see
http://www.imagemagick.org/Usage/distor ... rol_points for affine shift
and
http://www.imagemagick.org/Usage/distorts/#srt

convert image -distort SRT "inx,iny 1 0 outx,outy" result

If you are trying to do something other than a shift, the please explain further and post a link to your image so we can test your commands.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: WEIRD: convert -distort Affine producing black images

Post by anthony »

How big is the input image? Also try using +distort. your control point may be pushing the image out of the input images viewport (what -distort uses).
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

Re: WEIRD: convert -distort Affine producing black images

Post by tsanders »

The thing I need is the second example in http://www.imagemagick.org/Usage/distor ... rol_points (aligning two points on two other points)
I am using the exact code as described in the example, resulting sometimes in black images, as described in my original post.

NEW RESULTS: If I add a third controlpoint to the -distort Affine (the shear factor), the problem is gone, but all images are sheared about -30 degrees, no matter what image coordinates I use for the third control point.

FAILED: using your SRT code only shifts the first control point, there is no required scaling and rotation to align the second point.

FAILED: using +distort does not solve the problem, it also does not produce the required effect.

As stated before: the formula in my original posting does exactly what I need, only sometimes it produces black images.

I have placed the image on our server. If anyone can give it a try reproducing the problem using the two formulas, I would appreciate feedback on the results. The image is a 1MB digital camera picture.
http://www.xyz-imaging.com/001.jpg
Please remember, the problem is only on Ubuntu (I am using 12.04), not on Windows. Did not try OSX.

Thanks for your help!
Tom
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

Re: WEIRD: convert -distort Affine producing black images

Post by tsanders »

NEW RESULTS:
using literally the same code (including the koala.png imagefile) from the second example in http://www.imagemagick.org/Usage/distor ... rol_points also produces a black image.

The first example works OK...
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: WEIRD: convert -distort Affine producing black images

Post by magick »

This command:
  • convert koala.gif -virtual-pixel white \
    -distort Affine '30,11 15,15 48,29 60,15' koala_two_point.png
returns expected results for us. We're using ImageMagick 6.8.0-8, the latest release.
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

Re: WEIRD: convert -distort Affine producing black images

Post by tsanders »

Are you using Ubuntu? If so, what version?
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: WEIRD: convert -distort Affine producing black images

Post by anthony »

Okay I tried the two original command, with the provided image, and yes I get black for the first and correct for the second.

I am not certain why as only one source coordinate was changed by one pixel. It should not have that big an effect.

Adding verbose output...

Bad one...

Code: Select all

convert 001.jpg -verbose -distort Affine "369.5,1060.5 700,1100 2405.5,1077.5 2000,1100" +verbose 002.jpg
Affine Projection:
  -distort AffineProjection \
      '0.638462,-0.005331,0.005331,0.638462,458.434660,424.880457'
Affine Distort, FX Equivelent:
  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;
       xx=+1.566154*ii -0.013077*jj -712.423077;
       yy=+0.013077*ii +1.566154*jj -671.423077;
       p{ xx-page.x-.5, yy-page.y-.5 }' \
Good one...

Code: Select all

convert 001.jpg -verbose -distort Affine "368.5,1060.5 700,1100 2405.5,1077.5 2000,1100" +verbose 002.jpg
Affine Projection:
  -distort AffineProjection \
      '0.638149,-0.005326,0.005326,0.638149,459.194155,425.205547'
Affine Distort, FX Equivelent:
  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;
       xx=+1.566923*ii -0.013077*jj -713.961538;
       yy=+0.013077*ii +1.566923*jj -672.269231;
       p{ xx-page.x-.5, yy-page.y-.5 }' \
The numbers don't seem that different. At least not enough to cause an image to be 'all black'. Something is definitely odd.

Here is a faster 'test' case, for a single pixel input image...

Code: Select all

convert xc: -distort Affine "369.5,1060.5 700,1100 2405.5,1077.5 2000,1100" txt:
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (  0,  0,  0)  #000000  black
Any change to input coordinates, even the slightest seems to generate a good (non-black) image....

Code: Select all

convert xc: -distort Affine "369.500001,1060.5 700,1100 2405.5,1077.5 2000,1100" txt:
# ImageMagick pixel enumeration: 1,1,255,srgb
0,0: (65535,65535,65535)  #FFFFFFFFFFFF  white
The color (which should be white regardless of any valid distortion), is being sampled using EWA resampling filter. If "-filter point" is added, to turn off EWA, the results are again good. However EWA lookup should not be dependant on the distort arguments, except in the form of scaling vector arguments, which for affine distortion is a constant.

This very specific 'single pixel' case will probably need to be traced, to figure out how the two runs differ.

Cristy what is your view?
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
tsanders
Posts: 13
Joined: 2012-12-06T04:14:34-07:00
Authentication code: 6789

Re: WEIRD: convert -distort Affine producing black images

Post by tsanders »

Anthony,

Thanks for your effort. I have done some further testing. The thing I am trying to do is to align 25 images with two "jittering" origin points to line up with two chosen destination points.

I have made 5 runs with the set of 25 x 2 points, making minor changes to only one destination point (x-coord changing from 399 to 403). These are the results:

run 1:
dest1 = 399, 1100
dest2 = 2400, 1100
black images: 001-007-009-012-020-025

run 2:
dest1 = 400,1100
dest2 = 2400,1100
black images: 001-010-014-017-023

run 3:
dest1 = 401,1100
dest2 = 2400,1100
black images: 001-004-008-009

run 4:
dest1 = 402,1100
dest2 = 2400,1100
black images: 001-002-007-008-019-020-022-025

run 5:
dest1 = 403,1100
dest2 = 2400,1100
black images: 003-005-008-009-010-019


These are the 25 x 2 "jittering" origin points that I want to align to the destination points:

001: 388,1061 - 2449,1066
002: 369,1063 - 2422,1078
003: 403,1087 - 2437,1081
004: 403,1066 - 2436,1051
005: 378,1116 - 2406,1125
006: 369,1060 - 2405,1077
007: 401,1020 - 2420,1031
008: 385,1027 - 2412,1026
009: 402,1046 - 2422,1047
010: 409,1014 - 2440,998
011: 380,1004 - 2403,1011
012: 406,1045 - 2429,1051
013: 394,1065 - 2424,1079
014: 407,1032 - 2429,1048
015: 419,1060 - 2457,1062
016: 390,1011 - 2414,1011
017: 368,981 - 2397,974
018: 392,950 - 2430,969
019: 379,987 - 2422,1001
020: 403,1017 - 2452,1037
021: 403,1015 - 2450,1033
022: 352,1033 - 2411,1029
023: 374,999 - 2434,1011
024: 420,1008 - 2489,1011
025: 391,952 - 2463,990

I have not been able to do a run without black images. Best I have seen is 1 black image.

Hope anyone can shine some light on this. I can't. And I need this desperately :(

Tom
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: WEIRD: convert -distort Affine producing black images

Post by magick »

Anthony, I'm getting two different results suggesting numerical stability. On my Linux 64-bit OS, we get expected results:

Code: Select all

convert -verbose xc: -distort Affine "369.5,1060.5 700,1100 2405.5,1077.5 2000,1100" txt:
xc:=> XC 1x1 1x1+0+0 16-bit sRGB 0.000u 0:00.000
Affine Projection:
  -distort AffineProjection \
      '0.638462,-0.005331,0.005331,0.638462,458.434660,424.880457'
Affine Distort, FX Equivelent:
  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;
       xx=+1.566154*ii -0.013077*jj -712.423077;
       yy=+0.013077*ii +1.566154*jj -671.423077;
       p{ xx-page.x-.5, yy-page.y-.5 }' \
# -----
dux=1.000000; dvx=0.000000;   duy=0.000000; dvy=1.000000;
major_x=1.000000; major_y=0.000000;  minor_x=-0.000000; minor_y=1.000000;
A=1.000000; B=-0.000000; C=1.000000; F=1.000000
# Major=1.000000; Minor=1.000000
1.00000000000000000000 1.00000000000000000000
# Angle=-0.000000   Area=3.141593
Ulimit=2.000000; Vlimit=2.000000; UWidth=2.000000; Slope=0.000000;
# -----
dux=1.000000; dvx=0.000000;   duy=0.000000; dvy=1.000000;
major_x=1.000000; major_y=0.000000;  minor_x=-0.000000; minor_y=1.000000;
A=1.000000; B=-0.000000; C=1.000000; F=1.000000
# Major=1.000000; Minor=1.000000
1.00000000000000000000 1.00000000000000000000
# Angle=-0.000000   Area=3.141593
Ulimit=2.000000; Vlimit=2.000000; UWidth=2.000000; Slope=0.000000;
# -----
dux=1.000000; dvx=0.000000;   duy=0.000000; dvy=1.000000;
major_x=1.000000; major_y=0.000000;  minor_x=-0.000000; minor_y=1.000000;
A=1.000000; B=-0.000000; C=1.000000; F=1.000000
# Major=1.000000; Minor=1.000000
1.00000000000000000000 1.00000000000000000000
# Angle=-0.000000   Area=3.141593
Ulimit=2.000000; Vlimit=2.000000; UWidth=2.000000; Slope=0.000000;
# -----
dux=1.566154; dvx=0.013077;   duy=-0.013077; dvy=1.566154;
major_x=-0.764604; major_y=-1.366890;  minor_x=1.366890; minor_y=-0.764604;
A=2.453009; B=-0.000000; C=2.453009; F=6.017253
# Major=1.566208; Minor=1.566208
1.56620843942932519433 1.56620843942932519433
# Angle=-0.000000   Area=7.706355
Ulimit=3.132417; Vlimit=3.132417; UWidth=3.132417; Slope=0.000000;
0.50000000000000000000 0.50000000000000000000
-711.64653846153873928415 -670.63346153845793651271
u0=-712.146538; v0=-671.133462;
# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (65535,65535,65535)  #FFFFFFFFFFFF  white
xc:=> XC 1x1 1x1+0+0 16-bit sRGB 0.000u 0:00.000
# -----
On my Linux 32-bit OS, we get:

Code: Select all

convert -verbose xc: -distort Affine "369.5,1060.5 700,1100 2405.5,1077.5 2000,1100" txt:
xc:=> XC 1x1 1x1+0+0 16-bit sRGB 0.000u 0:00.000
Affine Projection:
  -distort AffineProjection \
      '0.638462,-0.005331,0.005331,0.638462,458.434660,424.880457'
Affine Distort, FX Equivelent:
  -fx 'ii=i+page.x+0.5; jj=j+page.y+0.5;
       xx=+1.566154*ii -0.013077*jj -712.423077;
       yy=+0.013077*ii +1.566154*jj -671.423077;
       p{ xx-page.x-.5, yy-page.y-.5 }' \
# -----
dux=1.000000; dvx=0.000000;   duy=0.000000; dvy=1.000000;
major_x=1.000000; major_y=0.000000;  minor_x=-0.000000; minor_y=1.000000;
A=1.000000; B=-0.000000; C=1.000000; F=1.000000
# Major=1.000000; Minor=1.000000
# Angle=-0.000000   Area=3.141593
Ulimit=2.000000; Vlimit=2.000000; UWidth=2.000000; Slope=0.000000;
# -----
dux=1.566154; dvx=0.013077;   duy=-0.013077; dvy=1.566154;
major_x=nan; major_y=nan;  minor_x=nan; minor_y=nan;
A=nan; B=nan; C=nan; F=nan
# Major=nan; Minor=nan
# Angle=nan   Area=nan
Ulimit=nan; Vlimit=nan; UWidth=nan; Slope=nan;
u0=-712.146538; v0=-671.133462;
v1=-2147483648; v2=-2147483648
u1=-2147483648; uw=-2147483647
# scan line from pixel -2147483648, -2147483648
# ImageMagick pixel enumeration: 1,1,65535,srgb
0,0: (    0,    0,    0)  #000000000000  black
xc:=> XC 1x1 1x1+0+0 16-bit sRGB 0.000u 0:00.000
Notice that dux, duy, and dvy differs from the 64-bit run. Why are these values different on the 32-bit system? Find out and we probably have the solution to this problem.
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: WEIRD: convert -distort Affine producing black images

Post by anthony »

Only one pixel is being calculated. The last. the others with
dux=1.000000; dvx=0.000000; duy=0.000000; dvy=1.000000;
is initialization code for the filter, one for each thread.
Note for affine, the 'scaling vectors' only need to be calculated once as the scaling vectors are constant acroos the image.

In the 64 bit version you only set up three threads
In the 32 bit version 3 threads are being setup.

Looking at the last (the real calculation, not initialization code)
64 bit..
dux=1.566154; dvx=0.013077; duy=-0.013077; dvy=1.566154;

32 bit...
dux=1.566154; dvx=0.013077; duy=-0.013077; dvy=1.566154;

So that is fine.

What is different is that the 'ellipse axis vectors' is coming out as 'nan' or 'Not A Number'
major_x=nan; major_y=nan; minor_x=nan; minor_y=nan;

That would be the fault as it is screwing up ellipse calculations.
This calculation is handled by 'ClampUpAxis()' using code from Nicholas, which is to ensure that the ellipse approaches a unit radius circle (before being multipied by the filter support size).

I am not real familiar with the mathematics of that code, as it involved Jacobian Matrix and Eigenvalues. Which is rather beyond my 'math' level.

It may be a good idea to get Nicholas involved in this as he wrote the code.

However adding print statements through that code should let use pin-point exactly where the 'nan' comes into being, and probably soem special case in floating point handling.

The most likely point for 'nan' occuring that I can think of is the calculation of sqrt_discriminant

or... u11 = ( (norm>0.0) ? temp_u11/norm : 1.0 );
which may be too 'lenient' in its handling of norm>0.0 with floating point numbers.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
magick
Site Admin
Posts: 11064
Joined: 2003-05-31T11:32:55-07:00

Re: WEIRD: convert -distort Affine producing black images

Post by magick »

We can reproduce the problem you posted and have a patch in ImageMagick 6.8.0-9 Beta available by sometime tomorrow. Thanks.
NicolasRobidoux
Posts: 1944
Joined: 2010-08-28T11:16:00-07:00
Authentication code: 8675308
Location: Montreal, Canada

Re: WEIRD: convert -distort Affine producing black images

Post by NicolasRobidoux »

anthony wrote:...
or... u11 = ( (norm>0.0) ? temp_u11/norm : 1.0 );
which may be too 'lenient' in its handling of norm>0.0 with floating point numbers.
Agreed. This is bad coding, esp. with the newer chips, which use multiple paths at runtime, each using different "internal" precision, for computing "the same thing": "it" not being zero in one "path" does not mean that it is not zero in another. Sorry I'm being vague: Can't find the references. The best one I can get to quickly is http://accu.org/index.php/journals/1558:
Various myths concerning floating point calculations abound. Hopefully it is now clear why the following are myths:

Since C's float (or double) type is mapped to IEEE single (or double) precision arithmetic, arithmetic operations have a uniquely defined meaning across platforms.

Arithmetic operations are deterministic; that is, if I do z=x+y in two places in the same program and my program never touches x and y in the meantime, then the results should be the same.

A variant: 'If x < 1 tests true at one point, then x < 1 stays true later if I never modify x'.

The same program, strictly compliant with the C standard with no 'un-defined behaviours', should yield identical results if compiled on the same IEEE-compliant platform by different compliant compilers. [Monniaux08]
-----
I'll have a look at Cristy's patch.
Post Reply