Differences between revisions 99 and 100
Revision 99 as of 2008-08-20 01:20:55
Size: 11941
Comment:
Revision 100 as of 2008-08-20 01:37:31
Size: 12940
Comment:
Deletions are marked like this. Additions are marked like this.
Line 139: Line 139:
== 2D image alignment and the xform.align2d header attribute ==

2D image alignment is generally characterized by a single 2D translation and a single 2D rotation. Whether the translation occurs before or after the rotation is dependent on the alignment algorithm. The Transform3D object has been designed to allow for the encapsulation of 2D alignment parameters. Specifically, the EULER_EMAN phi ({{{$$\phi$$}}}) angle or the EULER_SPIDER psi ({{{$$\psi$$}}}) may be used to store the alignment angle. In regards to translation, either or both of the pre/post translational approaches may be taken in their 2D equivalent form. Given that the rotational alignment angle is denoted {{{$$\phi$$}}} and the pre and post translation vectors are written {{{$$(dx_{pre},dy_{pre})^T$$}}} and {{{$$(dx_{post},dy_{post})^T$$}}} respectively, the Transform3D object that has been constructed using the Python syntax
== 2D image alignment and the Transform3D ==

2D image alignment is generally characterized by a single 2D translation and a single 2D rotation. Whether the translation occurs before or after the rotation is dependent on the alignment algorithm. The Transform3D

=== The Transform3D
objects works in 2D ===

The Transform3D o
bject has been designed to allow for the storage of 2D alignment parameters. Specifically, the EULER_EMAN phi ({{{$$\phi$$}}}) angle or the EULER_SPIDER psi ({{{$$\psi$$}}}) may be used to store the alignment angle. In regards to translation, either or both of the pre/post translational approaches may be taken in their 2D equivalent form. Given that the rotational alignment angle is denoted {{{$$\phi$$}}} and the pre and post translation vectors are written {{{$$(dx_{pre},dy_{pre})^T$$}}} and {{{$$(dx_{post},dy_{post})^T$$}}} respectively, the Transform3D object that has been constructed using the Python syntax
Line 174: Line 178:
The contents of the Transform3D object are not checked to make sure they describe a single (phi) rotation and or whether the current translations are purely 2D, quite literally the contents of the internal transformation matrix are multiplied against the 2D transformation using the above formula. The contents of the Transform3D object are not checked to make sure they describe a single (phi) rotation and or whether the current translations are purely 2D, quite literally the contents of the internal transformation matrix are multiplied against the 2D transformation using the above formula.

=== The xform.align2d header attribute ===

The "xform.align2d" EMData attribute stores a Transform3D {{{$$T3D_{align2d}$$}}} aligns the noisy 2D Image {{{$$Image_{noisy}$$}}} to the reference 2D image {{{$$Image_{reference}$$}}} by direction transformation of image pixels, given by the following

{{{$$ Image_{noisy,aligned} = T3D_{align2d} Image_{reference} $$}}}

{{$$T3D_{align2d}$$}}} stores the alignment parameters internally according to

{{{$$T3D_{align2d} = T_{post} R T_{pre} = [[I,\mathbf{t}_{post}],[\mathbf{0}^T,1]] [[R,\mathbf{0}],[\mathbf{0}^T,1]] [[I,\mathbf{t}_{pre}],[\mathbf{0}^T,1]] $$}}}

Where

