This shows you the differences between two versions of the page.

Both sides previous revision Previous revision | |||

mrtools:coordinatetransforms [2009/11/04 05:55] justin |
mrtools:coordinatetransforms [2020/02/04 22:54] (current) justin |
||
---|---|---|---|

Line 34: | Line 34: | ||

The transformation from image coordinates to magnet coordinats is done by multiplying the 4x4 affine transformation matrix specified by the Qform times the image coordinates [X<sub>img</sub> Y<sub>img</sub> Z<sub>img</sub>]: | The transformation from image coordinates to magnet coordinats is done by multiplying the 4x4 affine transformation matrix specified by the Qform times the image coordinates [X<sub>img</sub> Y<sub>img</sub> Z<sub>img</sub>]: | ||

- | <html> | + | $$ \left\lgroup\matrix{x_{mag}\cr y_{mag}\cr z_{mag}\cr1\cr}\right\rgroup |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{x_{mag}\cr y_{mag}\cr z_{mag}\cr1\cr}\right\rgroup | + | |

= \left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr | = \left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr | ||

rs_{21}& rs_{22} &rs_{23} &t_{y_{mm}}\cr | rs_{21}& rs_{22} &rs_{23} &t_{y_{mm}}\cr | ||

rs_{31}& rs_{32} &rs_{33} &t_{z_{mm}}\cr | rs_{31}& rs_{32} &rs_{33} &t_{z_{mm}}\cr | ||

0 & 0 &0 &1\cr}\right\rgroup. | 0 & 0 &0 &1\cr}\right\rgroup. | ||

- | \left\lgroup\matrix{x_{img}\cr y_{img}\cr z_{img}\cr1\cr}\right\rgroup | + | \left\lgroup\matrix{x_{img}\cr y_{img}\cr z_{img}\cr1\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

The Qform above is composed of a 3x3 portion that rotates and scales (specified by the rs's) and a 3x1 portion that translates (specified by the t's). Note that the coordinates have been made into **homogeneous** coordinates. This means that they have an added 1. This is a trick, the purpose of which is to allow us to do the translation and rotation in a single matrix multiplication. | The Qform above is composed of a 3x3 portion that rotates and scales (specified by the rs's) and a 3x1 portion that translates (specified by the t's). Note that the coordinates have been made into **homogeneous** coordinates. This means that they have an added 1. This is a trick, the purpose of which is to allow us to do the translation and rotation in a single matrix multiplication. | ||

Line 49: | Line 45: | ||

The above Qform is really the combination of three transformations. A translation which specifies the distance in number of voxels to the center of the voxel at location [1 1 1]. A scaling which specifies the distance in mm between centers of voxels (this is usually the same as your voxel dimensions, unless, for instance, you put a gap between slices). And a rotation around the center of the bore of the magnet. | The above Qform is really the combination of three transformations. A translation which specifies the distance in number of voxels to the center of the voxel at location [1 1 1]. A scaling which specifies the distance in mm between centers of voxels (this is usually the same as your voxel dimensions, unless, for instance, you put a gap between slices). And a rotation around the center of the bore of the magnet. | ||

- | <html> | + | $$ \left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr | + | |

rs_{21}& rs_{22} &rs_{23} &t_{y_{mm}}\cr | rs_{21}& rs_{22} &rs_{23} &t_{y_{mm}}\cr | ||

rs_{31}& rs_{32} &rs_{33} &t_{z_{mm}}\cr | rs_{31}& rs_{32} &rs_{33} &t_{z_{mm}}\cr | ||

Line 66: | Line 60: | ||

0 &1 &0 &t_{y_{img}}\cr | 0 &1 &0 &t_{y_{img}}\cr | ||

0 &0 &1 &t_{z_{img}}\cr | 0 &0 &1 &t_{z_{img}}\cr | ||

- | 0 & 0 &0 &1\cr}\right\rgroup | + | 0 & 0 &0 &1\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

The units of the t<sub>ximg</sub> are in voxels, the s's are in mm and the t<sub>mm</sub> are in mm in the rotated reference frame. | The units of the t<sub>ximg</sub> are in voxels, the s's are in mm and the t<sub>mm</sub> are in mm in the rotated reference frame. | ||

Line 74: | Line 66: | ||

