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:
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 mkdir OUTPUTS 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) \ justinblaber/b0_atlas_coreg:1.0.0
Or, for singularity:
singularity run -e \ -B INPUTS/:/INPUTS \ -B OUTPUTS/:/OUTPUTS \ shub://justinblaber/b0_atlas_coreg_app:1.0.0
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.