ANTsPy: Unexpected values with label transformations

Describe the bug I’m trying to align the Allen Institute mouse brain annotation volume to our own volumes using the following sequence: Register the Allen template to our own, transform 1 (Similarity + SyN) Register our own 3D brain acquisition to our own template, transform 2 (Similarity + SyN) After this, I use the transformations to transform the Allen annotation volume to our own acquisition image space. So I apply transform 1 and the inverse transform 2 to the Allen annotation volume to obtain the final aligned annotations. For applying the transforms I use the genericLabel interpolator. This mostly works fine except for a couple of regions. These regions now have values which were not present in the original annotation volume. This is a problem for us with further analysis and image generation as I can’t map the right colour to these values, as these values don’t exist in the Allen Institute structure trees. I suspect that it is summing label values somewhere, but I’m not sure as to the cause of the problem.

I can share the volumes if required.

To reproduce

rigid_transform_template = ants.registration(fixed=lsfm_template, moving=template_allen, moving_mask=None,
                                             type_of_transform='Similarity', write_composite_transform=True)
syn_transform_template = ants.registration(fixed=lsfm_template, moving=template_allen, moving_mask=None,
                                           type_of_transform='SyN',
                                           initial_transform=rigid_transform_template['fwdtransforms'],
                                           write_composite_transform=True)

rigid_transform_image = ants.registration(fixed=lsfm_template, moving=image, moving_mask=temp_mask,
                                          type_of_transform='Similarity',
                                          write_composite_transform=True)
syn_transform_image = ants.registration(fixed=lsfm_template, moving=image, moving_mask=temp_mask,
                                        type_of_transform='SyN',
                                        initial_transform=rigid_transform_image['fwdtransforms'],
                                        write_composite_transform=True)

new_atlas = ants.apply_transforms(fixed=lsfm_template, moving=atlas_allen,
                                  transformlist=syn_transform_template['fwdtransforms'],
                                  interpolator="genericLabel")
new_atlas = ants.apply_transforms(fixed=image, moving=new_atlas,
                                  transformlist=syn_transform_image['invtransforms'],
                                  interpolator="genericLabel")

Expected behavior There should be no integer values in the new image that were not in the original volume. The interpolator should assign only existing label values.

About this issue

  • Original URL
  • State: closed
  • Created 4 months ago
  • Comments: 40 (11 by maintainers)

Most upvoted comments

Sounds okay to me, too. But I defer to y’all.

Using double should be OK in my opinion.

I was confused before, I used numpy’s ‘float’ type which defaults to float64. With 32-bit floats, we see the same behavior

>>> a = np.asarray(614454277, dtype='uint32')
>>> af = a.astype('float32')
>>> af
array(6.144543e+08, dtype=float32)
>>> np.unique(af)
array([6.144543e+08], dtype=float32)
>>> af.astype('uint32')
array(614454272, dtype=uint32)

float32 can’t represent such as large integer.

I think the only ways to work around this are either to remap the labels, or to use antsApplyTransforms on the command line with double precision (don’t add --float).

I think this might be it.

https://github.com/ANTsX/ANTsPy/blob/ff7413a5e7685b94ad7fc9a9b2553656f3bd005e/ants/registration/apply_transforms.py#L111-L114

The moving image is cloned to float, but the output image is a clone of the original without type specified. So antsApplyTransforms is trying to write its float output into a uint32 image array.