There is one little hitch with this. The Qform specifies the transformation where the image coordinates specify the origin as (0,0,0) rather than (1,1,1) which is what Matlab uses. So, actually to get into the coordinates of the magnet from the coordinates in the image, you need to shift the origin by -1 first: | There is one little hitch with this. The Qform specifies the transformation where the image coordinates specify the origin as (0,0,0) rather than (1,1,1) which is what Matlab uses. So, actually to get into the coordinates of the magnet from the coordinates in the image, you need to shift the origin by -1 first: | ||

- | <html> | + | $$ \left\lgroup\matrix{x_{mag}\cr y_{mag}\cr z_{mag}\cr1\cr}\right\rgroup |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{x_{mag}\cr y_{mag}\cr z_{mag}\cr1\cr}\right\rgroup | + | |

= | = | ||

\left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr | \left\lgroup\matrix{rs_{11}& rs_{12} &rs_{13} &t_{x_{mm}}\cr | ||

Line 86: | Line 76: | ||

0& 0 &1 &-1\cr | 0& 0 &1 &-1\cr | ||

0& 0 &0 &1\cr}\right\rgroup. | 0& 0 &0 &1\cr}\right\rgroup. | ||

- | \left\lgroup\matrix{x_{img}\cr y_{img}\cr z_{img}\cr1\cr}\right\rgroup | + | \left\lgroup\matrix{x_{img}\cr y_{img}\cr z_{img}\cr1\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

But, this is a detail. So we'll ignore it below. | But, this is a detail. So we'll ignore it below. | ||

Line 102: | Line 90: | ||

The Qform of the inplane (Qform<sub>inplane</sub>) transforms into the magnet coordinates and the **inverse** of the Qform<sub>EPI</sub> takes you from the magnet coordinates to the EPI image coordinates: | The Qform of the inplane (Qform<sub>inplane</sub>) transforms into the magnet coordinates and the **inverse** of the Qform<sub>EPI</sub> takes you from the magnet coordinates to the EPI image coordinates: | ||

- | <html> | + | $$ \left\lgroup\matrix{x_{EPI}\cr y_{EPI}\cr z_{EPI}\cr1\cr}\right\rgroup |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{x_{EPI}\cr y_{EPI}\cr z_{EPI}\cr1\cr}\right\rgroup | + | |

= \left\lgroup\matrix{Qform_{EPI}\cr}\right\rgroup^{-1}. | = \left\lgroup\matrix{Qform_{EPI}\cr}\right\rgroup^{-1}. | ||

\left\lgroup\matrix{Qform_{inplane}\cr}\right\rgroup. | \left\lgroup\matrix{Qform_{inplane}\cr}\right\rgroup. | ||

- | \left\lgroup\matrix{x_{inplane}\cr y_{inplane}\cr z_{inplane}\cr1\cr}\right\rgroup | + | \left\lgroup\matrix{x_{inplane}\cr y_{inplane}\cr z_{inplane}\cr1\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

Note that this does not assume that the inplane and EPI are taken with the same slice prescriptions. Since it uses the Qforms set by the magnet software, it will transform from inplane coordinates to EPI coordinates regardless of how the slices were placed in the inplane and EPI images. That is, as long as the subject didn't move their head in between the scans. | Note that this does not assume that the inplane and EPI are taken with the same slice prescriptions. Since it uses the Qforms set by the magnet software, it will transform from inplane coordinates to EPI coordinates regardless of how the slices were placed in the inplane and EPI images. That is, as long as the subject didn't move their head in between the scans. | ||

Line 128: | Line 111: | ||

mrAlign computes the alignment between the inplane images and the volume images based on trying to find the best match between the two images. A good starting place for this, is to initialize the alignment from the headers, which means to use the Qform information. As noted above this won't give a perfect alignment because the subject's head was in a different location on the two days. But, it's a good starting place and mrAlign will find a good alignment from there. Now, we know the alignment from the inplane to the volume and from the volume to the magnet on the day the volume was taken (Qform<sub>volume</sub>). So, we can compute the transformation from the inplane to the magnet coordinates **as if the head were in the same place on the day we acquired the inplane as the day we acquired the volume**. mrAlign puts that transform into the Sform<sub>inplane</sub>. | mrAlign computes the alignment between the inplane images and the volume images based on trying to find the best match between the two images. A good starting place for this, is to initialize the alignment from the headers, which means to use the Qform information. As noted above this won't give a perfect alignment because the subject's head was in a different location on the two days. But, it's a good starting place and mrAlign will find a good alignment from there. Now, we know the alignment from the inplane to the volume and from the volume to the magnet on the day the volume was taken (Qform<sub>volume</sub>). So, we can compute the transformation from the inplane to the magnet coordinates **as if the head were in the same place on the day we acquired the inplane as the day we acquired the volume**. mrAlign puts that transform into the Sform<sub>inplane</sub>. | ||

- | <html> | + | $$ \left\lgroup\matrix{Sform_{inplane}\cr}\right\rgroup |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{Sform_{inplane}\cr}\right\rgroup | + | |

= \left\lgroup\matrix{Qform_{volume}\cr}\right\rgroup. | = \left\lgroup\matrix{Qform_{volume}\cr}\right\rgroup. | ||

- | \left\lgroup\matrix{Alignment\cr}\right\rgroup | + | \left\lgroup\matrix{Alignment\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

So, the Sform contains the transformation of an image into the magnet space as if the head were in the same place as the day that the volume anatomy was taken. The Sform<sub>volume</sub> is simply set to the Qform<sub>volume</sub> since it already specifies the transformation of the volume coordinates to the magnet coordinates on the day that the volume was taken. (This is what mrAlign does when you set "Set Base Coordinate Frame" in the File menu). | So, the Sform contains the transformation of an image into the magnet space as if the head were in the same place as the day that the volume anatomy was taken. The Sform<sub>volume</sub> is simply set to the Qform<sub>volume</sub> since it already specifies the transformation of the volume coordinates to the magnet coordinates on the day that the volume was taken. (This is what mrAlign does when you set "Set Base Coordinate Frame" in the File menu). | ||

Line 146: | Line 125: | ||

So as long as the Sform is set in the same way, we can now compute the transformation from the inplane image coordinates to the volume coordinates. That is, to find which voxel in the volume ([X<sub>volume</sub> Y<sub>volume</sub> Z<sub>volume</sub>]) the voxel from the inplane image [X<sub>inplane</sub> Y<sub>inplane</sub> Z<sub>inplane</sub>] comes from, the following computation is done: | So as long as the Sform is set in the same way, we can now compute the transformation from the inplane image coordinates to the volume coordinates. That is, to find which voxel in the volume ([X<sub>volume</sub> Y<sub>volume</sub> Z<sub>volume</sub>]) the voxel from the inplane image [X<sub>inplane</sub> Y<sub>inplane</sub> Z<sub>inplane</sub>] comes from, the following computation is done: | ||

- | <html> | + | $$ \left\lgroup\matrix{x_{volume}\cr y_{volume}\cr z_{volume}\cr1\cr}\right\rgroup |

- | <div class="math"> | + | |

- | \left\lgroup\matrix{x_{volume}\cr y_{volume}\cr z_{volume}\cr1\cr}\right\rgroup | + | |

= \left\lgroup\matrix{Sform_{volume}\cr}\right\rgroup^{-1}. | = \left\lgroup\matrix{Sform_{volume}\cr}\right\rgroup^{-1}. | ||

\left\lgroup\matrix{Sform_{inplane}\cr}\right\rgroup. | \left\lgroup\matrix{Sform_{inplane}\cr}\right\rgroup. | ||

- | \left\lgroup\matrix{x_{inplane}\cr y_{inplane}\cr z_{inplane}\cr1\cr}\right\rgroup | + | \left\lgroup\matrix{x_{inplane}\cr y_{inplane}\cr z_{inplane}\cr1\cr}\right\rgroup $$ |

- | </div> | + | |

- | </html> | + | |

You should never actually have to work with the Qforms and Sforms directly, though. If you ever need to explicitly do transformations, you should get the transformation matrices using viewGet. MLR will compute the correct transformations as discussed above using the Sforms. It will also take care of the shift by 1 (to account for Matlab's 1 based numbering system and the Qform/Sform's 0 based numbering system). There are transformations base2scan and scan2scan among many others. If you need the scan2base instead of the base2scan, simply use inv(base2scan). So to transform a coordinate in your base [X Y Z] to find its coordinate in the scan, you would do: | You should never actually have to work with the Qforms and Sforms directly, though. If you ever need to explicitly do transformations, you should get the transformation matrices using viewGet. MLR will compute the correct transformations as discussed above using the Sforms. It will also take care of the shift by 1 (to account for Matlab's 1 based numbering system and the Qform/Sform's 0 based numbering system). There are transformations base2scan and scan2scan among many others. If you need the scan2base instead of the base2scan, simply use inv(base2scan). So to transform a coordinate in your base [X Y Z] to find its coordinate in the scan, you would do: | ||