Open tushaarkataria opened 7 months ago
We can help more if you can share code and example data.
There is variation in registration due to random sampling, which you can disable by using one of the "repro" methods in antsRegistration.
It is suspicious if it works for exactly 18 and fails for 2 every time. What if you run the same patch 20 times?
I tried the "repro" setting and flushing all the variables related to the registration but i still see the same issue.
And i just want to clarify, it's kind of like 2-3 out the 20 patches, but similar in percentage when compared to the total number of patches like approximately 10-20% of the patches are not registered. But I can chalk that upto optimization issue and feature issue that i used for registration.
It's when i try to register the same un-registered image from the previous run in a notebook or another script, it registers well. I am not sure how to debug that behavior.
I made a 2D example experiment here
https://github.com/cookpa/antsPyRegistrationStability
Basically, I took a slice from two 0.5mm T1w images, then ran registration 500 times, using
Here's a plot of the CC metric (radius = 4) after registration. These are negative values as used in ANTs optimizers so a more negative number is greater similarity
I did notice a few outliers in both the CLI and the python output, but I don't see strong evidence that using a for loop makes things worse.
The failure rate is subjective but to my eye it was less than 10-20%. If your registrations are more unstable, here's a few things you could try:
Pad the images. Having images extend all the way to the boundary of the FOV can lead to stability issues. ImageMath PadImage can be used to add (say 20 voxels of) empty space around the borders before registration. This doesn't change the physical space so you can still apply the transforms to the original images.
Change the default downsampling and smoothing. The default parameters have been somewhat optimized for 3D anatomical images. It might be downsampling or smoothing too much.
Check initialization. The default is to align the center of mass of the two images, if this is likely to go wrong (eg, there are negative intensities), an alternative strategy may be required.
Check affine registration. This is faster and its worth optimizing this a bit because a poor affine stage will often lead to bad deformable results.
Impose regularization eg using a transform like SyN[0.2, 3,1]
rather than the default SyN[0.2, 3,0]
. If the problem is unreasonably large deformations in the syn stage.
@tushaarkataria it looks like you were definitely on to something! #579
OK we've tried our best to eliminate any uninitialized memory being accessed in images. I'm not certain that this was affecting antsRegistration, but it was affecting cortical thickness in a similar way. Anyway, wheels available here if anyone wants to try them out
I updated the scripts here
https://github.com/cookpa/antsPyRegistrationStability
to use the "repro" mode options. I get 100% reproducible results over 100 runs even before the recent fixes, so maybe registration wasn't affected? Though other functions definitely were. Running more iterations now to confirm
Confirmed after 500 iterations - registration of the same data is 100% deterministic with this call
import ants
import sys
fi = ants.image_read('data/fixed_slice_2d.nii.gz')
mi = ants.image_read('data/moving_slice_2d.nii.gz')
iterations = int(sys.argv[1])
for i in range(iterations):
reg = ants.registration(fixed=fi, moving=mi, type_of_transform='antsRegistrationSyNQuickRepro[s]')
deformed_mi = ants.apply_transforms(fixed=fi, moving=mi, transformlist=reg['fwdtransforms'])
ants.image_write(deformed_mi, 'output/antspy_loop/moving_deformed_iteration_{:04d}.nii.gz'.format(i))
if (i + 1) % int(iterations / 10) == 0:
print(f"Iteration {i + 1}/{iterations} completed.")
On Mac OS 12 (Intel) with ANTsPy 0.4.2
I am trying to register patches of size 12000x12000 that are sampled from a bigger image. I am observing inconsistent performance of AntsPy.
Let's say i have 20 patches of the above mentioned size. Ants framework when executed with a python scripts works for 18 of them and doesn't for the other 2. By doesn't i mean, it gives bad performance on registration. If I rerun it still works for 18 of them, but the 2 for which it doesn't work, are different patches. AntsPy is performing inconsistently while in a loop.
Then I tested running ants on those 2 patches using a Notebook, and it registered them well. So Ants is working but AntsPy while in a loop is not.
I am not sure how to debug this issue ? Can it be a memory flushing issue ?? But i see in the AntsPy Code that it's calling a binary, which i think gets flushed on it own.
Has anyone else come across this issue ?? Any help would be appreciated.