Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistency problems with Registration of anatomical images #1816

Open
WesselvEng opened this issue Dec 5, 2024 · 33 comments
Open

Inconsistency problems with Registration of anatomical images #1816

WesselvEng opened this issue Dec 5, 2024 · 33 comments

Comments

@WesselvEng
Copy link

Operating system and version

CentOS Linux 7 (Core)

CPU architecture

x86_64 (PC, Intel Mac, other Intel/AMD)

ANTs code version

ANTs Version: 2.1.0.post370-ga466e

ANTs installation type

Other (please specify below)

Summary of the problem

Hello everybody. So I am using ANTs on a higher performance cluster (torque) at the DCCN in Nijmegen.
I've been trying to register DWI rodent MRI data onto an existing template (DSURQE) to be able to analyse the
FA and MD maps. I'm following the following strategy to achieve that:
For every subject I first register anatomical (T2) image onto a template anatomical image (T2) using antsRegistration and create a
composite transform using ComposeMultiTransform.
Then I register the subject DWI data onto the subject anatomical data. To do this I take the temporal mean of one of
the b0 maps of the DWI data (after corrections, see code) as proxy for the whole DWI image.
I then apply both composite transform on the DWI data, so in practice i register DWI onto anatomical and the resulting
image onto the template, so that my DWI data is registered onto the template.
To improve the processing time I am using masks that I created using an AI program called BEN for all subjects.
These masks I dilate a little using fslmaths so they cover the brain and the surrounding tissue to get a better
brain/no-brain contrast.
Im facing a problem when it comes to the anatomical registrations. With the same ANTs version I am getting very inconsistent
anatomical to template registrations. I've tried doing less non-linear iterations, different metrics for different
transforms but when looking through the documentations I actually can't find what I am really doing wrong
with my parameters. For some subjects an anatomical registration works when I don't use masks, but for other subjects
the anat to template registration then doesn't work anymore. There really is not a thing to point towards that might cause failing of the registration, as far as I know. It feels like some stochasticity causes registrations to work or not. In the I resorted to using older ANTs versions and here some subjects that kept failing seemed to work.
Most subjects had proper anatomical to template registration with an older ANTs version (ANTs/2.1.0.post370-ga466e
).
However for some that didn't work I used ANTs/2.5.1-gb909304 or ANTs/2.5.3-g98bf76d. For all versions I used the exact same script.

Now I am a bit confused as to what could be the reasons that my registration do not work as I expect them to be. There
are some minor quality difference between some subjects, but most of them should be fixed by the preprocessing steps applied
to the anatomical images. It just seems weird to me that for the same subject registration work on older versions of
ANTs but not on newer versions. Therefore I was wondering if this could be caused by faulty functioning of
the ANTs built that I use, faulty quality of my input data or if it is just the nature of working with this kind of data. It really feels like some registrations only work by some stochasticity or something... I was wondering if someone could explain how ANTs exactly handles data and whether these inconsistencies might arise from my side (bad preprocessing or registration parameters, or approach) or that it is something that really is part of ants.

For this specific subject registration with ants/2.1.0 looks like this:
anat2template

and for ants/2.5.3 like this:
anat2template

Commands to reproduce the problem.

Here is the anatomical to template registration call:

antsRegistration 
--dimensionality 3 \
--float 0 \
-a 0 \
-v 1 \
--output reg/anat2std \
--interpolation Linear \
--winsorize-image-intensities [0.005,0.995] \
--use-histogram-matching 0 \
--initial-moving-transform [DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1] \
--transform Rigid[0.1] \
--metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz',1,32,Regular,0.25] \
--convergence [1000x500x250x100,1e-6,10] \
--shrink-factors 8x4x2x1 \
--smoothing-sigmas 3x2x1x0vox \
--transform Affine[0.1] \
--metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,32,Regular,0.25] \
--convergence [1000x500x250x100,1e-6,10] \
--shrink-factors 8x4x2x1 \
--smoothing-sigmas 3x2x1x0vox \
--transform SyN[0.1,3,0] \
--metric CC[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz',1,4] \
--convergence [40x30x15x10,1e-6,10] \
--shrink-factors 8x4x2x1 \
--smoothing-sigmas 3x2x1x0vox  \
--masks [DSURQE_100micron_mask.nii.gz,sub-aRi114_ses-1_T2w_mask_dilated.nii.gz]
ComposeMultiTransform 3 ${anat2temp} -R DSURQE_100micron_average.nii.gz reg/anat2std1Warp.nii.gz reg/anat2std0GenericAffine.mat 

 antsApplyTransforms -i ${anat_noext}'_N4_dn.nii.gz' -r DSURQE_100micron_average.nii.gz -t ${anat2temp} -o ${anat_noext}'_2std.nii.gz'

Output of the command with verbose output.

script_sub-aRi114_output.txt
--> with ants/2.1.0

script_sub-aRi114_output.txt
--> with ants/2.5.3

Data to reproduce the problem

Here is a link to an example of a full script and the full file output for the same subject with different ANTs versions: https://drive.google.com/drive/folders/1Bv2Hkb9N0GpWx60-kG-3HFcWXMOfCldT?usp=sharing

@cookpa
Copy link
Member

cookpa commented Dec 5, 2024

Thanks for the examples. I will try to look when I get time.

From reading the description, I would suggest checking the header info of the problematic images vs ones that work consistently. ANTs 2.1 vs 2.5 has different ITK versions, and ITK has changed the way it handles NIFTI headers. So data that has different sform or qform parameters can behave differently on different versions.

https://github.com/ANTsX/ANTs/wiki/How-does-ANTs-handle-qform-and-sform-in-NIFTI-1-images%3F

@WesselvEng
Copy link
Author

Thanks for the examples. I will try to look when I get time.

From reading the description, I would suggest checking the header info of the problematic images vs ones that work consistently. ANTs 2.1 vs 2.5 has different ITK versions, and ITK has changed the way it handles NIFTI headers. So data that has different sform or qform parameters can behave differently on different versions.

