[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
 theta = np.deg2rad(45)
 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.


More information about the Scipy-tickets mailing list