eman2:transforminpython
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| eman2:transforminpython [2025/06/19 19:56] – created steveludtke | eman2:transforminpython [2025/07/06 03:39] (current) – steveludtke | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== The center of the image ====== | + | ====== Transforms in Python ====== |
| + | |||
| + | ===== The center of the image ===== | ||
| ---- | ---- | ||
| - | The center of the image for purposes of rotations is different for odd and even sized images. For even images, the center is at (nx/2,ny/2) where the first pixel is at (0,0). For odd sized images, the center is at ((nx-1)/ | + | The center of the image for purposes of rotations is different for odd and even sized images. For even images, the center is at $(nx/2,ny/2)$ where the first pixel is at $(0,0)$. For odd sized images, the center is at $((nx-1)/ |
| {{attachment: | {{attachment: | ||
| - | ====== What is a Transform? | + | ===== What is a Transform? ===== |
| ---- | ---- | ||
| - | We use the [[http:// | + | We use the [[http:// |
| - | < | + | $$\mathrm{Tr} = M T S R$$ |
| - | Where < | + | Where $M$ is a mirroring operation about the x-axis, |
| - | ====== Supported Rotation Conventions | + | ===== Supported Rotation Conventions ===== |
| ---- | ---- | ||
| ||Convention ||Angle Names ||Matrices || | ||Convention ||Angle Names ||Matrices || | ||
| - | ||EMAN ||az, alt, phi (Z, | + | ||EMAN ||az, alt, phi (Z, |
| - | ||Imagic ||gamma, beta, alpha ||< | + | ||Imagic ||gamma, beta, alpha ||$\begin{bmatrix}\cos gamma&\sin gamma& 0\\-\sin gamma&\cos gamma&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}1&0&0\\0& \cos beta& \sin beta\\0& -\sin beta& \cos beta\end{bmatrix}$ $\begin{bmatrix}\cos alpha&\sin alpha& 0\\-\sin alpha&\cos alpha&0\\0&0&1\end{bmatrix}$ |
| - | ||Spider ||psi, theta, phi ||< | + | ||Spider ||psi, theta, phi ||$\begin{bmatrix}\cos psi&\sin psi& 0\\-\sin psi&\cos psi&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos theta&0&\sin theta\\0& 1& 0\\-\sin theta& 0& \cos theta\end{bmatrix}$ $\begin{bmatrix}\cos phi&\sin phi& 0\\-\sin phi&\cos phi&0\\0&0&1\end{bmatrix}$ |
| - | ||MRC ||phi, theta, omega ||< | + | ||MRC ||phi, theta, omega ||$\begin{bmatrix}\cos phi&\sin phi& 0\\-\sin phi&\cos phi&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos theta&0&\sin theta\\0& 1& 0\\-\sin theta& 0& \cos theta\end{bmatrix}$ $\begin{bmatrix}\cos omega&\sin omega& 0\\-\sin omega&\cos omega&0\\0&0&1\end{bmatrix}$ |
| - | ||XYZ ||z, y, x ||< | + | ||XYZ ||z, y, x ||$\begin{bmatrix}\cos z&\sin z& 0\\-\sin z& \cos z&0\\0&0&1\end{bmatrix}$ $\begin{bmatrix}\cos y&0&\sin y\\0& 1& 0\\-\sin y& 0& \cos y\end{bmatrix}$ $\begin{bmatrix}1&0&0\\0& \cos x& \sin x\\0& -\sin x& \cos x\end{bmatrix}$ |
| - | ||spin ||Omega, n1, n2, n3 ||Quaternion rotation by Omega degrees about the vector [n1,n2\,n3] || | + | ||spin ||Omega, n1, n2, n3 ||Quaternion rotation by Omega degrees about the vector |
| - | ||sgirot ||q, n1, n2, n3 ||Quaternion rotation by q degrees about the vector [n1,n2\,n3] || | + | ||sgirot ||q, n1, n2, n3 ||Quaternion rotation by q degrees about the vector |
| - | ||quaternion ||e0, e1, e2, e3 ||Literal quaternion rotation using q = e0 + e1\mathbf{i} + e2\mathbf{j} + e2\mathbf{k} | + | ||quaternion ||e0, e1, e2, e3 ||Literal quaternion rotation using |
| ||2d||alpha||Rotation in 2-D only, for 3-D objects this is a rotation about Z|| | ||2d||alpha||Rotation in 2-D only, for 3-D objects this is a rotation about Z|| | ||
| - | ====== The Transform object in Python | + | ===== The Transform object in Python ===== |
| ---- | ---- | ||
| - | ===== Constructing a Transform | + | ==== Constructing a Transform ==== |
| There a four ways to construct a Transform object in Python | There a four ways to construct a Transform object in Python | ||
| - | <code>#!python | + | <code python> |
| t = Transform() # default constructor, | t = Transform() # default constructor, | ||
| t = Transform({" | t = Transform({" | ||
| Line 44: | Line 46: | ||
| For example: | For example: | ||
| - | <code>#!python | + | <code python> |
| t = Tranform({" | t = Tranform({" | ||
| t = Tranform({" | t = Tranform({" | ||
| Line 51: | Line 53: | ||
| </ | </ | ||
| - | For more information on default parameters and what happens when some parameters are not set see [[# | + | ==== Setting/ |
| - | + | <code python> | |
| - | ===== Setting/ | + | |
| - | <code>#!python | + | |
| t = Transform() | t = Transform() | ||
| t.set_rotation({" | t.set_rotation({" | ||
| Line 67: | Line 67: | ||
| You can supply ANY rotation CONVENTION as a string to get the rotation in the corresponding convention, irrespective of the " | You can supply ANY rotation CONVENTION as a string to get the rotation in the corresponding convention, irrespective of the " | ||
| - | <code>#!python | + | <code python> |
| t = Transform({' | t = Transform({' | ||
| </ | </ | ||
| Line 73: | Line 73: | ||
| You can still get the rotation in other conventions: | You can still get the rotation in other conventions: | ||
| - | <code>#!python | + | <code python> |
| t.get_rotation(' | t.get_rotation(' | ||
| t.get_rotation(' | t.get_rotation(' | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| - | < | + | < |
| t = Transform() | t = Transform() | ||
| t.set_scale(2.0) | t.set_scale(2.0) | ||
| Line 85: | Line 85: | ||
| s = Transform({" | s = Transform({" | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| - | < | + | < |
| t = Transform() | t = Transform() | ||
| # Can be set using integers | # Can be set using integers | ||
| Line 96: | Line 96: | ||
| s = Transform({" | s = Transform({" | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| - | < | + | < |
| t = Transform() | t = Transform() | ||
| t.set_trans(1, | t.set_trans(1, | ||
| Line 105: | Line 105: | ||
| s = Transform({" | s = Transform({" | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| You can tell a Transform deduce any of its parameters from a dictionary. Similarly you can get the parameters of a Transform as a dictionary | You can tell a Transform deduce any of its parameters from a dictionary. Similarly you can get the parameters of a Transform as a dictionary | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 118: | Line 118: | ||
| s = Transform(d) # s is the same as t | s = Transform(d) # s is the same as t | ||
| </ | </ | ||
| - | For more information the behaviour of set_params see [[# | ||
| - | ===== A Transform multiplied by a Vec3f ===== | + | ==== A Transform multiplied by a Vec3f ==== |
| - | The transformation of a 3D vector | + | The transformation of a 3D vector $$ v = (v_x, |
| - | < | + | $$ Tr \mathbf{v} |
| This can be done in Python using the following | This can be done in Python using the following | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 134: | Line 133: | ||
| v_transformed = t.transform(v) # can also do it this way if you prefer | v_transformed = t.transform(v) # can also do it this way if you prefer | ||
| </ | </ | ||
| - | ===== Transforming a 3D image ===== | + | ==== Transforming a 3D image ==== |
| Transforming a 3D image is achieved using a single function call | Transforming a 3D image is achieved using a single function call | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 146: | Line 145: | ||
| You can alternatively use the EMData processing framework, for example: | You can alternatively use the EMData processing framework, for example: | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 155: | Line 154: | ||
| In fact < | In fact < | ||
| - | ====== 2D degenerate use of the Transform object in Python | + | ===== 2D degenerate use of the Transform object in Python ===== |
| ---- | ---- | ||
| The Transform object can be used as though it were a 2D transformation matrix. In this case the interface for setting/ | The Transform object can be used as though it were a 2D transformation matrix. In this case the interface for setting/ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| Use the " | Use the " | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_rotation({" | t.set_rotation({" | ||
| Line 168: | Line 167: | ||
| s = Transform(a) # works fine | s = Transform(a) # works fine | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| The interface is more or less identical to the 3D case | The interface is more or less identical to the 3D case | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_trans(1, | t.set_trans(1, | ||
| Line 178: | Line 177: | ||
| s = Transform(" | s = Transform(" | ||
| </ | </ | ||
| - | ===== Setting/ | + | ==== Setting/ |
| For getting the parameters in 2D form use the following | For getting the parameters in 2D form use the following | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 187: | Line 186: | ||
| s = Transform(d) # s is the same as t | s = Transform(d) # s is the same as t | ||
| </ | </ | ||
| - | ===== A Transform multiplied by a Vec2f ===== | + | ==== A Transform multiplied by a Vec2f ==== |
| - | The transformation of a 2D vector | + | The transformation of a 2D vector $$ v_{2D} = (v_x,v_y)^T $$ by a Transform is equivalent to setting the z component of 3D vector to 0. If $$ v = (v_x, |
| - | < | + | $$ Tr \mathbf{v_{2D}} |
| and the z component is ignored. Note that the internal implementation is efficient. 2D vector transformation can be done in Python using the following | and the z component is ignored. Note that the internal implementation is efficient. 2D vector transformation can be done in Python using the following | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 201: | Line 200: | ||
| v_transformed = t.transform(v) # can also do it this way if you prefer | v_transformed = t.transform(v) # can also do it this way if you prefer | ||
| </ | </ | ||
| - | ===== Transforming a 2D image ===== | + | ==== Transforming a 2D image ==== |
| Transforming a 2D image is achieved using a single function call | Transforming a 2D image is achieved using a single function call | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 212: | Line 211: | ||
| You can alternatively use the EMData processing framework, for example: | You can alternatively use the EMData processing framework, for example: | ||
| - | <code>#!python | + | <code python> |
| t = Transform() | t = Transform() | ||
| t.set_params({" | t.set_params({" | ||
| Line 222: | Line 221: | ||
| Note that if you try to transform a 2D image using a Transform that contains 3D rotations or translations you will get an error: | Note that if you try to transform a 2D image using a Transform that contains 3D rotations or translations you will get an error: | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| a = test_image() # 2D | a = test_image() # 2D | ||
| Line 229: | Line 228: | ||
| a.transform(t) # ERROR is thrown | a.transform(t) # ERROR is thrown | ||
| </ | </ | ||
| - | << | ||
| - | ====== A more in depth look at the dictionary constructor | + | ===== A more in depth look at the dictionary constructor ===== |
| ---- | ---- | ||
| The dictionary constructor, | The dictionary constructor, | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| t = Transform({" | t = Transform({" | ||
| Line 241: | Line 239: | ||
| If any of the angles or not specified they are implicitly set to 0 | If any of the angles or not specified they are implicitly set to 0 | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| t = Transform({" | t = Transform({" | ||
| Line 247: | Line 245: | ||
| If no euler type is specified then the rotation matrix is the identity | If no euler type is specified then the rotation matrix is the identity | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| </ | </ | ||
| Similarly if any of the translation parameters are not specified they are implicitly set to 0 | Similarly if any of the translation parameters are not specified they are implicitly set to 0 | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| t = Transform({" | t = Transform({" | ||
| Line 258: | Line 256: | ||
| If scale is not specified it is by default 1.0, similarly if mirror is not specified it is be default False | If scale is not specified it is by default 1.0, similarly if mirror is not specified it is be default False | ||
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| </ | </ | ||
| - | << | ||
| - | ====== A more in depth look at set_params | + | ===== A more in depth look at set_params ===== |
| ---- | ---- | ||
| Constructing a Transform with some dictionary is the same as calling set_params on a Transform that is the identity. | Constructing a Transform with some dictionary is the same as calling set_params on a Transform that is the identity. | ||
| - | <code>#!python | + | <code python> |
| d = {" | d = {" | ||
| t = Transform(d) # t is initialized as the identity and then set_params(d) is called internally | t = Transform(d) # t is initialized as the identity and then set_params(d) is called internally | ||
| Line 275: | Line 272: | ||
| The main difference between calling set_params explicitly on a Transform as opposed to constructing a Tranform with a dictionary lies in the fact that the construction method first sets the Transform object to the identity before calling set_params. So if calling the set_params function on a Transform that has already been initialized and had many things done than you should be aware of the following... | The main difference between calling set_params explicitly on a Transform as opposed to constructing a Tranform with a dictionary lies in the fact that the construction method first sets the Transform object to the identity before calling set_params. So if calling the set_params function on a Transform that has already been initialized and had many things done than you should be aware of the following... | ||
| - | ===== If unspecified, | + | ==== If unspecified, |
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| d = {" | d = {" | ||
| t.set_params(d) # t still has the same rotation, scale and mirror but it has an updated translation | t.set_params(d) # t still has the same rotation, scale and mirror but it has an updated translation | ||
| </ | </ | ||
| - | ===== For rotation and translation, | + | ==== For rotation and translation, |
| - | <code>#!python | + | <code python> |
| t = Transform({" | t = Transform({" | ||
| d = {" | d = {" | ||
eman2/transforminpython.1750362982.txt.gz · Last modified: by steveludtke