https://github.com/ANTsX/ANTs/wiki/How-does-ANTs-handle-qform-and-sform-in-NIFTI-1-images%3F

Thanks for your quick reply! I checked the nifit headers from my mask and anat files with fslhd. From the anatomical i got this:

qform_name	Scanner Anat
qform_code	1
qto_xyz:1	0.141667 -0.000000 0.000000 -7.881513 
qto_xyz:2	0.000000 0.500000 -0.000000 -2.942948 
qto_xyz:3	0.000000 0.000000 0.150000 -1.922426 
qto_xyz:4	0.000000 0.000000 0.000000 1.000000 
qform_xorient	Left-to-Right
qform_yorient	Posterior-to-Anterior
qform_zorient	Inferior-to-Superior
sform_name	Scanner Anat
sform_code	1
sto_xyz:1	0.141667 -0.000000 -0.000000 -7.881513 
sto_xyz:2	-0.000000 0.500000 -0.000000 -2.942948 
sto_xyz:3	0.000000 0.000000 0.150000 -1.922426 
sto_xyz:4	0.000000 0.000000 0.000000 1.000000 
sform_xorient	Left-to-Right
sform_yorient	Posterior-to-Anterior
sform_zorient	Inferior-to-Superior
file_type	NIFTI-1+

from the mask I got this:

qform_name	Scanner Anat
qform_code	1
qto_xyz:1	0.141667 0.000000 0.000000 -7.881513 
qto_xyz:2	0.000000 0.500000 0.000000 -2.942948 
qto_xyz:3	0.000000 0.000000 0.150000 -1.922426 
qto_xyz:4	0.000000 0.000000 0.000000 1.000000 
qform_xorient	Left-to-Right
qform_yorient	Posterior-to-Anterior
qform_zorient	Inferior-to-Superior
sform_name	Scanner Anat
sform_code	0
sto_xyz:1	0.000000 0.000000 0.000000 0.000000 
sto_xyz:2	0.000000 0.000000 0.000000 0.000000 
sto_xyz:3	0.000000 0.000000 0.000000 0.000000 
sto_xyz:4	0.000000 0.000000 0.000000 1.000000 
sform_xorient	Unknown
sform_yorient	Unknown
sform_zorient	Unknown
file_type	NIFTI-1+

These numbers are pretty consistent on all anatomical and mask files.
I see that the sform data is absent, but as I understood then the qform data is taken, or did I miss understand that?
The only thing that stands out a bit might be the sto_xyz:4 0.000000 0.000000 0.000000 1.000000 in the mask info, could this cause any problems?

@cookpa
Copy link
Member

cookpa commented Dec 5, 2024

I don't think that one line of sform would be enough to cause this problem. I can check in more detail but could you please isolate the one command that is going wrong and make a script that just runs that command with the sample input?

I think this involves "sub-aRi114_ses-1_T2w_N4_dn.nii.gz", which you included, and the fixed image "/project/4180000.24/analysis_wessel/DTI/template/DSURQE_100micron_average.nii.gz", which I don't think is there.

@cookpa
Copy link
Member

cookpa commented Dec 5, 2024

One other thing that comes to mind is that in animal data, the small voxel sizes sometimes expose numerical problems with optimizers. Example: #1348

So one thing I would test is if the two versions behave differently if the spacing of the images is changed.

