AffineImageTransformation broken

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.
User avatar
rmabry
Posts: 148
Joined: 2004-04-13T11:25:27-07:00

Post by rmabry »

anthony wrote: Bilinear in contrast just averages out all the pixel colors in the very center of the inter-pixel space, whcih sort of 'blurs' a 'hash' or 'dither pattern' in images.


Right, an average weighted by the areas produced when a transformed pixel cuts the original grid of pixels. It strikes me as being the right method for a translation by a fraction of a pixel and for any horizontal or vertical stretching, but perhaps not much more. (More on such translations below.) Still, it seems to do an adequate job in some other cases because, I suppose, it at least does *something* and preserves local averages.
As for the next step in testing, I would try very very slight partial pixel level translations
of a single pixel image and check the look and size of the image at various numbers. EG: .3 .5 .8 etc and even small negative movements, to ensure the final image size and placements and the look of the single 'pixel' is also correct.

If that works then the low level stuff should also be right. However a quick look

Code: Select all

    convert xc:blue -affine 1,0,0,1,.3,0 -transform info:
    xc:blue XC 1x1 1x1+0+0 DirectClass 16-bit 
Also

Code: Select all

convert pattern:gray50 -interpolate bilinear -affine 1,0,0,1,.5,0 -transform x:
shows that the translation does not enlarge the destination image correctly as it remains a single pixel in size. Of course as the size is wrong the single pixel lookup is not a proper representation of the result, and the 'hash' shows no sign of the bilinear interpolation, whcih should produce an 'averaged grey' in the last example (I think).


Right, but as I said, this doesn't have any effect right now, except on the virtual canvas (via page.x and page.y). I'm not suggesting changing it, because this is clearly intentional at the moment: the code presently checks the "extent" of the transformed image (using the min and max x and y values of the transformed corners) and then translates it to fit in the smallest possible window. Therefore when the affine transform is itself a translation, the code just translates it right back!

It is nice to have that as a default, but some day it seems reasonable to add the option of leaving the viewport fixed and just taking what comes into it by way of the transform. (Someone was recently asking for this in the case of rotations, with the ability to choose a center of rotation. That would be very useful.) Yet another option would be to enlarge the image to contain the transformed extents. In that case a translation to the right would always grow the size of the image in that direction, for instance.

I see a bug in PerlMagick that affects the translation part. I'll post that elsewhere.

Rick
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Post by anthony »

the code presently checks the "extent" of the transformed image (using the min and max x and y values of the transformed corners) and then translates it to fit in the smallest possible window.


That is true, but it does not 'floor(), or ceil()' those maximum and minimums before it turns then from intergers to floats.

translating a single pixel any fraction of a pixel should result in a resulting image that is
two pixels wide, each pixel containing part of the original pixel as it is blured by the interpolation lookup.

EG:

Code: Select all

  convert xc:blue -affine 1,0,0,1,.3,0 -transform info: 
should have produced a 2x1 pixel image! only a integer translation should retain the exact original size of the image, and only result in a change to the virtual offset.

This was what I was getting at, when I first brought up the posibility that while Affine Transformation was working in a gross way, it may not be exact at the pixel level.

-----
As for your proposed option, I agree a selection on weather images are enlarged or the size is preserved would be nice, (with the default to preserve the size). Thorugh right now we have been concentrating on ensuring that we preserve ALL the information, to give the user the maximum freedom to express what they want to do.

The option however should allow you to: crop to original size, center crop to original size, fit transformed image size. (the center crop I would prefer as a good default, though would negate any effect from affine translation). These would also speed up translations as it reduces the number of transformed color lookups needed.

Such a option would be easy to implement in affine too. though should probably also effect the other distortion mapping operators like -rotate -shear and -wave, as well.

In the mean time the last example in the rotate section shows a technique of cropping the result to match the original image.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Post Reply