Registration Practical


Practical Overview


For this practical, please move into the appropriate data directory first and perform all commands in that directory.

cd ~/fsl_course_data/reg


Intra-subject Registration



We start by using FLIRT for image-to-image registration within a single subject. The images we start with are of a different modality (T1-weighted and T2-weighted), and are called sub2_t1 and sub2_t2.
  1. Apply BET before FLIRT
    Apply BET to the images sub2_t1 and sub2_t2 (saving the results as sub2_t1_brain and sub2_t2_brain). Check the outputs in FSLView:
    fslview sub2_t1 sub2_t1_brain
    Note that these do not need to be "perfect" but should have removed the majority of the non-brain structures without removing any of the brain material. It doesn't matter if there are some differences between them, especially around the eyeballs.

  2. Registration using the FLIRT GUI
    Start the FLIRT GUI (using "Flirt &" or "Flirt_gui &") and register sub2_t2_brain (input image) to sub2_t1_brain (reference image). Note that to make the file browser for the reference image go to the local directory (and not the directory containing the template images) just erase the contents of the "Filter" box (at the top) and press return.

    Choose 6 DOF (which is not the default) since these images are from the same subject, and check that Correlation Ratio is the selected cost function (from the "Advanced Options" - it should be the default) as the images are different modalities.

    Select an output image name of your choice then press "Go". This will take a few minutes to run... (make sure you look in your terminal window, as this should initially show the command line call to flirt, and after this it will display the message "Finished" when things are done - so look for this)

  3. While you wait...
    Load the input and reference volumes into FSLView (note that this is normally not possible as FSLView requires the same resolution and FOV, which this pair just happens to have but which is not typical). Once these are loaded, try to see the difference by flicking between them: that is, by turning the "top" one off and on (i.e. making them visible or not in the image list - by changing the "eye" symbol).

  4. Visual Check - FSLView
    Once FLIRT has finished, add the resulting transformed image (output) to FSLView. Compare it to the reference image and the input image. Try to see the differences by flicking between pairs of images. Make sure that you only have two of them visible at any one time or it can get very confusing.

    Flicking between images is a very good way of detecting registration differences and changes. Another option is to open two ortho-views within FSLView and use the linked cursor to explore them. To detect subtle changes the flicking method is usually far better.

  5. Visual Check - slices
    Now use slices to look at the result (the file output_image or whatever you have called it instead) by running:
    slices output_image sub2_t1_brain
    The red lines are edges generated from the second image (sub2_t1_brain) and should be aligned with changes in intensity in the output image, although sometimes they will show small differences in the BET masking around the outer brain surface.


Inter-subject Registration


