# Euler3DTransform class and Transforms class

**URL:** <https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332>\
**Category:** Algorithms\
**Tags:** simpleitk, registration, python\
**Created:** [September 12, 2022, 4:44pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332 "2022-09-12T16:44:59Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![natwille1](https://discourse.itk.org/user_avatar/discourse.itk.org/natwille1/32/2911_2.png) [@natwille1](https://discourse.itk.org/u/natwille1)\
**Post date:** [September 12, 2022, 4:44pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/1 "2022-09-12T16:44:59Z")

</div>

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

```auto
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](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!

---

<div class="post-metadata">

**Author:** ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)\
**Post date:** [September 12, 2022, 7:03pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/2 "2022-09-12T19:03:06Z")

</div>

Hello @natwille1,

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

```auto
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](https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1CompositeTransform.html).

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](https://simpleitk.org/doxygen/latest/html/classitk_1_1simple_1_1Euler3DTransform.html). To get a copy of it as a Euler3DTransform: `fitted_transform.GetBackTransform()`.

---

<div class="post-metadata">

**Author:** ![natwille1](https://discourse.itk.org/user_avatar/discourse.itk.org/natwille1/32/2911_2.png) [@natwille1](https://discourse.itk.org/u/natwille1)\
**Post date:** [September 13, 2022, 10:51am UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/4 "2022-09-13T10:51:00Z")

</div>

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:

```auto
        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.

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [September 13, 2022, 1:00pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/5 "2022-09-13T13:00:25Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![natwille1](https://discourse.itk.org/user_avatar/discourse.itk.org/natwille1/32/2911_2.png) [@natwille1](https://discourse.itk.org/u/natwille1)\
**Post date:** [September 13, 2022, 2:29pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/6 "2022-09-13T14:29:05Z")

</div>

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

```auto
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()`?

---

<div class="post-metadata">

**Author:** ![blowekamp](https://discourse.itk.org/user_avatar/discourse.itk.org/blowekamp/32/79_2.png) [@blowekamp](https://discourse.itk.org/u/blowekamp)\
**Post date:** [September 13, 2022, 2:36pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/7 "2022-09-13T14:36:15Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![natwille1](https://discourse.itk.org/user_avatar/discourse.itk.org/natwille1/32/2911_2.png) [@natwille1](https://discourse.itk.org/u/natwille1)\
**Post date:** [October 19, 2022, 1:21pm UTC](https://discourse.itk.org/t/euler3dtransform-class-and-transforms-class/5332/8 "2022-10-19T13:21:00Z")

</div>

Sorry for super late reply, I was using version 2.1.1.2 - upgrading to 2.2.0 fixed it.

```auto
t = sitk.CompositeTransform(fitted_transform).GetBackTransform()
t.GetAngleX()

```
