Page 1 of 1

Affine transformatino not accurate

Posted: 2010-04-15T07:58:28-07:00
by sherwood168
I rotated an image at 90 degrees. The image theoretically should swap its width and height. However, I got different results:

Code: Select all

convert mouse.png -matte -virtual-pixel transparent -affine 0,1,-1,0,0,0,0 -transform +repage affine_rotate.png

identify mouse.png
mouse.png PNG 150x88 150x88+0+0 DirectClass 8-bit 13.0723kb

identify affine_rotate.png
affine_rotate.png PNG 90x152 90x152+0+0 DirectClass 8-bit 13.0879kb
The origial image has a dimension of 150X88. I expected that the result image dimension is 88X150 but I got 90X152.

I understand that it might be caused by inaccurate floating number math, but is there anyway to improve it so that rotation produces accurate results at 90, 180, 270 degrees?

Re: Affine transformatino not accurate

Posted: 2010-04-15T09:42:43-07:00
by snibgo
Very strange. You might want to post this in the bugs forum: viewforum.php?f=3

Meanwhile, you might try "-rotate 90".

Re: Affine transformatino not accurate

Posted: 2010-04-15T10:07:40-07:00
by snibgo
Incidentally, I don't get that problem on some trial images with IM 6.6.0-8 on Windows7. Can you post mouse.png? What IM version are you on?

Re: Affine transformatino not accurate

Posted: 2010-04-15T18:50:13-07:00
by anthony
The Affine transform IS accurate! The actual image size is not relevent! Image content is what is important here. and the Image content is correct!

The -affine -transform operators are actually calls to the newer +distort routine (which the older calls). This routine adds an extra pixel border around the distortion (with virtual offset (page)), to ensure that any semi-transparent edge anti-aliasing is not clipped, in the generic case.

For example if you did not just do a simple rotation, but also scaled the image by half, you will get some semi-transparent pixels around the edges, even if the original image would scale to exactly integer pixels. It also very much depends on the -interpolation and -filter settings that being used for the image resampling.

Examples of scaling and resizing images using Affine type transforms is covered in
IM Examples, Resizing of Scaling, Distort/Affine Resize - free-form resizing
http://www.imagemagick.org/Usage/resize/#distort

These examples are relevent regardless of if rotation is applied or not.

Your rotation by 90 degrees is a very VERY special case, and not a generic case. If you want perfect 90 degree rotations, then you are better off using -rotate which does not include scaling or shearing components, and as such can handles 90 degree rotations as being 'special'.

Re: Affine transformatino not accurate

Posted: 2010-04-15T19:22:04-07:00
by snibgo
It might be a good thing if the documentation http://www.imagemagick.org/script/comma ... hp?#affine mentioned this additional pixel border.

Re: Affine transformatino not accurate

Posted: 2010-04-15T19:42:06-07:00
by anthony
snibgo wrote:It might be a good thing if the documentation http://www.imagemagick.org/script/comma ... hp?#affine mentioned this additional pixel border.
What it really should say is that it is really equivalent to +distort AffineProjection, and its output is a virtual canvas with a vitural offset (posibily negative).

As I said the image size is not important to distorted images, as long as it contains all the results.

What is important is correct image content and the correct offset for placement. Remember unlike a simple image -rotate. A affine rotation as a 'origin' or 'point of rotation' and in its most simplist usage, probably rotated the image completely out of the normal 'positive' space, around a fixed origin (such as the top left corner!). Even the older 'non-distort' version of -affine -transform did this!

You can see my older notes on using Affine Transformations in...
Affine Matrix Transforms (a separate sub-page of examples)
http://www.imagemagick.org/Usage/distorts/affine/

NOTE the heavy use of +repage to delete the virtual offsets from image results!

The only reason -affine still exists as an option is that it provides an alternative method of setting an affine distortion for the -draw command. +distort should really be used instead.