The objective of this practical is to try to register an image of one subject to standard space with both affine (FLIRT) and non-linear (FNIRT) methods. We will work with an older subject that has slightly enlarged ventricles compared to the standard brain, and hence we expect it to be advantageous to use non-linear registration.
  1. Registration command (FLIRT)
    We will now use the command-line version of FLIRT as an exercise, even though the GUI could also be used. With the command-line version of FLIRT we will register old_subj to the standard space, but first we need to skull strip it. Run
    bet old_subj old_brain -f 0.35
    and take a look at the output to make sure it is acceptable. Remember that we do not need the brain extraction to be "perfect" but large errors need to be avoided.

    Then we want to run FLIRT, linearly registering old_subj to the standard space so that we can supply FNIRT with a good initial guess. We do this, using 12 DOF and the Correlation Ratio cost function, with the command

    flirt -in old_brain -ref $FSLDIR/data/standard/MNI152_T1_2mm_brain -dof 12 -cost corratio -out flirted_old_brain -omat old_subj_to_MNI152.mat

    Note: this call must be typed as a single line, and the standard image is not in the course data directory but can be found in $FSLDIR/data/standard (type "ls $FSLDIR/data/standard" to see the contents of this directory).

    You should also note that we used $FSLDIR/data/standard/MNI152_T1_2mm_brain as our -ref, i.e. we register our skull-stripped brain to a skull-stripped template.

    To see the full range of command-line options just type "flirt". If this looks hard, you can also look at the command-line calls that the GUIs made in the previous examples.

  2. Visual check
    When Flirt is finished (a couple of minutes) load the output and reference volumes into FSLView (the reference, MNI152_T1_2mm_brain, can be loaded most easily using the "Add Standard ..." option from the "File" menu). Once these are loaded, try to see the difference by flicking between them. See if the registration has worked well.

    Note that affine registration to standard space is never "perfect", but should get major features such as the brainstem and brain outline quite close. Variation in the population is expected and is reflected in the blurring of structures within the standard (average) brain - although this standard brain was produced with non-linear registration and is less blurred than the affine version MNI152lin_T1_2mm. However, in this case the image is of an older subject and the enlarged ventricles will not fit perfectly with the standard brain.

  3. Transformation Matrix
    When running FLIRT we also saved a transformation matrix which we called old_subj_to_MNI152.mat (the argument to the -omat parameter). Look at this transformation matrix (it is a text file) using
    cat old_subj_to_MNI152.mat
    from the terminal window. It should be a 4 by 4 array of numbers, as described in the lecture.

    Let us also put it (the transformation matrix) to use straight away by transforming the original (non-skull-stripped) image with the same transform. Run the command
    flirt -in old_subj -ref $FSLDIR/data/standard/MNI152_T1_2mm_brain -out flirted_old_subj -applyxfm -init old_subj_to_MNI152.mat
    This means we will now have two images (flirted_old_brain and flirted_old_subj), both transformed into the same space. Note that the -ref option here is used to decide the size and resolution of the output image; the intensities inside that image are not used, but the number and size of the voxels are.

  4. Registration command (FNIRT)
    Now we will look at non-linear registration of old_subj to MNI152_T1_2mm. Note that FNIRT is more sensitive to errors in brain extraction so we do not use the BET output nor do we register it to the skull stripped template, as it deals with non-brain tissue via a cost-function weighting mask in the standard space.

    Running FNIRT takes around 20 minutes, so this has already been done using the following command (do not run this now):
    fnirt --in=old_subj --aff=old_subj_to_MNI152.mat --config=T1_2_MNI152_2mm.cnf
    --cout=coef_old_subj_to_MNI152 --iout=fnirted_old_subj --jout=jac_old_subj_to_MNI152 --jacrange=0.1,10

    FNIRT actually takes a large number of parameters but here we have used the configuration file T1_2_MNI152_2mm.cnf to specify most of these for us. The configuration file is simply a text file that contains many of the parameters that FNIRT takes (and values for them). This enables us to come up with a set of parameters that works well for matching a T1-weighted structural scan to the MNI152 T1-weighted standard brain and other common uses. You may see the parameters that were used by typing
    cat $FSLDIR/etc/flirtsch/T1_2_MNI152_2mm.cnf
    The sight of that may convince you that configuration files are quite useful, and that unless you know exactly what you are doing you should use existing configurations. FSL comes with configuration files for doing things like matching T1 structural images to the MNI152 T1 standard brain (T1_2_MNI152_2mm.cnf) and for matching FA-images to the FMRIB58 FA standard brain (FA_2_FMRIB58_1mm.cnf). In the example above we have restricted the Jacobian-determinant (see below) to be in a more narrow range than is normally the case (default 0.01,100). We do this to facilitate calculating the inverse of the field later in the practical.

    Note that the FNIRT command requires that you specify the FLIRT matrix (old_subj_to_MNI152.mat) that we generated previously. If you forget that you will most likely get poor results and may spend a long time trying to figure out why - like we did when preparing this practical. :-(

    Also note that a registration always implies registering one image (typically -i or --in in FSL applications) to another. In the fnirt command above we can see that we want to register the image old_subj, but to what? The --ref image is in this case specified in the configuration file and if you performed the cat command above you will have seen on the first row --ref=/usr/local/fsl/data/standard/MNI152_T1_2mm.

  5. Visual Check (images)
    Load flirted_old_subj, fnirted_old_subj and MNI152_T1_2mm into fslview (Note that the last image can be added with "Add standard..."). Flip between the registered images and the template to see how well they match. It can also be interesting to flip back and forth between the linearly (flirted_old_subj) and the non-linearly (fnirted_old_subj) registered images. That may convince you that FNIRT has actually been quite gentle with your images, and on the whole the warps are relatively small and well behaved. It will appear as if the 2 images have a different smoothness, as they have had different interpolations applied to them with the different tools, but ignore that for now (they could be made the same by applying each transformation with applywarp if desired).

  6. Deformation Field
    The output file coef_old_subj_to_MNI152 is not a normal image but is a special coefficient file format used by FNIRT, which is used to store the deformation field (also called a warpfield). It also contains the information that we passed from FLIRT to FNIRT (i.e. the information in old_subj_to_MNI152.mat). You can view it (the coefficients) using fslview, but chances are that you will not feel much the wiser.

    To view the deformation field itself it is necessary to convert the coefficients stored in coef_old_subj_to_MNI152 into fields. This is done using the command fnirtfileutils to change it into a vector image. Run the command

    fnirtfileutils --in=coef_old_subj_to_MNI152 --ref=$FSLDIR/data/standard/MNI152_T1_2mm --out=field_old_subj_to_MNI152_nonlinear_only

    This will produce a field (field_old_subj_to_MNI152_nonlinear_only) containing only the non-linear part of the warp, i.e. not including the affine part of the transform. This is useful for visual inspection since the non-linear part tends to be overshadowed by the affine component, making it difficult to interpret what one sees.

    Now run the command

    fnirtfileutils --in=coef_old_subj_to_MNI152 --ref=$FSLDIR/data/standard/MNI152_T1_2mm --withaff --out=field_old_subj_to_MNI152

    The field (field_old_subj_to_MNI152) will now contain both the affine and non-linear components, which is necessary if we want to use them with other tools; e.g. convertwarp or invwarp.

  7. Visual Check (deformation field)
    Now view the deformation field (use field_old_subj_to_MNI152_nonlinear_only for visual inspection) in fslview. Note that it is a 4D image, with three images in the fourth dimension. These correspond to x-displacements (Volume 0), y-displacements (Volume 1) and z-displacements (volume 2). You will often need to adjust the scaling of these images since fslview determines it from the first volume only. The values you observe when you click in the images are displacements (c.f. the little arrows in the lecture) in units of mm.

    If you are doing well for time (this is a bit less than half-way through the practical) you can actually see "those arrows" by turning on "Display as Lines" in the "DTI display options" in fslview (from the "i" pop-up menu). They appear more clearly if you zoom in on a portion of the image. Although they are typically difficult to interpret, they can be quite decorative in a "haystacky" kind of way.

  8. Jacobian of deformation field (degree of expansion/compression)
    The Jacobian determinants of the deformation fields are often more useful for viewing than the deformation fields themselves. When we ran FNIRT we used --jout=jac_old_subj_to_MNI152 (see above if you have forgotten) to specify that we wanted the Jacobian determinants (one per voxel) written to the file jac_old_subj_to_MNI152.

    Had we forgotten that we could still have generated the Jacobians at a later stage with the command

    fnirtfileutils --in=coef_old_subj_to_MNI152 --ref=$FSLDIR/data/standard/MNI152_T1_2mm --jac=jac_old_subj_to_MNI152

    The Jacobian field is useful for checking what liberties FNIRT has been taking with your data. The interpretation of the Jacobian is "voxelwise relative volume change" between the original (in our case old_subj) and the warped (in our case fnirted_old_subj) image. A jacobian of 5 indicates that a volume in the original image has been shrunk by a factor of 5 (e.g. 1mm3 -> 0.2mm3). In general we don't want the Jacobian to be either too small or too large since it seems reasonable that a "function" that exists in both brains should be "implemented" in approximately equal amounts of brain tissue. To check this load jac_old_subj_to_MNI152 into fslview (you might need to change the display range to be something like 0 to 3) and then click Tools->Image Histogram.

    It (the Jacobian) is also useful in its own right, and is an important carrier of information e.g. in VBM. Look again at the Jacobian field and try to work out where the main volume changes has occurred. One area is around the ventricles, which we expected. Can you see any other areas?



Applying and Inverting Transformations

The objective of this part of the practical is to become familiar with applying transformations in FLIRT and FNIRT, as well as using their inverses.
  1. Applying a transform (FLIRT)
    We are goint to apply the same linear transform that we calculated previously, but use it to resample our data (image) to a higher resolution. We do that with the command
    flirt -in old_subj -ref $FSLDIR/data/standard/MNI152_T1_1mm -out highres_flirted_old_subj -applyxfm -init old_subj_to_MNI152.mat
    Note that the important thing here is that we have specified a different -ref scan, one with a different resolution and matrix size.

  2. Applying a transform (FNIRT)
    Now we are going to do the same thing with a non-linear transform. For that we will use the applywarp application. Issue the command
    applywarp -i old_subj -r $FSLDIR/data/standard/MNI152_T1_1mm -o highres_fnirted_old_subj -w coef_old_subj_to_MNI152
    Again we are using the same transform, but resampling onto a -ref scan with higher resolution and different matrix size.

  3. Visual Check
    Use the command
    fslview $FSLDIR/data/standard/MNI152_T1_1mm highres_flirted_old_subj highres_fnirted_old_subj
    to again compare the linear and non-linear registration, this time with final images of higher resolution.

  4. Creating an inverse transform (FLIRT)
    Find the inverse of the transformation matrix found previously that registered sub2_t2_brain to sub2_t1_brain
    The inverse can be found using the InvertXFM (GUI).

  5. Applying a transform (FLIRT), part 2
    We are now going to use the inverse transform we just created (referred to as inv_matrix.mat here, but it can be whatever you decided to call it) to map sub2_t1_brain onto sub2_t2_brain. Note that this is the opposite mapping compared to what we did above. We do that with the command
    flirt -applyxfm -init inv_matrix.mat -in sub2_t1_brain -ref sub2_t2_brain -out sub2_t1_brain_to_t2_brain
    Note that sub2_t2_brain is treated as the reference (determining output size) in this case. Issue the command
    fslview sub2_t2_brain sub2_t1_brain_to_t2_brain
    to check the results.

  6. Creating an inverse transform (FNIRT)
    The inverse of a non-linear transformation can be found using the command-line tool: invwarp
    This is a slow process (it can even be slower than running FNIRT directly!) and so the following command has already been run and the output saved:
    invwarp --warp=coef_old_subj_to_MNI152 --ref=old_subj --out=field_MNI152_to_old_subj
    where the output file is called field_MNI152_to_old_subj.

    Note that the transform in field_MNI152_to_old_subj is that which maps our template (i.e. $FSLDIR/data/standard/MNI152_T1_2mm) onto our individual brain (old_subj).

  7. Applying a transformation (FNIRT), part 2
    We are now going to use applywarp to resample the template $FSLDIR/data/standard/MNI152_T1_2mm onto our individual brain old_subj. We do this with the command
    applywarp --ref=old_subj --in=$FSLDIR/data/standard/MNI152_T1_1mm --out=MNI152_fnirted_to_old_subj --warp=field_MNI152_to_old_subj

    View the results with the command
    fslview old_subj MNI152_fnirted_to_old_subj


Fieldmap-based Unwarping with FUGUE


The objective of this section of the practical is to perform fieldmap-based unwarping of functional (EPI) images using the pre-stats options in FEAT. An example session with a raw fieldmap and functional series is in the feat_example subdirectory. Change to this directory now:

cd ~/fsl_course_data/reg/feat_example

  1. Functional Data
    For this practical we have extracted the first 20 timepoints from a real functional experiment just in order to demonstrate the FUGUE unwarping options in the pre-stats (we will not proceed to find activations - that's another practical!)

    The functional data is called epi.nii.gz.

    The first thing to do now is to LOOK AT THE DATA. Do this by loading it into FSLView and running the movie mode. Explore the data by moving the cursor around, looking at intensities, etc. There should be no obvious scanner artefacts but some motion effects should be clear (especially near the brainstem).

  2. Starting the FEAT GUI
    Type     Feat &
    (Feat_gui &     on Mac)

  3. Enter the Functional Data

    Now enter the functional images by clicking on the Select 4D data button (don't just type "epi.nii.gz" in the file select popup or you probably won't end up setting the full pathname; use the file-select icon on the right to select the input data).

    Once you have done this successfully FEAT should automatically set the correct number of volumes or timepoints (20 in this case).

  4. Select Pre-Stats
    Now use the pull down menu on the top right (should initially be set to "Full Analysis") and change it "Pre-Stats". This will mean that only the pre-stats processing is applied and no further analysis is done.

  5. Setup Pre-Stats
    At this point select the "Pre-Stats" tab and then set the "B0 unwarping" option. This will create a set of fields that you need to fill in, as shown in the lecture.

  6. Entering values

  7. Set up Registration
    Finally, select the "Registration" tab and enter the image struct_brain (from inside the feat_example directory) as the "Main structural image" with 7 DOF chosen. For reasons of speed, de-select the "standard space" image (and "Initial structural image" if it happens to be set) - as we are only interested in the functional to structural registration at this point.

  8. Run the Pre-stats
    Once the pre-stats and registration tabs have been set up press the "Go" button at the bottom. This will create a new web browser window where you can monitor the progress, showing the individual commands that are executed and where to find the results (list of links at the top - for us the "pre-stats" is the interesting link). It should only take a few minutes to finish.

  9. View the FEAT Results
    Once FEAT is finished open the "pre-stats" results (by clicking on the link at the top of the web broswer window). Alternatively, you can find the required html files in the output directory, which will have the name epi.feat (if you got it right first time, or epi+.feat, epi++.feat, ... if you ran it twice, or three times, etc.)

    On the pre-stats report page there are many images which we will now examine:

    Now look at the results of the functional to structural image registration by clicking on the "Registration report" link on the main FEAT report page (up one from the unwarping report page). The images here show the registrations as red lines taken from the edges of one image overlayed on the greyscale backdrop of the other image. This is also done for the non-unwarped functional in order to see the relative improvement (hopefully) of the unwarping procedure. Check that the registration is in fact better when this correct unwarping is done.

  10. Change the Unwarp Direction
    Go back to the FEAT GUI (or if you shut it down just start it again and set up all the values as before - but don't press go just yet!)

    In the pre-stats tab, change the "unwarp direction" to "-y" instead of "y". Re-run FEAT and examine the results (these will be in a directory named epi+.feat, or epi++.feat etc.)

    You should notice that the distortion correction is now run in the wrong direction and that the "undistorted" image looks more distorted (and less like the non-distorted magnitude image) than the original distorted example_func did. The movie should also show a more dramatic transition from the "undistorted" functional to the fieldmap magnitude image than it does the other way around.

    It is usually necessary to try both positive and negative directions when collecting fieldmap and functional images for the first time on a given system with a given protocol. Once you have determined the correct sign of the unwarp direction you can then use this with all subsequent images from this protocol.

  11. Change the Echo Spacing (optional)
    Go back to the FEAT GUI again and change the echo spacing to a value five times as large. Re-run FEAT and look at the results. This clearly shows how important getting the correct echo spacing is!

    Note for the technically-minded: the echo spacing is equal to the amount of time taken to go from the centre of one line of k-space to the centre of the next line in the EPI readout. It is influenced by many sequence parameters (such as ramp sampling) and cannot be calculated without a detailed knowledge of the particular EPI sequence implementation, but a scanner operator or physicist should be able to quote it for any given EPI sequence used. In the case of parallel acquisitions the "effective" echo spacing is normally the actual echo spacing divided by the acceleration factor.



Standard-space masking - a useful application (optional)

cd ~/fsl_course_data/reg


Now let's use a saved FLIRT transform to mask out the ventricles, cerebellum and brain stem in example_func, using a crude standard-space mask which excludes those regions.
The registration from example_func to the standard-space template has already been done and is saved as exfunc2std.mat. We want to take this matrix and transform a standard-space mask to the functional space.

First invert the transform exfunc2std.mat with:
convert_xfm -omat std2exfunc.mat -inverse exfunc2std.mat
or, alternatively, use the InvertXFM GUI (note that this is InvertXFM_gui if you are on a Mac).

Then transform the standard-space mask $FSLDIR/data/standard/MNI152_T1_2mm_strucseg_periph into the space of example_func using flirt with -applyxfm and -init as above, calling the output lowresmask

View the result with FSLView.

We will also need to "binarise" the mask, i.e. make sure that is consists only of ones and zeros (because the transformation above will have introduced values between zero and one). The command
fslmaths lowresmask -thr 0.5 -bin lowresmask
will first set all values below 0.5 to 0 and then set all values above 0.5 to 1.

Now apply this mask using:
fslmaths example_func -mas lowresmask masked_example_func
and view the result. Note that FSLView will use a colour lookup table for this image by default as it has "mask" in the name - however it is probably better to view it in greyscale, so change the colour lookup table.

Can you think of an easy way of masking out the left side of the brain, even if the head appears "skewed" in the original image?


Partial FOV Registration (optional)

cd ~/fsl_course_data/reg

The objective of this practical exercise is to use FLIRT for registering small FOV images. This will involve the use of schedule files and initialised transforms without search which is also very useful for cases of difficult image registration.

  1. Small FOV Registration
    For partial FOV images an initial translation alignment can be found using the schedule xyztrans.sch (found in $FSLDIR/etc/flirtsch)
    Apply this schedule to register partial_brain to whole_brain and save the transformation matrix to partial2whole.mat using:

    flirt -in partial_brain -ref whole_brain -schedule $FSLDIR/etc/flirtsch/xyztrans.sch -omat partial2whole.mat -out partial2whole

  2. Visual Check
    Inspect the result - note that the transformation here is 3 DOF (translation only).
    This is necessary to limit the flexibility, since there is insufficient data to easily obtain a good fit with more DOF.

  3. Fine Adjustments using Initialisation
    By using the previous translation as a starting point, a fine adjustment in 3D can be made to the transformation above using:

    flirt -in partial_brain -ref whole_brain -dof 6 -out partial2wholeB -omat partial2wholeB.mat -init partial2whole.mat -nosearch

    Note the use of the two options: -init and -nosearch
    The -init option (when separate from -applyxfm) uses the specified transformation as a starting point and -nosearch turns off the large-scale search for the global minimum which is necessary when the registration is ill-constrained as it is for small FOV.

  4. Visual Check
    Inspect the result of the fine adjustment and compare it to the previous translation-only result.
    Is this an improvement?
    Note that a small FOV image that is "tilted" will have an arbitrary cutoff line running across its top and bottom slices. This is normal and a natural consequence of a trying to show a tilted, small FOV on top of a larger image. Therefore do not judge the performance based on this, but instead look at the anatomical features in the images and how well they match.


Getting to Know the Transformation Matrix (optional)

  1. Decomposing the Transformation Matrix
    Run avscale exfunc2std.mat and find the scaling values. This information is extracted from the transformation matrix and shows that some scaling (value different from 1.0) was necessary to align the images well.

    Note that this command is also useful for finding other information about the transformation matrix, such as rotation angles, translations and skews as well as the forward and backward half transformations (which are useful to take images into a "halfway" space which equalises interpolation artefacts).