Euler3DTransform class and Transforms class

I executed a ImageRegistrationMethod function call, and set the initial transform according to:

initial_transform = sitk.CenteredTransformInitializer(
    fixed_image,
    moving_image,
    sitk.Euler3DTransform(),
    sitk.CenteredTransformInitializerFilter.GEOMETRY,
)

After the registration, the function returns a transform of the Transform class:
https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1Transform.html

When calling fitted_transform.GetParameters(), the function returns a tuple of 6 values. What do these values correspond to? There is no documentation specifying what is actually returned by this generic class, as far as I can tell.

Thanks!

Hello @natwille1,

TLDR;
angle_x, angle_y, angle_z, tx, ty, tz - angles are in radians, translation in mm.

print(fitted_transform)
print(fitted_transform.GetParameters())

Long answer:

Generally speaking the GetParameters method is for internal use. The order and meaning of the parameter values is dependent on the transformation type, so better to use explicit methods such as the Euler3DTransform’s GetAngleX method (note that your initial_transform is of type Transform and internally it is Euler3DTransform).

I assume fitted_transform is the result returned from executing the registration (code snippet doesn’t show this), so it is a CompositeTransform.

The contents of this CompositeTransform depend on the transform type which was actually optimized, in this case assuming the initial_transform was used for initialization (it’s in the name) it will be a Euler3DTransform. To get a copy of it as a Euler3DTransform: fitted_transform.GetBackTransform().

1 Like

Thanks for the answer, that’s clear. I double checked and the registration procedure and it actually returns a Transform class rather than a CompositeTransform, which does not have the “GetBackTransform” method. I suppose that’s because the CentredTransformInitializer class returns a Transform, else I’m missing something

Here is the code to run the registration:

        initial_transform = sitk.CenteredTransformInitializer(
            fixed_image,
            moving_image,
            sitk.Euler3DTransform(),
            sitk.CenteredTransformInitializerFilter.GEOMETRY,
        )
            registration_method = sitk.ImageRegistrationMethod()
            registration_method.SetMetricAsMeanSquares()

            registration_method.SetOptimizerAsGradientDescent(
                learningRate=1.0,
                numberOfIterations=500,
                convergenceMinimumValue=1e-6,
                convergenceWindowSize=10,
            )
            registration_method.SetOptimizerScalesFromPhysicalShift()

            # Don't optimize in-place
            registration_method.SetInitialTransform(initial_transform, inPlace=False)

            final_transform = registration_method.Execute(
                sitk.Cast(self.sd_fixed_image, sitk.sitkFloat32),
                sitk.Cast(self.sd_moving_image, sitk.sitkFloat32),
            )

I suppose it’s okay, as long as I can be 100% sure that the GetParameters method of Transform class always returns the values of the internal Euler3DTransform in the correct order.

1 Like

Please try to explicitly cast fitted_transform to a CompositeTransform to get the results. That is try:
sitk.CompositeTransform(fitted_transform).GetBackTransform()
or
fitted_transform.Downcast().GetBackTransform()

Both of these should return a Euler3DTransform object.

1 Like

Thanks for the input! Attempting either one of those options results in an AttributeError:

fitted_transform.Downcast().GetBackTransform().GetAngleX()
AttributeError: 'Transform' object has no attribute 'GetAngleX'

t = sitk.CompositeTransform(fitted_transform).GetBackTransform() 
t.GetAngleX() 
AttributeError: 'Transform' object has no attribute 'GetAngleX'

Maybe I need to use a different sitk.ImageRegistrationMethod()?

What version of SimpleITK are you using?

The BackTransform method should automatically downcast in newer versions of SimpleITK. Try adding another .Downcast() to downcast to the Euler transform type.