Read Transform - Apply to VersorRigid3DTransform

I’ve been trying to read a transform from disk (VersorRigid3DTransform saved previously) and then feed it into the VersorRigid3DTransform class so that I can get access to the original parameters like: Matrix, Translation, etc.


transform = sitk.ReadTransform('path/to/transform.tfm')
versor = sitk.VersorRigid3DTransform(transform)

However, when I run this I get a runtime / sitk error:

RuntimeError: Exception thrown in SimpleITK new_VersorRigid3DTransform: ../../Code/Common/src/sitkVersorRigid3DTransform.cxx:177:
sitk::ERROR: Transform is not of type Transform!

For some reason, sitk is not identifying the transform as a transform.

I can print(transform) and it appears as a itk::simple::Transform as expected.:

 CompositeTransform (0x55ba8a2f48f0)
   RTTI typeinfo:   itk::CompositeTransform<double, 3u>
   Reference Count: 1
   Modified Time: 993
   Debug: Off
   Object Name: 
   Transforms in queue, from begin to end:
   VersorRigid3DTransform (0x55ba8a3388d0)
     RTTI typeinfo:   itk::VersorRigid3DTransform<double>
     Reference Count: 1
     Modified Time: 989
     Debug: Off
     Object Name: 
       0.999942 -0.0101886 0.0035472 
       0.0101895 0.999948 -0.000234057 
       -0.00354463 0.000270188 0.999994 
     Offset: [1.11228, 0.0329762, 0.545213]
     Center: [-66.7903, -3.167, 1.79558]
     Translation: [1.15481, -0.647841, 0.781093]
       0.999942 0.0101895 -0.00354463 
       -0.0101886 0.999948 0.000270188 
       0.0035472 -0.000234057 0.999994 
     Singular: 0
     Versor: [ 0.000126063, 0.00177298, 0.00509461, 0.999985 ]
   End of MultiTransform.
   TransformsToOptimizeFlags, begin() to end(): 
   TransformsToOptimize in queue, from begin to end:
   End of TransformsToOptimizeQueue.
   End of CompositeTransform.

This syntax also matches a stackoverflow response by @blowekamp:

Any ideas on what might be causing the issue?

Hello @gattia,

You wrote the transform as a CompositeTransform inside of which you have a VersorRigid3DTransform, so that is why it is failing.

Example code illustrating that saving and reading a VersorRigid3DTransform works:

import SimpleITK as sitk

tx = sitk.VersorRigid3DTransform()

sitk.WriteTransform(tx, 'my_transform.tfm')
transform = sitk.ReadTransform('my_transform.tfm')
versor = sitk.VersorRigid3DTransform(transform)

Thanks, @zivy!

Is there a way to get the original transform out using sitk? Or does it have to be re-saved as a pure VersorRigid3DTransform() in the first place?

Hello @gattia,

Yes, you can read it from the file, just requires a cast to CompositeTransform and getting the last transform from its stack:

transform = sitk.ReadTransform('my_transform.tfm')
# Cast the Transform to CompositeTransform and get the back transform
# which is a versor 
versor = sitk.CompositeTransform(transform).GetBackTransform()
1 Like

Thanks! And Im guessing this requires sitk >2.0?. Im currently using an older version and tried something like this, but it doesn’t work since sitk 1.x doesn’t have CompositeTransform (as far as I can tell).

I can “probably” upgrade without other downstream problems. But just want to make sure before I open up that can of worms.

Yes, you are correct, this is with the 2.x SimpleITK interface. The old interface didn’t provide access to internal transformations in the stack of a composite transformation and had other limitations.

I highly recommend moving to the new 2.x releases if you can. Many improvements and bug fixes (see release notes for 2.0). We tried to keep the interface backwards compatible, as much as we could. There is a migration guide online, so take a look at that before you make your decision.

1 Like

Thanks for confirming. This might be the final push that makes me switch. Its been on the list of to dos, but wasnt worth the work before. Might need to now :).

Thanks again for helping guide me through this.


1 Like