b0 to T1 atlas coregistration with FSL and ANTS

In this post, I’ll demonstrate how to coregister a b0 (non diffusion weighted EPI image) to a T1 weighted atlas.

Tools and files used in this article:

b0_atlas_coreg_inputs.zip contains a T1 and b0 from the same subject, as well as a T1 weighted MNI atlas, all in the nifti format.

First, it’s important to note that to improve coregistration, the subject’s b0 image should be susceptibility corrected before attempting to coregister it to its T1. The b0 used in this example was corrected via topup using two reverse phase encoded b0 images. Below is the typical pipeline:

1.\ Susceptibility\ distortion\ correction\ (if\ available)
2.\ Coregister\ subject\ b0\ to\ subject\ T1
3.\ Register\ T1\ to\ Atlas
4.\ Apply\ composed\ transforms\ to\ get\ b0\ into\ "atlas\ space"

If you have FSL, ANTS, and the Convert3D tool installed (if not, you can skip ahead and use docker/singularity), then run the following:

wget http://justinblaber.org/downloads/articles/b0_atlas_coreg/b0_atlas_coreg_inputs.zip
unzip b0_atlas_coreg_inputs.zip
bet T1.nii.gz T1_mask.nii.gz -R
epi_reg --epi=b0.nii.gz --t1=T1.nii.gz --t1brain=T1_mask.nii.gz --out=epi_reg
c3d_affine_tool -ref T1.nii.gz -src b0.nii.gz epi_reg.mat -fsl2ras -oitk epi_reg_ANTS.txt
antsRegistrationSyN.sh -d 3 -f atlas.nii.gz -m T1.nii.gz -o ANTS
antsApplyTransforms -d 3 -i b0.nii.gz -r atlas.nii.gz -n BSpline -t ANTS0GenericAffine.mat -t epi_reg_ANTS.txt -o b0_lin_atlas.nii.gz
antsApplyTransforms -d 3 -i b0.nii.gz -r atlas.nii.gz -n BSpline -t ANTS1Warp.nii.gz -t ANTS0GenericAffine.mat -t epi_reg_ANTS.txt -o b0_nonlin_atlas.nii.gz

The above is my current preferred pipeline to do this type of coregistration. In my opinion, I’ve found that epi_reg works best for coregistering a subject’s b0 to its own T1. However, I’ve found that FSL’s nonlinear registration tool, fnirt, is not quite as robust. It works well on some data, but on other data (like HCP data, in my experience) it can fail in non-obvious ways. I’ve found that ANT’s registration is pretty robust, so I’ve opted to use that instead. However, the issue that arises is you need to compose the transforms from FSL and ANTs in order to get the final transform from diffusion space to MNI space. Luckily, c3d_affine_tool can can convert the transforms between these two different formats.

I’ve gone ahead and dockerized/singularized the above. If you’d prefer to go this route, you can do:

mkdir INPUTS
wget http://justinblaber.org/downloads/articles/b0_atlas_coreg/b0_atlas_coreg_inputs.zip -O INPUTS/b0_atlas_coreg_inputs.zip
unzip INPUTS/b0_atlas_coreg_inputs.zip -d INPUTS

Then, for docker:

sudo docker run --rm \
-v $(pwd)/INPUTS/:/INPUTS/ \
-v $(pwd)/OUTPUTS:/OUTPUTS/ \
--user $(id -u):$(id -g) \

Or, for singularity:

singularity run -e \

If everything runs successfully, the output should look like:

Whether or not you need linear or nonlinear registration is application specific. However, if you use the above pipeline, then you can have access to both. If you find antsRegistrationSyN.sh takes too long, then you can substitute it for antsRegistrationSyNQuick.sh instead.

A few things:

Why not directly coregister the b0 to the T1 atlas?

I believe it’s because it’s somewhat “unstable”. epi_reg is “stable” because it enforces a 6-DOF constraint when performing the coregistration between two different modalities. Since it’s the same subject, we can enforce this really strong constraint. Nonrigid registration between the subject T1 and template are relatively stable because the modalities are the same and the resolutions are usually high. Jumping directly from b0 to T1 would require a non-rigid registration with a robust cost function (like mutual information, which fnirt doesn’t even support, although we don’t use it here). Furthermore, the voxel resolution for diffusion is usually much lower than for a T1, so there’s less signal to deal with. Composing the transforms from the two stable registrations just works well in practice.

5 thoughts on “b0 to T1 atlas coregistration with FSL and ANTS”

  1. Dear Justin,

    thank you very much for this very helpful post! The registration worked quite good for my data. Still, I have one question; which procedure would you recommend to apply the deformation field from the warping to all DWI volumes?

    Best regards,


    1. Nonrigid registration of DWMRI directly is typically not done. If you do affine registration you can simply rotate the b-vectors, but if you do nonrigid it would require a a b-vector field with each voxel being corrected individually (i.e. each voxel is rotated a different amount with nonrigid registration). I would try to do all your processing into a scalar value (like FA map) per voxel then map that to the template if possible.

  2. Hello sir,
    The detailed explanation of your pipeline was very helpful.
    I found the registration results by ANTS to be visually quite superior, compared to those produced by FSL.

    Thus, I want to extend this pipeline so I can get a pair of combinational transform functions from ANTS, for going from diffusion to MNI, and vice versa.
    I want to use those functions later in FSL’s ProbTrackX to perform tractography.

    To achieve that, I first tried to convert the affine transformation produced by ANTS to FSL, using c3d_affine_tool.
    I got this error “terminate called after throwing an instance of ‘char const*’
    Aborted (core dumped)”

    Then I tried an alternative route of using FSL’s epi_reg produced .mat file in FSL’s convertwarp function (to combine the affine matrix and the non-linear transform).
    I now get the error “terminate called after throwing an instance of ‘NEWIMAGE::FnirtFileReaderException’
    what(): FnirtFileReader:: msg=FnirtFileReader: Displacement fields must contain 3 volumes
    Aborted (core dumped)”

    Please let me know if you have an insight.
    Thank you!

  3. Dear Justin Blaber,

    I would like to register the FA map (computed after EDDY, TOPUP) to the T1, the T1 to the ICBM space and then combine the warps to use them for the FA map.
    Do you have any recommendations how to do that?

    Best regards,


    1. I would still co-register the b0 to T1 template in the above pipeline, but when you apply the transforms, do it to the FA nifti instead of the B0 nifti. This should get the FA map into template space.

Leave a Reply

Your email address will not be published. Required fields are marked *