{{{$$ R = [[cos phi,sin phi, 0],[-sin phi,cos phi,0],[0,0,1]], \mathbf{t}_{pre} = (dx_{pre},dy_{pre},0)^T, \mathbf{t}_{post} = (dx_{post},dy_{post},0)^T $$}}

And in particular, {{{$$\phi$$}}} is the alignment angle and any combination of pre and post translation may be involved as part of the alignment transformation.

TableOfContents

Transformations in EMAN2

For a more information on the contents of 3D rotation matrices please consult the Sparx [http://macro-em.org/sparxwiki/Euler_angles Euler Angles] page.

The Transform3D Class

EMAN2 uses the [http://blake.bcm.edu/eman2/doxygen_html/classEMAN_1_1Transform3D.html Transform3D] class for storing/managing Euler angles and translations. At any time a Transform3D ($$T3D$$) object defines a group of 3 [http://en.wikipedia.org/wiki/Affine_transformations affine transformations] that are applied in a specific order, namely

$$T3D \equiv T_{post} R T_{pre}$$

Where $$T_{pre}  is a pre translation, $$R$$ is a rotation and $$T_{post}  is a post translation. The Transform3D object stores these transformations internally in a 4x4 matrix, as is commonly the case in computer graphics applications that use homogeneous coordinate systems (i.e. OpenGL). In these approaches the 4x4 transformation matrix $$T3D$$ is constructed in this way

$$T3D = [[R,\mathbf{t}],[\mathbf{0}^T,1]]$$

Where R is a $$3x3$$ rotation matrix and $$\mathbf{t}=(dx,dy,dz)^T$$ is a post translation. In this approach a 3D point $$\mathbf{p}=(x,y,z)^T$$ as represented in homogeneous coordinates as a 4D vector $$\mathbf{p}_{hc}=(x,y,z,1)^T$$ and is multiplied against the matrix $$M$$ to produce the result of applying the transformation

$$ T3D \mathbf{p}_{hc} = ( (R\mathbf{p} +  \mathbf{t})^T, 1 )^T  yuck fixme$$

In this way the result of applying a Transform3D to a vector is literally a rotation followed by a translation. The Transform3D allows for both pre and post translation and stores the cumulative result internally

$$T3D = T_{post} R T_{pre} = [[I,\mathbf{t}_{post}],[\mathbf{0}^T,1]] [[R,\mathbf{0}],[\mathbf{0}^T,1]] [[I,\mathbf{t}_{pre}],[\mathbf{0}^T,1]] = [[R,R\mathbf{t}_{pre}+\mathbf{t}_{post}],[\mathbf{0}^T,1]]$$

Constructing a Transform3D object in Python

In Python you can construct a Transform3D object in a number of ways

   1 from EMAN2 import Transform3D
   2 t = Transform3D() # t is the identity
   3 t = Transfrom3D(EULER_EMAN,25,45,65) # EULER_EMAN rotation convention uses the az, alt, phi 
   4 t = Transform3D(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention
   5 t = Transform3D(25,45,65) # EULER_EMAN convention used by default, arguments are taken as az, alt, phi
   6 t = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   7 t = Transform3D(25,45,65,Vec3f(4,5,6)) # EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   8 t = Transform3D(1,0,0,0,1,0,0,0,1) # Explicitly setting the nine members of the rotation matrix, row wise.
   9 s = Transform3D(t) # copy constructor

Setting Transform3D rotations and translation attributes in Python

You can set the pre and post translations, as well as the rotations, directly from Python

   1 from EMAN2 import Transform3D
   2 t = Transform3D()
   3 # setting the rotations
   4 t.set_rotation(25,45,65) # EULER_EMAN convention rotations az, alt, phi
   5 t.set_rotation(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention
   6 t.set_rotation(EULER_EMAN, {"az":25,"alt":45,"phi":65}) # Optional dictionary style approach
   7 t.set_rotation(1,0,0,0,1,0,0,0,1) # Explicitly set the nine members of the rotation matrix, row wise.
   8 # setting translations
   9 t.set_pretrans(1,2,3)# pre translation dx, dy, dz
  10 t.set_pretrans(Vec3f(1,2,3)) # also takes Vec3f argument
  11 t.set_pretrans([1,2,3]) # also takes tuple argument
  12 t.set_posttrans(4,5,6)# post translation dx, dy, dz
  13 t.set_posttrans(Vec3f(4,5,6)) # also takes Vec3f argument
  14 t.set_posttrans([4,5,6]) # also takes tuple argument

Getting transform3D rotations and translation attributes in Python

You can get these attributes using similar syntax to that employed for the setter methods

   1 from EMAN2 import Transform3D
   2 t = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   3 # get rotations
   4 dictionary = t.get_rotation(EULER_EMAN) # returns a dictionary with keys "az", "alt" and "phi"
   5 dictionary = t.get_rotation(EULER_SPIDER) # returns a dictionary with keys "phi", "theta" and "psi"
   6 # get translations
   7 vector = t.get_pretrans() # Returns a Vec3f object containing the translation
   8 vector = t.get_posttrans() # Returns a Vec3f object containing the translation

Multiplication

Transform3D times a Transform3D

The main thing to consider when multiplying two Transform3D objects is what will be the ultimate result of asking for the pre_trans and post_trans vectors of the resulting Transform3D object ($$T3D_{rst}$$). To answer this question we look at the details

$$T3D_{rst} = T3D_{2} T3D_{1} = T_{2,post} R_{2} T_{2,pre} T_{1,post} R_{1} T_{1,pre} = T_{2,post} R_{2} T_{2,pre}[[R_{1},R_{1}\mathbf{t}_{1,pre}+\mathbf{t}_{1,post}],[\mathbf{0}^T,1]]$$

$$ = T_{2,post} R_{2} [[R_{1},R_{1}\mathbf{t}_{1,pre}+\mathbf{t}_{1,post}+\mathbf{t}_{2,pre}],[\mathbf{0}^T,1]]$$

The translation in right column ($$R_{1}\mathbf{t}_{1,pre}+\mathbf{t}_{1,post}+\mathbf{t}_{2,pre}$$) is now what will be returned when $$T3D_{rst}$$ is asked for its pre_translation vector from python (or C++). Similarly, the post translation vector of $$T3D_{2}$$ will now be returned by calling get_postrans on $$T3D_{rst}$$. To complete the details, internally the Transform3D object will look like

$$ T3D_{rst} = [[ R_{2}R_{1},R_{2}(R_{1}\mathbf{t}_{1,pre}+\mathbf{t}_{1,post}+\mathbf{t}_{2,pre})+\mathbf{t}_{2,post}],[\mathbf{0}^T,1]]$$

In Python the Transfrom3D x Transform3D operation can be achieved using the '*' operator

   1 T1 = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   2 T2 = Transform3D(25,45,65,Vec3f(4,5,6)) # EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   3 Trst = T2*T1

Transform3D times a 3D vector (Vec3f)

If v is a three dimensional vector encapsulated as a Vec3f then one can right multiply it by a Transform3D object and this achieves the following result

$$T3D \mathbf{v} =  [[R,R\mathbf{t}_{pre}+\mathbf{t}_{post}],[\mathbf{0}^T,1]] \mathbf{v}  $$

$$T3D \mathbf{v} = Rv+R\mathbf{t}_{pre}+\mathbf{t}_{post}  $$

The vector v is treated implicitly as though it were an homogeneous point, but the last row of the matrix-vector multiplication is not performed.

In Python the Transfrom3D x Vec3f operation can be achieved using the '*' operator or by calling the Transform3D::transform(Vec3f) function

   1 T = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   2 v = Vec3f(1,2,3) # for example, pixel coordinates 1,2,3
   3 v_dash = T*v
   4 v_dash = T.transform(v) # Achieves the same result as calling T*v

Explicitly rotating a 3D vector (Vec3f)

If a Transform3D is represented as

$$T3D = [[R,\mathbf{t}],[\mathbf{0}^T,1]]$$

One can calculate

$$\mathbf{v}_R = R \mathbf{v}$$

in Python by doing

   1 T = Transform3D(Vec3f(1,2,3),25,45,65,Vec3f(4,5,6)) # Specify a pre trans, followed by EULER_EMAN convention rotations az, alt, phi, followed by the post trans
   2 v = Vec3f(1,2,3) # for example, pixel coordinates 1,2,3
   3 v_R = T.rotate(v)

Alignment conventions and EMData header attributes

2D image alignment and the Transform3D

2D image alignment is generally characterized by a single 2D translation and a single 2D rotation. Whether the translation occurs before or after the rotation is dependent on the alignment algorithm. The Transform3D

The Transform3D objects works in 2D

The Transform3D object has been designed to allow for the storage of 2D alignment parameters. Specifically, the EULER_EMAN phi ($$\phi$$) angle or the EULER_SPIDER psi ($$\psi$$) may be used to store the alignment angle. In regards to translation, either or both of the pre/post translational approaches may be taken in their 2D equivalent form. Given that the rotational alignment angle is denoted $$\phi$$ and the pre and post translation vectors are written $$(dx_{pre},dy_{pre})^T$$ and $$(dx_{post},dy_{post})^T$$ respectively, the Transform3D object that has been constructed using the Python syntax

   1 t = Transform3D(0,0,25) # 25 is phi
   2 t.set_pretrans(2,3) # pre translation dx and dy
   3 t.set_posttrans(-1,-10) # post translation dx and dy

and this will create a Transform3D matrix $$T3D_{2D}$$ that stores the transformation matrix as

$$T3D_{2D} \equiv [[cos phi,sin phi, 0, cos phi * dx_{pre} + sin phi * dy_{pre} + dx_{post}],[-sin phi,cos phi,0,-sin phi * dx_{pre} + cos phi * dy_{pre} + dy_{post}],[0,0,1,0],[0,0,0,1]]$$

The Vec2f object

The Vec2f object was created specifically to be used with Transform3D objects in situations involving 2D alignments. You can set Transform3D pre and post translations using Vec2f objects in Python as follows

   1 from EMAN2 import Transform3D, Vec2f
   2 t = Transform3D(0,0,25) # 25 is phi
   3 pretrans = Vec2f(2,3)
   4 posttrans = Vec2f(-1,10)
   5 t.set_pretrans(pretrans) # pre translation dx and dy
   6 t.set_posttrans(postrans) # post translation dx and dy

Transform3D times a 2D vector (Vec2f)

A Vec2f may be right multiplied against a Transform3D object to efficiently calculate transformed 2D coordinates. In this mode of operation the Transform3D object is treated implicitly as though it were 2D affine transformation matrix -

$$ T3D_{2D} \dot \mathbf(Vec2f) = [[cos phi,sin phi, 0, cos phi * dx_{pre} + sin phi * dy_{pre} + dx_{post}],[-sin phi,cos phi,0,-sin phi * dx_{pre} + cos phi * dy_{pre} + dy_{post}],[0,0,1,0],[0,0,0,1]] \dot \mathbf(Vec2f) $$

$$ \equiv [[cos phi,sin phi, cos phi * dx_{pre} + sin phi * dy_{pre} + dx_{post}],[-sin phi,cos phi,-sin phi * dx_{pre} + cos phi * dy_{pre} + dy_{post}],[0,0,1]] ((v_x),(v_y),(1)) $$

The contents of the Transform3D object are not checked to make sure they describe a single (phi) rotation and or whether the current translations are purely 2D, quite literally the contents of the internal transformation matrix are multiplied against the 2D transformation using the above formula.

The xform.align2d header attribute

The "xform.align2d" EMData attribute stores a Transform3D $$T3D_{align2d}$$ aligns the noisy 2D Image $$Image_{noisy}$$ to the reference 2D image $$Image_{reference}$$ by direction transformation of image pixels, given by the following

$$ Image_{noisy,aligned} = T3D_{align2d} Image_{reference} $$

$$T3D_{align2d}$$} stores the alignment parameters internally according to

$$T3D_{align2d} = T_{post} R T_{pre} = [[I,\mathbf{t}_{post}],[\mathbf{0}^T,1]] [[R,\mathbf{0}],[\mathbf{0}^T,1]] [[I,\mathbf{t}_{pre}],[\mathbf{0}^T,1]] $$

Where

{$$ R = [[cos phi,sin phi, 0],[-sin phi,cos phi,0],[0,0,1]], \mathbf{t}_{pre} = (dx_{pre},dy_{pre},0)^T, \mathbf{t}_{post} = (dx_{post},dy_{post},0)^T $$

And in particular, $$\phi$$ is the alignment angle and any combination of pre and post translation may be involved as part of the alignment transformation.

3D object alignment

text

The xform.align3d header attribute

text

3D projection alignment

text

The xform.reconstruct header attribute

text

Transformations and projections

Say the data model is a 3D map denoted M(x,y,z) and a projection is to be generated in a particular direction. The model may also be pre and/or post translated as part of the projection process. The translation information along with the direction of the projection is to be stored in a Transform3D object T, and the projection is to be generated according to or equivalently to the following

$$p(x,y) = int_z T3D M(x,y,z)  dz$$

That is, the projection operation can be thought of as first transforming the 3D map M by the Transform3D object, and by subsequently taking planar integrals along z.

Transformations and backprojections

If a projection was generated as described above using a Transform3D object, the operation of backprojection (in the same direction) requires inverse of the original Transform3D object.

Using 3D symmetry (Symmetry3D) objects together with Transform3D objects

Description will go here

EMAN2/TransformConventions (last edited 2009-02-04 21:14:56 by DavidWoolford)