Another thing: spatial units. The xyzt_units field may be important, this was another relatively recent fix to ITK (InsightSoftwareConsortium/ITK#4595)

@WesselvEng
Copy link
Author

WesselvEng commented Dec 6, 2024

I don't think that one line of sform would be enough to cause this problem. I can check in more detail but could you please isolate the one command that is going wrong and make a script that just runs that command with the sample input?

I think this involves "sub-aRi114_ses-1_T2w_N4_dn.nii.gz", which you included, and the fixed image "/project/4180000.24/analysis_wessel/DTI/template/DSURQE_100micron_average.nii.gz", which I don't think is there.

I've added the script in this message. Also I added an extra folder in the drive called sub-aRi114, this also contains the template and the template mask. Script is changed so it works if working directory is called sub-aRi114 :)

But the weirdest thing now is that I reran the analysis to check if it ran properly and now i get proper anatomical registration... I double checked if I was not using a different ants version but twice it gave proper anatomical registration. Their should be no difference with the earlier scripts that I used for this subject for input files or anything...

script.txt

@WesselvEng
Copy link
Author

WesselvEng commented Dec 6, 2024

One other thing that comes to mind is that in animal data, the small voxel sizes sometimes expose numerical problems with optimizers. Example: #1348

So one thing I would test is if the two versions behave differently if the spacing of the images is changed.

Another thing: spatial units. The xyzt_units field may be important, this was another relatively recent fix to ITK (InsightSoftwareConsortium/ITK#4595)

Regarding the spacing: what do you mean exactly? should I increase the apperent voxel size or how would I do that?

Regarding the xyzt_unit values: I found out that my anatomicals and anatomical masks have a xyzt_units value of 2. My template anatomical also has a value of 2. The template mask actually has an xyzt_units value of 0 but the dilated version of this mask (which I use for my script) has a value of 10. My anatomical masks also have a xyzt_units value of 10. Could this potentially cause problems bc the xyzt_units values are not comparable?

@WesselvEng
Copy link
Author

was not my intention to close this problem woops, still have the problem

@WesselvEng WesselvEng reopened this Dec 6, 2024
@WesselvEng
Copy link
Author

One other thing that comes to mind is that in animal data, the small voxel sizes sometimes expose numerical problems with optimizers. Example: #1348

So one thing I would test is if the two versions behave differently if the spacing of the images is changed.

Another thing: spatial units. The xyzt_units field may be important, this was another relatively recent fix to ITK (InsightSoftwareConsortium/ITK#4595)

turning on the Gradient Filter for MI metrics as as suggested in #1348 still resulted in some bad registrations such as this one
anat2template

@cookpa
Copy link
Member

cookpa commented Dec 6, 2024

Regarding the spacing: what do you mean exactly? should I increase the apperent voxel size or how would I do that?

You can use SetSpacing to modify the headers. Sometimes scaling everything so that the spacing is approx 1mm helps.

Regarding the xyzt_unit values: I found out that my anatomicals and anatomical masks have a xyzt_units value of 2. My template anatomical also has a value of 2. The template mask actually has an xyzt_units value of 0 but the dilated version of this mask (which I use for my script) has a value of 10. My anatomical masks also have a xyzt_units value of 10. Could this potentially cause problems bc the xyzt_units values are not comparable?

I think that's OK. The xyzt_units is inherited from the old Analyze format, it's a byte where the first three bits describe space and the next three describe time. The space bits should be 2 for mm. 10 means mm for space and s for time. 0 means unknown, which I believe defaults to mm.

@cookpa
Copy link
Member

cookpa commented Dec 6, 2024

I don't think that one line of sform would be enough to cause this problem. I can check in more detail but could you please isolate the one command that is going wrong and make a script that just runs that command with the sample input?
I think this involves "sub-aRi114_ses-1_T2w_N4_dn.nii.gz", which you included, and the fixed image "/project/4180000.24/analysis_wessel/DTI/template/DSURQE_100micron_average.nii.gz", which I don't think is there.

I've added the script in this message. Also I added an extra folder in the drive called sub-aRi114, this also contains the template and the template mask. Script is changed so it works if working directory is called sub-aRi114 :)

But the weirdest thing now is that I reran the analysis to check if it ran properly and now i get proper anatomical registration... I double checked if I was not using a different ants version but twice it gave proper anatomical registration. Their should be no difference with the earlier scripts that I used for this subject for input files or anything...

script.txt

Interesting. I guess it could be stochastic still. If you can run it a bunch of times and it's consistent, it suggests a hidden problem somewhere in the preprocessing.

To run it myself, I need a really minimal example, just this

antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 --output reg/anat2std --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 --initial-moving-transform [DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1] --transform Rigid[0.1] --metric MI[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform Affine[0.1] --metric MI[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform SyN[0.1,3,0] --metric CC[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,4] --convergence [30x20x10x5,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox  --masks [${template_mask},${anat_mask}]

and the fixed, moving images and their masks. Then I will see if I can notice anything in the registration itself.

@gdevenyi
Copy link
Contributor

gdevenyi commented Dec 6, 2024

When I do work in animal land, a major problem is the conversion of the data coming off the scanner is often not properly structured to NIFTI format. If you are using bruker data, the only known reliable converter is https://github.com/BrkRaw/brkraw. For other manufactures I have worked with I had to scan calibration objects and then fix data after-the-fact with data re-ordering and flipping.

The viewer ITKsnap is standards-compliant and interprets data the same way the latest ANTs IO reader does for NIFTI, so it is an ideal tool to use to confirm that your fixed and moving images are properly standards-compliant in orientation, before you attempt alignment.

Finally, you may be interested in
https://github.com/CoBrALab/minc-toolkit-extras/blob/master/antsRegistration_affine_SyN.sh
https://github.com/CoBrALab/minc-toolkit-extras/blob/master/ants_generate_iterations.py

which I developed as part of my work to make the ANTs registration tools more consistent across voxel sizes and species.

I see N4 being used in this set of commands as well, I would note that I have found anisotropic data has issues in some places because of subsampling assumptions. I also isotropize data and adapt tools to work at "real world" scalings (mm) instead of the voxel scalings to avoid issues with that.

@WesselvEng
Copy link
Author

I don't think that one line of sform would be enough to cause this problem. I can check in more detail but could you please isolate the one command that is going wrong and make a script that just runs that command with the sample input?
I think this involves "sub-aRi114_ses-1_T2w_N4_dn.nii.gz", which you included, and the fixed image "/project/4180000.24/analysis_wessel/DTI/template/DSURQE_100micron_average.nii.gz", which I don't think is there.

I've added the script in this message. Also I added an extra folder in the drive called sub-aRi114, this also contains the template and the template mask. Script is changed so it works if working directory is called sub-aRi114 :)
But the weirdest thing now is that I reran the analysis to check if it ran properly and now i get proper anatomical registration... I double checked if I was not using a different ants version but twice it gave proper anatomical registration. Their should be no difference with the earlier scripts that I used for this subject for input files or anything...
script.txt

Interesting. I guess it could be stochastic still. If you can run it a bunch of times and it's consistent, it suggests a hidden problem somewhere in the preprocessing.

To run it myself, I need a really minimal example, just this

antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 --output reg/anat2std --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 --initial-moving-transform [DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1] --transform Rigid[0.1] --metric MI[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform Affine[0.1] --metric MI[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform SyN[0.1,3,0] --metric CC[DSURQE_100micron_average.nii.gz,${anat_noext}'_N4_dn.nii.gz',1,4] --convergence [30x20x10x5,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox  --masks [${template_mask},${anat_mask}]

and the fixed, moving images and their masks. Then I will see if I can notice anything in the registration itself.

Hmm okay, next monday I'll try to run it like, 100 times to see if that is the case.
Here is the antsRegistration call but then with the files that I sent below:

antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 --output reg/anat2std --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 --initial-moving-transform [DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz',1] --transform Rigid[0.1] --metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform Affine[0.1] --metric MI[DSURQE_100micron_average.nii.gzsub-aRi114_ses-1_T2w_N4_dn.nii.gz',1,32,Regular,0.25] --convergence [1000x500x250x100,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --transform SyN[0.1,3,0] --metric CC[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz',1,4] --convergence [30x20x10x5,1e-6,10] --shrink-factors 8x4x2x1 --smoothing-sigmas 3x2x1x0vox --masks [DSURQE_100micron_mask_dilated.nii.gz,sub-aRi114_ses-1_T2w_mask_dilated.nii.gz]

moving image: sub-aRi114_ses-1_T2w_N4_dn.nii.gz
moving mask: sub-aRi114_ses-1_T2w_mask_dilated.nii.gz
fixed image: DSURQE_100micron_average.nii.gz
fixed mask: DSURQE_100micron_mask_dilated.nii.gz

I believe this is everything you need then! let me know if I missed something.

You can use SetSpacing to modify the headers. Sometimes scaling everything so that the spacing is approx 1mm helps.
Also this I'll try in the coming days, possibly passed the weekend.

Thanks for the advice! Will look in to it asap!

@WesselvEng
Copy link
Author

When I do work in animal land, a major problem is the conversion of the data coming off the scanner is often not properly structured to NIFTI format. If you are using bruker data, the only known reliable converter is https://github.com/BrkRaw/brkraw. For other manufactures I have worked with I had to scan calibration objects and then fix data after-the-fact with data re-ordering and flipping.

I also use brkraw luckily!

The viewer ITKsnap is standards-compliant and interprets data the same way the latest ANTs IO reader does for NIFTI, so it is an ideal tool to use to confirm that your fixed and moving images are properly standards-compliant in orientation, before you attempt alignment.

Oh this is a good one, like mentioned above, after the weekend I'll immediately check it out!

Finally, you may be interested in https://github.com/CoBrALab/minc-toolkit-extras/blob/master/antsRegistration_affine_SyN.sh https://github.com/CoBrALab/minc-toolkit-extras/blob/master/ants_generate_iterations.py

which I developed as part of my work to make the ANTs registration tools more consistent across voxel sizes and species.

I see N4 being used in this set of commands as well, I would note that I have found anisotropic data has issues in some places because of subsampling assumptions. I also isotropize data and adapt tools to work at "real world" scalings (mm) instead of the voxel scalings to avoid issues with that.

Idem for this, will check it out after the weekend!
Thank you so much for you help and advice!

@cookpa
Copy link
Member

cookpa commented Dec 9, 2024

Here's what I got after editing the command

image
antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 \
  --output [anat2std,anat2stdWarped.nii.gz] --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 \
  --initial-moving-transform [DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1] \
  --transform Rigid[0.1] --metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,32] \
  --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox --transform Affine[0.1] \
  --metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,32] \
  --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox \
  --transform SyN[0.1,3,0] --metric CC[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,2] \
  --convergence [30x20x5,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox  \
  --masks [DSURQE_100micron_mask_dilated.nii.gz,sub-aRi114_ses-1_T2w_mask_dilated.nii.gz]

I removed the shrink factor 8x from all stages, and changed the metric to use dense sampling. The moving image has a slice thickness of 0.5mm, the lower resolution in combination with the differing FOV between moving and fixed image can lead to poor convergence. Downsampling and smoothing too much can render the anatomical landmarks invisible

@gdevenyi
Copy link
Contributor

gdevenyi commented Dec 9, 2024

I removed the shrink factor 8x from all stages, and changed the metric to use dense sampling. The moving image has a slice thickness of 0.5mm, the lower resolution in combination with the differing FOV between moving and fixed image can lead to poor convergence. Downsampling and smoothing too much can render the anatomical landmarks invisible

This is exactly where switching to my "mm based" representation of the scale space really helps, the default subsampling suggestions for ANTs fall over pretty quickly for anisotropic data if you don't deeply understand what it does.

@WesselvEng
Copy link
Author

Here's what I got after editing the command

image ``` antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 \ --output [anat2std,anat2stdWarped.nii.gz] --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 \ --initial-moving-transform [DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1] \ --transform Rigid[0.1] --metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,32] \ --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox --transform Affine[0.1] \ --metric MI[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,32] \ --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox \ --transform SyN[0.1,3,0] --metric CC[DSURQE_100micron_average.nii.gz,sub-aRi114_ses-1_T2w_N4_dn.nii.gz,1,2] \ --convergence [30x20x5,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox \ --masks [DSURQE_100micron_mask_dilated.nii.gz,sub-aRi114_ses-1_T2w_mask_dilated.nii.gz] ```

I removed the shrink factor 8x from all stages, and changed the metric to use dense sampling. The moving image has a slice thickness of 0.5mm, the lower resolution in combination with the differing FOV between moving and fixed image can lead to poor convergence. Downsampling and smoothing too much can render the anatomical landmarks invisible

Interesting, seems like a good point. So from what you suggested the lack of landmarks could impede the convergence and therefore bad registrations?
Today I was looking with a colleague of mine at the analysis. He mentioned that perhaps something with the orientation information of the masks is wrong. I changed orientation to RAS of template and subjects mask and anatomicals and this seemed to improve overall registration performance, but still there are some faulty regs. I found that in my initial tries the masks had no sform orientation values, as mentioned before. However, you mentioned that this would not form a problem as information would be taken from the qform parameters, if I understood you right. When I changed the mask orientation to RAS I saw that these values were present in the nifti headers. Maybe in my first attempts the absence of this sform orient info of the masks also impeded registration by a mismatch in the initial transform e.g. the moving image was rotated 90 degrees bc of missing orientation info and therefore the whole registration was faulty?
Also, my colleague proposed that because each iterations is inherently a stochastic move (just trying to see if a specific iteration leads to better convergence) that with bad luck in the end the registrations moves totally the wrong way. Therefore, sometimes it would just not succeed.
Maybe this, in combination with bad landmark detection and as well as insufficient orientation information lead to so many failed registrations?

I hadn't had time today to look at the spacing. Tomorrow ill try to set spacing to ~1mm for all directions for all voxels to see if it improves the registrations. Later I'll also try some runs without the 8x shrink factor and the dense sampling metric!

Thanks for your help

@cookpa
Copy link
Member

cookpa commented Dec 9, 2024

I looked at the images in ITK-SNAP and the masks appeared correctly oriented.

BTW, using dense sampling for the metric disables the random perturbation of the sample points (as well as adding more sample points, which probably also helps). So run-to-run variability should be reduced.

@WesselvEng
Copy link
Author

I removed the shrink factor 8x from all stages, and changed the metric to use dense sampling. The moving image has a slice thickness of 0.5mm, the lower resolution in combination with the differing FOV between moving and fixed image can lead to poor convergence. Downsampling and smoothing too much can render the anatomical landmarks invisible

This is exactly where switching to my "mm based" representation of the scale space really helps, the default subsampling suggestions for ANTs fall over pretty quickly for anisotropic data if you don't deeply understand what it does.

hmm I dont think I fully comprehend what you mean, but that is probably because of my lack of knowledge about this concept! From what I understand you also suggest that upscaling to 1mm scale would help because ANTs would better be able to do the regs, correct?

@WesselvEng
Copy link
Author

I looked at the images in ITK-SNAP and the masks appeared correctly oriented.

BTW, using dense sampling for the metric disables the random perturbation of the sample points (as well as adding more sample points, which probably also helps). So run-to-run variability should be reduced.

hmm intersting. So far from what I have seen today fixing the sform parameters in the NIFTI headers decreased the amount of failed regs per try with 50%. So still stochastically they fail, but they fail less often. Im gonna try the dense sampling metric and without 8x shrink factors now!

@gdevenyi
Copy link
Contributor

gdevenyi commented Dec 9, 2024

hmm I dont think I fully comprehend what you mean, but that is probably because of my lack of knowledge about this concept! From what I understand you also suggest that upscaling to 1mm scale would help because ANTs would better be able to do the regs, correct?

No, there's no need to rescale. You just need to understand that smoothing and subsampling happens by default in voxel-spacing, and if your data is anisotropic, that will carry through to how the subsampling and smoothing is applied during registration.

This causes issues in two ways

  1. Anisotropic smoothing messes with the "concept" of the scale space of features
  • fixable by defining smoothing using the "mm" suffix
  1. Subsampling unevenly reducing the feature dimension more in one direction than another
  • fixable by always "thinking" about subsampling in that dimension, or by supersampling the data into an isotropic representation

I've tried to tackle these issues by wrapping the registartion in a bunch of python math to use the physical dimensions of the images as well as their voxel sizes to define a more coherent scale-space to step through during registration.

@WesselvEng
Copy link
Author

hmm I dont think I fully comprehend what you mean, but that is probably because of my lack of knowledge about this concept! From what I understand you also suggest that upscaling to 1mm scale would help because ANTs would better be able to do the regs, correct?

No, there's no need to rescale. You just need to understand that smoothing and subsampling happens by default in voxel-spacing, and if your data is anisotropic, that will carry through to how the subsampling and smoothing is applied during registration.

This causes issues in two ways

  1. Anisotropic smoothing messes with the "concept" of the scale space of features
  • fixable by defining smoothing using the "mm" suffix
  1. Subsampling unevenly reducing the feature dimension more in one direction than another
  • fixable by always "thinking" about subsampling in that dimension, or by supersampling the data into an isotropic representation

I've tried to tackle these issues by wrapping the registartion in a bunch of python math to use the physical dimensions of the images as well as their voxel sizes to define a more coherent scale-space to step through during registration.

aaaah okay I think Im beginning to understand. So because of the anisotropic voxels, smoothing happens unevenly across different directions and therefore you get uneven smoothing and deforming (if that is the correct term) of the original image. By defining smoothing over mm, so in real space instead of voxels, the program will adjust the amount of voxels it needs per direction to get an even distance across all directions and therefore you will have homogenous smoothing and thus no deforming (again correct me if im wrong) of the image. Am I getting closer to what you mean?
I'll need to get a bit more knowledge about what the subsampling etc. means and what it does, I'll get back to this :)

So far I have ran a registration round with specifically defining the orientations for all used niftis (masks and anatomicals), removing the 8x shrink factor and using dense sampling metric. So far, all anatomical registrations were succesful! DWI registrations were not always right for all subjects yet. Im gonna rerun with the same settings to check if the results are now indeed more consistent as @cookpa suggested!
Im going to run a round with the mm suffix too as @gdevenyi suggested to see if this improves the results :)

Thank you all for you advice so far, it has been really helpful and educative!

@cookpa
Copy link
Member

cookpa commented Dec 10, 2024

aaaah okay I think Im beginning to understand. So because of the anisotropic voxels, smoothing happens unevenly across different directions and therefore you get uneven smoothing and deforming (if that is the correct term) of the original image. By defining smoothing over mm, so in real space instead of voxels, the program will adjust the amount of voxels it needs per direction to get an even distance across all directions and therefore you will have homogenous smoothing and thus no deforming (again correct me if im wrong) of the image. Am I getting closer to what you mean?
I'll need to get a bit more knowledge about what the subsampling etc. means and what it does, I'll get back to this :)

Not quite. The downsampling (-f) is defined in integer units of the fixed voxel space. So -f 4 means "take the smallest voxel length in the fixed image (0.1mm in your case) and multiply by 4". So the resolution is 0.4x0.4x0.4mm for that stage. If your fixed space had spacing (0.5, 0.5, 1), then -f 4 would imply 4 * 0.5 = 2mm.

The smoothing standard deviation -s can be in voxels (using the same idea above) or mm, and it can be floats. So -s 1.5mm is acceptable, as is 2vox. This is isotropic smoothing in 3D. However, if you have spacing (0.5,0.5,3) and you have smoothing with a 1mm SD kernel, it's going to smooth across more voxels in-plane.

But I think the problem with using -f 8 -s 3vox in your data is not so much the smoothing itself, it's that you are smoothing and downsampling the image so much that its features become invisible.

Here's what it looks like if I apply the same operation:

SmoothImage 3 sub-aRi114_ses-1_T2w_N4_dn.nii.gz 0.3 smooth.nii.gz 1
ResampleImageBySpacing 3 smooth.nii.gz downsample.nii.gz 0.8 0.8 0.8 0
image

The next level (-f 4, -s 2vox) at least preserves some hint of a brain structure

SmoothImage 3 sub-aRi114_ses-1_T2w_N4_dn.nii.gz 0.2 smooth2.nii.gz 1
ResampleImageBySpacing 3 smooth2.nii.gz downsample2.nii.gz 0.4 0.4 0.4 0
image

Edited: correct decimal place

@WesselvEng
Copy link
Author

hmm I dont think I fully comprehend what you mean, but that is probably because of my lack of knowledge about this concept! From what I understand you also suggest that upscaling to 1mm scale would help because ANTs would better be able to do the regs, correct?

No, there's no need to rescale. You just need to understand that smoothing and subsampling happens by default in voxel-spacing, and if your data is anisotropic, that will carry through to how the subsampling and smoothing is applied during registration.

This causes issues in two ways

  1. Anisotropic smoothing messes with the "concept" of the scale space of features
  • fixable by defining smoothing using the "mm" suffix
  1. Subsampling unevenly reducing the feature dimension more in one direction than another
  • fixable by always "thinking" about subsampling in that dimension, or by supersampling the data into an isotropic representation

I've tried to tackle these issues by wrapping the registartion in a bunch of python math to use the physical dimensions of the images as well as their voxel sizes to define a more coherent scale-space to step through during registration.

okay so I have tried fixing the anisotropic smoothing by changing the smoothing sigma suffix to -smoothing-sigmas 2x1x0mm, however this resulted in many registrations to become more skewed, as compared to keeping the voxel suffix, example below:
image
image

You can see below that the edges of the subject anat are a bit compressed. There are several comparable subjects like this and some worse and more deformed.
So I think I should either change the smoothing values or I am approaching it incorrectly then what you mean.

This deformation I did not see in virtually all subjects with the same settings, but with the 'vox' suffix.
Sadly, the high performance cluster Im using is very busy today so haven't been able to run the same analysis multiple times to see if there are still inconsistencies with the current approach I'm using. Will come back to this!

@gdevenyi
Copy link
Contributor

okay so I have tried fixing the anisotropic smoothing by changing the smoothing sigma suffix to -smoothing-sigmas 2x1x0mm

These smoothing sigmas are too large if you're working with animal data represented with true resolution.

Here's what my reg script would've approximately done internally: (min is minimum voxel size, max is maximum physical extent of the image)

$ ants_generate_iterations.py --min 0.15 --max 20
--convergence [ 500x500x180x60x20x20,1e-6,10 ] \
--shrink-factors 4x4x3x2x1x1 \
--smoothing-sigmas 0.375x0.3x0.22499999999999998x0.15x0.075x0.0mm

@cookpa Regarding the random sampling component and masks, I think there was some concern with how masking is handled during random voxel sampling. I didn't dig into it because I only ever used dense sampling, but maybe that's also an impact here?

@cookpa
Copy link
Member

cookpa commented Dec 10, 2024

@cookpa Regarding the random sampling component and masks, I think there was some concern with how masking is handled during random voxel sampling. I didn't dig into it because I only ever used dense sampling, but maybe that's also an impact here?

This is a good point, I believe the sampling is done on the whole volume and then points outside the intersection of the masks are discarded. So there can be fluctuations in the exact number of sample points. IMO dense sampling is the way unless there is a particular need to mitigate sampling bias

@WesselvEng
Copy link
Author

okay so I have tried fixing the anisotropic smoothing by changing the smoothing sigma suffix to -smoothing-sigmas 2x1x0mm

These smoothing sigmas are too large if you're working with animal data represented with true resolution.

Here's what my reg script would've approximately done internally: (min is minimum voxel size, max is maximum physical extent of the image)

$ ants_generate_iterations.py --min 0.15 --max 20
--convergence [ 500x500x180x60x20x20,1e-6,10 ] \
--shrink-factors 4x4x3x2x1x1 \
--smoothing-sigmas 0.375x0.3x0.22499999999999998x0.15x0.075x0.0mm

yeah when this seems more logic indeed, really didn't think about difference between vox and real distance, but seems pretty logic!
So in my script, if I want to use the mm suffix, do you think the values that you mentioned above would be appropriate for my data? Or are these example numbers?
I still find it hard imagining what everything exactly is, e.g. what the effect is of multiple iteration levels with the convergence.

@cookpa Regarding the random sampling component and masks, I think there was some concern with how masking is handled during random voxel sampling. I didn't dig into it because I only ever used dense sampling, but maybe that's also an impact here?

This is a good point, I believe the sampling is done on the whole volume and then points outside the intersection of the masks are discarded. So there can be fluctuations in the exact number of sample points. IMO dense sampling is the way unless there is a particular need to mitigate sampling bias

Since I use the Dense Sampling in my analysis faulty anatomical registrations were virtually absent, maybe 1 or 2 subjects. Only my DWI-> anatomical registrations were not great so my DWI->anatomical->template were a bit messy as shown below
image
For my DWI->anatomical I use
antsIntroduction.sh -d 3 -i b0_tmean.nii.gz -o dwi2anat -r ${anat} -t RA -s CC -m 20x15x10
but I guess I could change to a Dense Sampling strategy here too and see if that improves :)

I hope the server is not as busy today as yesterday, then I try the dense sampling strategy a few times to see how consistent it is :)

@gdevenyi
Copy link
Contributor

So in my script, if I want to use the mm suffix, do you think the values that you mentioned above would be appropriate for my data? Or are these example numbers?

Those are based on your minimal voxel size and the "average" size for a mouse brain, so they should be OK to use. Of course, if you used my reg scripts directly, that would all be handled internally ;)

I still find it hard imagining what everything exactly is, e.g. what the effect is of multiple iteration levels with the convergence.

Those numbers say the maximum number of optimization steps at a given shrink/smooth, provided they don't meet the 1e-6 convergence criteria first. They're rarely met anyways because convergence happens first.

I hope the server is not as busy today as yesterday, then I try the dense sampling strategy a few times to see how consistent it is :)

These are all optimizations on top of dense sampling, its definitely a good place to start.

@WesselvEng
Copy link
Author

WesselvEng commented Dec 17, 2024

I looked at the images in ITK-SNAP and the masks appeared correctly oriented.

BTW, using dense sampling for the metric disables the random perturbation of the sample points (as well as adding more sample points, which probably also helps). So run-to-run variability should be reduced.

Okay so I have just ran a few hundred runs with the following settings:
mkdir -p reg antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 --output reg/anat2std --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 --initial-moving-transform [${template},\${anat_noext}'_N4_dn.nii.gz',1] --transform Rigid[0.1] --metric MI[${template},\${anat_noext}'_N4_dn.nii.gz',1,32] --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox --transform Affine[0.1] --metric MI[${template},\${anat_noext}'_N4_dn.nii.gz',1,32] --convergence [500x250x100,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox --transform SyN[0.1,3,0] --metric CC[${template},\${anat_noext}'_N4_dn.nii.gz',1,2] --convergence [30x20x5,1e-6,10] --shrink-factors 4x2x1 --smoothing-sigmas 2x1x0vox --masks [${template_mask},\${anat_mask}]

12 times I ran all my 100 subjects. Of these 12 runs per subject there were a total of 4 failed runs with 1 subject being over represented ( 3 times, aRi013). So 4/1200 runs failed. But I found that quality of registration could vary a lot between subjects and runs.
I decided to run the overrepresented subject 100 times with this script and found that it failed 6/100 times and that registration quality also varied.
I also ran a subject that did not show any failed registration (aRi108) in the initial runs 100 times and this one failed zero times, but interestingly also showed very consistent results, as opposed to aRi013.

All in all does this show that for the anatomical registrations Dense Sampling solved indeed let to more consistent results and solved my initial problem, so thank you a lot! :)
Also I think that, depending on the specifics of the data, some data are more prone to faulty registrations, based on stochastic variables, then others and that this is also reflected in the consistency in the quality of the registration.

Now only my DWI -> template registrations are left. I tried the same strategy with Dense Sampling and not too big of shrink factors, but sadly it did not work yet. If you have any advice on this I am happy to hear it! I'm gonna take a look at those scripts of yours to see if they can help with it @gdevenyi :)

@cookpa
Copy link
Member

cookpa commented Dec 17, 2024

I'm glad you're making progress.

I noticed several issues in your dwi processing script.

antsIntroduction.sh -d 3 -i b0_tmean.nii.gz -o dwi2anat -r ${anat} -t RA -s CC -m 20x15x10

This is old ANTS, antsIntroduction.sh was an early version of antsRegistrationSyN.sh. It is not optimized for intra-subject registration. Also, you call WarpTimeSeriesImageMultiTransform 4 on 3D images - this will likely also cause problems.

Looking at the example image you uploaded

image

Here I'm displaying the average of all DWI (including b=0 and b>0). Sometimes, averaging all the b>0 improves contrast, especially if the number of b=0 is small. FSL's select_dwi_vols can do this.

The DWI space appears offset from the T2w space. This is not ideal, but it happens. Ideally, the origin of each image should be set such that they overlap. This is very useful for keeping intrasubject registration from going wrong. But the initial center of mass alignment will hopefully fix this.

I think a metric mask is definitely needed here, because the contrast outside the brain is very different. I'd probably not downsample at all, because of the thickness of the slices. And I'd consider doing only rigid registration. Without a field map to correct susceptibility, the registration accuracy is going to be limited. If there's residual eddy correction needed, I'd attempt to do this in 2D (defining an in-plane correction for each slice, along the phase-encode axis only).

@WesselvEng
Copy link
Author

I'm glad you're making progress.

I noticed several issues in your dwi processing script.

antsIntroduction.sh -d 3 -i b0_tmean.nii.gz -o dwi2anat -r ${anat} -t RA -s CC -m 20x15x10

This is old ANTS, antsIntroduction.sh was an early version of antsRegistrationSyN.sh. It is not optimized for intra-subject registration. Also, you call WarpTimeSeriesImageMultiTransform 4 on 3D images - this will likely also cause problems.

I got this script from my supervisor, he used it in the past so maybe that's why its a bit outdated. I already considered switching to antsRegistration SyN.sh but it didnt improve yet. Als I thought that DWI images were 4D so thats why I need to put in 4 for the dimensions. I tried to use antsApplytransforms however when I put in 4 for dimensions I wouldn't run. But if I can use 3D dimensions then perhaps I could use antsApplytransforms instead. I suppose I have to first use CompseMultTransform to create a transform from the output of antsRegistration.sh?
What is the difference between antsApply and AarpTimeSeriesImageMultitTransform then?

Looking at the example image you uploaded

image Here I'm displaying the average of all DWI (including b=0 and b>0). Sometimes, averaging all the b>0 improves contrast, especially if the number of b=0 is small. FSL's select_dwi_vols can do this.

I believe in my supervisors script he tried to control for this by taking the temporal mean from the b0 images (first 5 images of the dwi.nii.gz file) using fslmaths so to get an averaged image for all DWI images: fslmaths b0.nii.gz -Tmean b0_tmean.nii.gz. This is then used as proxy for the whole dwi.nii.gz file to register it to the anatomical (and subsequently to the template).
If I understand correctly you propose to make an average from all the scans that are not b0 maps, and use that as proxy for the DWI for the registrations? I wonder if that would work because I know that later on in the DWI nifti files the image tends to move a bit as compared to the beginning. I understood that this is because the gradient are not perfectly symmetric and due to thermal increase of the tissue. Would that matter for the average image? I could do only an initial center of mass alignment on the non b0 images of the dwi.nii.gz file on the anatomical images, and then after this ICM alignment average all the b>0 images and then use that as proxy for the whole dwi.nii.gz file again? Would that work?

The DWI space appears offset from the T2w space. This is not ideal, but it happens. Ideally, the origin of each image should be set such that they overlap. This is very useful for keeping intrasubject registration from going wrong. But the initial center of mass alignment will hopefully fix this.

Hm yeah but that is the purpose of the dwi->anat registration right? Would think to that that is fixed by ICM alignment indeed. But I suppose the ICM alignment would fix these right?

I think a metric mask is definitely needed here, because the contrast outside the brain is very different. I'd probably not downsample at all, because of the thickness of the slices. And I'd consider doing only rigid registration. Without a field map to correct susceptibility, the registration accuracy is going to be limited. If there's residual eddy correction needed, I'd attempt to do this in 2D (defining an in-plane correction for each slice, along the phase-encode axis only).

So would you propose to make a mask for the moving image during the DWI->anat registration? I could make a mask for the b0 temporal mean, or then perhaps for the average b>1 images. I'll leave out the shrink factors then, so not to down sample. I do perform eddy current correction using FSL with eddy_correct ${dwi_file} ${dwi_noext}'_eddy.nii' 0, is this what you mean?
I think I can access the b0 field map from the scanner data, but Im not sure how to use them then.

First Ill try the newer antsRegistrationSyn.sh with only rigid registration and without downsampling :) Ill wait for you answers to see how to implement the rest!

@cookpa
Copy link
Member

cookpa commented Dec 18, 2024

If I understand correctly you propose to make an average from all the scans that are not b0 maps, and use that as proxy for the DWI for the registrations? I wonder if that would work because I know that later on in the DWI nifti files the image tends to move a bit as compared to the beginning. I understood that this is because the gradient are not perfectly symmetric and due to thermal increase of the tissue. Would that matter for the average image?

Yes, it would matter. You know your data best, I was just making a suggestion. Sounds like you have a good rationale to use mean b=0.

Anyway, I would not use antsRegistrationSyN.sh at all, I would use a custom command

fixed=t2.nii.gz
fixed_mask=t2_mask.nii.gz
moving=mean_b0.nii.gz

antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 \ 
  --output [dwi2anat,dwi2anatWarped.nii.gz] --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 \ 
  --initial-moving-transform [${fixed},${moving},1] \ 
  --transform Rigid[0.1] --metric MI[${fixed},${moving},1,32] \ 
  --convergence [50,1e-6,10] --shrink-factors 1 --smoothing-sigmas 0vox \
  --masks [${fixed_mask}, none]

To combine warps, you can use antsApplyTransforms -d 3 ... -t transform -t transform2 ... -o [ compositeWarp.nii.gz, 1]

If you try to do anything non-rigid with antsRegistration, I would make b0 the fixed image, t2w the moving. Note this affects the order of transforms when you apply warps. Then run rigid. Use the rigid output as an intial transform to an affine / deformable step, with the --restrict-deformation option to only allow deformation in-plane, along z.

There is a antsSliceRegularizedRegistration program which operates in 2D with regularization along the slices, but it is hard-coded to deform in the x-y plane and regularize along z, so it would take some modifications to work on your data, or you'd have to reslice.

@cookpa
Copy link
Member

cookpa commented Dec 18, 2024

See also

https://github.com/ANTsX/ANTs/wiki/Dimensionality-or-ImageDimension-option-in-ANTs

for more on what ANTs calls the "ImageDimension" and why it's often correct to use -d 3 even if some data is 4D.

@WesselvEng
Copy link
Author

If I understand correctly you propose to make an average from all the scans that are not b0 maps, and use that as proxy for the DWI for the registrations? I wonder if that would work because I know that later on in the DWI nifti files the image tends to move a bit as compared to the beginning. I understood that this is because the gradient are not perfectly symmetric and due to thermal increase of the tissue. Would that matter for the average image?

Yes, it would matter. You know your data best, I was just making a suggestion. Sounds like you have a good rationale to use mean b=0.
okay okay then I understood correct :)

Anyway, I would not use antsRegistrationSyN.sh at all, I would use a custom command

fixed=t2.nii.gz
fixed_mask=t2_mask.nii.gz
moving=mean_b0.nii.gz

antsRegistration --dimensionality 3 --float 0 -a 0 -v 1 \ 
  --output [dwi2anat,dwi2anatWarped.nii.gz] --interpolation Linear --winsorize-image-intensities [0.005,0.995] --use-histogram-matching 0 \ 
  --initial-moving-transform [${fixed},${moving},1] \ 
  --transform Rigid[0.1] --metric MI[${fixed},${moving},1,32] \ 
  --convergence [50,1e-6,10] --shrink-factors 1 --smoothing-sigmas 0vox \
  --masks [${fixed_mask}, none]

To combine warps, you can use antsApplyTransforms -d 3 ... -t transform -t transform2 ... -o [ compositeWarp.nii.gz, 1]

Thank you for your suggestion! Been busy collecting data today so hadn't had the time yet, but will try asap will look at these suggestions asap :)

If you try to do anything non-rigid with antsRegistration, I would make b0 the fixed image, t2w the moving. Note this affects the order of transforms when you apply warps. Then run rigid. Use the rigid output as an intial transform to an affine / deformable step, with the --restrict-deformation option to only allow deformation in-plane, along z.

I got a feeling that non-linear deformation only increased troubles with the DWI registration. I tried to create a manual call myself, but that was not very succesfull as the b0_temp mean got very skewed, looking like the affine part went very wrong. I can try both and see what works best. I think with the using the T2w as moving and b0 as fixed, in the end I should apply the inverse transform on the b0 to register it to the t2w right? Or am I wrong?

There is a antsSliceRegularizedRegistration program which operates in 2D with regularization along the slices, but it is hard-coded to deform in the x-y plane and regularize along z, so it would take some modifications to work on your data, or you'd have to reslice.

Also thanks for this suggestion, perhaps if everything else will not work its worth taking a look.

I got some stuff to continue working with! Will let you know if it improves the registrations :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants