Size: 454
Comment:
|
Size: 7554
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
== Transformations in the context of projections, reconstructions, and in general == | [[TableOfContents]] |
Line 3: | Line 3: |
=== Transforming an EMData object === | = Transformations in EMAN2 = == 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 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,\hat{t}],[\hat{0}^T,1]]$$}}} Where R is a {{{$$3x3$$}}} rotation matrix and {{{$$\hat{t}=(dx,dy,dz)^T$$}}} is a post translation. In this approach a 3D point {{{$$\hat{p}=(x,y,z)^T$$}}} as represented in homogeneous coordinates as a 4D vector {{{$$\hat{p_{hc}}=(x,y,z,1)^T$$}}} and is multiplied against the matrix {{{$$M$$}}} to produce the result of applying the transformation {{{$$ T3D \hat{p}_{hc} = ( R\hat{p} + \hat{t}, 1 )^T $$}}} In this way the result of applying a Transform3D to a vector is literally a rotation follow 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,\hat{t}_{post}],[\hat{0}^T,1]] [[R,\hat{0}],[\hat{0}^T,1]] [[I,\hat{t}_{pre}],[\hat{0}^T,1]] = [[R,R\hat{t}_{pre}+\hat{t}_{post}],[\hat{0}^T,1]]$$}}} === Constructing a Transform3D Object In Python === In Python you can construct a Transform3D object in a number of ways {{{#!python from EMAN2 import Transform3D t = Transform3D() # t is the identity t = Transfrom3D(EULER_EMAN,25,45,65) # EULER_EMAN rotation convention uses the az, alt, phi t = Transform3D(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention t = Transform3D(25,45,65) # EULER_EMAN convention used by default, arguments are taken as az, alt, phi 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 t = Transform3D(25,45,65,Vec3f(4,5,6)) # EULER_EMAN convention rotations az, alt, phi, followed by the post trans t = Transform3D(1,0,0,0,1,0,0,0,1) # Explicitly setting the nine members of the rotation matrix, row wise. s = Transform3D(t) # copy constructor }}} === Setting and Getting Transform3D Rotations and Translation Attributes === You can set the pre and post translations, as well as the rotations, directly from Python {{{#!python from EMAN2 import Transform3D t = Transform3D() # setting the rotations t.set_rotation(25,45,65) # EULER_EMAN convention rotations az, alt, phi t.set_rotation(EULER_SPIDER,24,44,64) # EULER_SPIDER rotation convention uses the phi, theta, psi convention t.set_rotation(EULER_EMAN, {"az":25,"alt":45,"phi":65}) # Optional dictionary style approach t.set_rotation(1,0,0,0,1,0,0,0,1) # Explicitly set the nine members of the rotation matrix, row wise. # setting translations t.set_pretrans(1,2,3)# pre translation dx, dy, dz t.set_pretrans(Vec3f(1,2,3)) # also takes Vec3f argument t.set_pretrans([1,2,3]) # also takes tuple argument t.set_posttrans(4,5,6)# post translation dx, dy, dz t.set_posttrans(Vec3f(4,5,6)) # also takes Vec3f argument t.set_posttrans([4,5,6]) # also takes tuple argument }}} == 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 from Python. To answer this question we look at the details {{{$$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}\hat{t}_{1,pre}+\hat{t}_{1,post}],[\hat{0}^T,1]]$$}}} {{{$$ = T_{2,post} R_{2} [[R_{1},R_{1}\hat{t}_{1,pre}+\hat{t}_{1,post}+\hat{t}_{2,pre}],[\hat{0}^T,1]]$$}}} The translation in right column is now what will be returned when the Transform3D object is asked for its pre_translation vector from python. Similarly, the post translation vector of {{{$$T3D_{2}$$}}} will now be returned by a call to get_postrans. To complete the details, internally the Transform3D object will look like {{{$$ $$T3D_{2} T3D_{1} = T_{2,post} [ R_{2}[R_{1},R_{1}\hat{t}_{1,pre}+\hat{t}_{1,post}+\hat{t}_{2,pre}],[\hat{0}^T,1]]$$}}} You can get these attributes using similar syntax {{{#!python from EMAN2 import Transform3D 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 # get rotations dictionary = t.get_rotation(EULER_EMAN) # returns a dictionary with keys "az", "alt" and "phi" dictionary = t.get_rotation(EULER_SPIDER) # returns a dictionary with keys "phi", "theta" and "psi" # get translations vector = t.get_pretrans() # Returns a Vec3f object containing the translation vector = t.get_posttrans() # Returns a Vec3f object containing the translation }}} == Rotations == A rotation of a pixel coordinate at [x,y,z] about the y axis looks like 4x4 Rotation matrix x homog pix coord In general a rotation matrix will look like this 4x4 general rotation matrix Note that only the upper left 3x3 block is used to store the rotation information == Translations == Translation of a pixel coordinate at [x,y,z] by [dx,dy,dz] looks like 4x4 depiction of translation matrix x homog pix coord This shows how the homogeneous coordinate representation is used to achieve translation == Rotations and Translations == Rotation Need MathML == Transforming an EMData object == |
Line 9: | Line 120: |
t = Transform3D(EULER_EMAN,10,23,0) # three angles are az=10,alt=23,phi=0 | t = Transform3D(EULER_EMAN,10,23,0) # three angles in the EMAN convention are az=10,alt=23,phi=0. # The convention may also be EULER_SPIDER, EULER_IMAGIC, EULER_MRC, EULER_SPIN, EULER_XYZ |
Line 15: | Line 127: |
This next section will look better once we get mathml working | |
Line 16: | Line 129: |
=== Transforms and Euler Angles in the context of Projections === | A pixel given at coordinate vector v = [x,y,z]^T will be transformed using the following" {{{$$vhat = T_{post} R T_{pre} v$$}}} Where the rotation matrix R and associated conventions are defined in Baldwin and Penczek 2007. == 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 T M(x,y,z) dz$$}}} That is, the projection is generated by first transforming the 3D map M by the Transform3D object, and proceeded by taking line integrals along z. == Transformations and recontructors == In order to insert a projection as generated in the conventional way (above) into a 3D volume in the correct orientation, one must invert the Transform3D object that was used to generate the projection prior to slice insertion. |
Transformations in EMAN2
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 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,\hat{t}],[\hat{0}^T,1]]$$
Where R is a $$3x3$$ rotation matrix and $$\hat{t}=(dx,dy,dz)^T$$ is a post translation. In this approach a 3D point $$\hat{p}=(x,y,z)^T$$ as represented in homogeneous coordinates as a 4D vector $$\hat{p_{hc}}=(x,y,z,1)^T$$ and is multiplied against the matrix $$M$$ to produce the result of applying the transformation
$$ T3D \hat{p}_{hc} = ( R\hat{p} + \hat{t}, 1 )^T $$
In this way the result of applying a Transform3D to a vector is literally a rotation follow 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,\hat{t}_{post}],[\hat{0}^T,1]] [[R,\hat{0}],[\hat{0}^T,1]] [[I,\hat{t}_{pre}],[\hat{0}^T,1]] = [[R,R\hat{t}_{pre}+\hat{t}_{post}],[\hat{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 and Getting Transform3D Rotations and Translation Attributes
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
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 from Python. To answer this question we look at the details
$$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}\hat{t}_{1,pre}+\hat{t}_{1,post}],[\hat{0}^T,1]]$$
$$ = T_{2,post} R_{2} [[R_{1},R_{1}\hat{t}_{1,pre}+\hat{t}_{1,post}+\hat{t}_{2,pre}],[\hat{0}^T,1]]$$
The translation in right column is now what will be returned when the Transform3D object is asked for its pre_translation vector from python. Similarly, the post translation vector of $$T3D_{2}$$ will now be returned by a call to get_postrans. To complete the details, internally the Transform3D object will look like
$$ $$T3D_{2} T3D_{1} = T_{2,post} [ R_{2}[R_{1},R_{1}\hat{t}_{1,pre}+\hat{t}_{1,post}+\hat{t}_{2,pre}],[\hat{0}^T,1]]$$
You can get these attributes using similar syntax
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
Rotations
A rotation of a pixel coordinate at [x,y,z] about the y axis looks like
4x4 Rotation matrix x homog pix coord
In general a rotation matrix will look like this
4x4 general rotation matrix
Note that only the upper left 3x3 block is used to store the rotation information
Translations
Translation of a pixel coordinate at [x,y,z] by [dx,dy,dz] looks like
4x4 depiction of translation matrix x homog pix coord
This shows how the homogeneous coordinate representation is used to achieve translation
Rotations and Translations
Rotation
Need MathML
Transforming an EMData object
An EMData object may be transformed using the following syntax
This next section will look better once we get mathml working
A pixel given at coordinate vector v = [x,y,z]^T will be transformed using the following"
$$vhat = T_{post} R T_{pre} v$$
Where the rotation matrix R and associated conventions are defined in Baldwin and Penczek 2007.
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 T M(x,y,z) dz$$
That is, the projection is generated by first transforming the 3D map M by the Transform3D object, and proceeded by taking line integrals along z.
Transformations and recontructors
In order to insert a projection as generated in the conventional way (above) into a 3D volume in the correct orientation, one must invert the Transform3D object that was used to generate the projection prior to slice insertion.