# [Scipy-tickets] [SciPy] #1736: Proper order of translation and rotation in scipy.ndimage.affine_transform

SciPy Trac scipy-tickets@scipy....
Mon Sep 24 11:21:57 CDT 2012

```#1736: Proper order of translation and rotation in scipy.ndimage.affine_transform
----------------------------------------------------+-----------------------
Reporter:  obsessive_pipette_guy                   |       Owner:  somebody
Type:  defect                                  |      Status:  new
Priority:  normal                                  |   Milestone:  Unscheduled
Component:  scipy.ndimage                           |     Version:  0.10.0
Keywords:  affine_transform rotation offset order  |
----------------------------------------------------+-----------------------
It ought to be easy to use scipy's affine_transform to perform any
arbitrary set of affine transformations in a single step by composing them
into a single rotation and translation, but because affine_transform does
rotation and translation in the wrong order, this is '''way''' harder to
do than it should be.

For example, supposing I have an image and I want to rotate it 45o about
its centre and translate it so that its centre is at (300,500). Normally,
I would do this by composing affine matrices for each step using
homogeneous coordinates, then multiply them together and apply the result:

{{{
import numpy as np
from scipy.ndimage import affine_transform
from scipy.misc import lena

img = lena()
rows,cols = img.shape

# centre image on the origin
centre = np.identity(3)
centre[:2,2] = -rows/2.,-cols/2.

# rotate it
rotate = np.identity(3)
rotate[:2,:2] =
[np.cos(theta),np.sin(theta)],[-np.sin(theta),np.cos(theta)]

# translate it to the final position
translate = np.identity(3)
translate[:2,2] = 300,500

# compose the affine matrix
affine = np.dot(translate,np.dot(rotate,centre))

# this ought to work, but it doesn't!
rmat = affine[:2,:2]
offset = affine[:2,2]
transformed =
affine_transform(img,rmat,offset=offset,output_shape=(512,512))
}}}

The problem is that affine_transform does the translation ('offset')
''before'' it does the rotation, whereas the use of matrices for linear
transformations implicitly assumes that the translation is done ''after''
the rotation:

{{{
affine   coords   rotation  translation
[a b c]   [x]     [ax + by] + [c]
[d e f] * [y]  =  [dx + ey] + [f]
[0 0 1]   [1]
}}}

So at the moment, in order to combine multiple translations and rotations
into a single call to affine_transform you have to do mental gymnastics in
order to take into account the fact that affine_transform does the
translation first.

I would suggest that, at the very least, the order in which the offset and
rotation matrix are applied by affine-transform should be corrected. Doing
the translation before the rotation is just wrong.

Even better, it would be great if affine_transform could just take a 3x3
affine matrix (much like MATLAB's maketform), so that it would be easy to
compose and apply arbitrary affine transformations.

--
Ticket URL: <http://projects.scipy.org/scipy/ticket/1736>
SciPy <http://www.scipy.org>
SciPy is open-source software for mathematics, science, and engineering.
```