Unexpected rigid transformation when called from python

Hi there,

if I rigidly register two volumes within Slicer using the Elastix module, everything is as expected. However, when called from Python, I encountered unexpected behavior. The code worked using Slicer 4.11 and Elastix 5.0.1, the issues appeared using Slicer 5.2.2 and Elastix 5.1.0:

  1. transform matrix is not shown in transform module
    expected:
    expected_transform
    got:
    got_transform

  2. When exporting the resulting transformation to file, the .tfm file is gigantic with >700MB, normally it’s just the transformation matrix and a few KB in size.

Here’s the relevant python code:

 elastixLogic = Elastix.ElastixLogic()
 # create result transform
 slicer.mrmlScene.AddNewNodeByClass('vtkMRMLTransformNode', result_transform_name)
 # register
 elastixLogic.registerVolumes(get_node_by_name(slicer, fixed_name),
                           get_node_by_name(slicer, moving_name),
                           parameterFilenames=[path_params_rigid],
                           outputTransformNode=get_node_by_name(slicer,
                                                                result_transform_name))

get_node_by_name() just calls slicer.util.getNode()

I checked the rigid parameter file, it correctly uses a local copy of Parameters_Rigid.txt from the
https://github.com/lassoan/SlicerElastix/blob/master/Elastix/Resources/RegistrationParameters/Parameters_Rigid.txt repo, which is consistent with the file in AppData (path see below).

As a reference also the Elastix output when called manually via the Elastix module UI within Slicer:

which elastix:   C:\Users\steph\AppData\Local\NA-MIC\Slicer 5.2.2\NA-MIC\Extensions-31382\SlicerElastix\lib\Slicer-5.2\elastix.exe
  elastix version: 5.1.0
  Git revision SHA: d652938573e5f193955908eba225a854b31ce36a
  Git revision date: Thu Jan 12 14:20:18 2023 +0100
  Build date: Apr 25 2023 06:37:51
  Compiler: Visual C++ version 193532217.1
  Memory address size: 64-bit
  CMake version: 3.22.1
  ITK version: 5.3.0

Command-line arguments:
  -f C:/Users/steph/AppData/Local/Temp/Slicer/Elastix/20230816_103312_020\input\fixed.mha 
-m C:/Users/steph/AppData/Local/Temp/Slicer/Elastix/20230816_103312_020\input\moving.mha 
-out C:/Users/steph/AppData/Local/Temp/Slicer/Elastix/20230816_103312_020\result-transform 
-p "C:\Users\steph\AppData\Local\NA-MIC\Slicer 5.2.2\NA-MIC\Extensions-31382\SlicerElastix\lib\Slicer-5.2\qt-scripted-modules\Resources\RegistrationParameters\Parameters_Rigid.txt"

What could be the issue here? Note that the python generated transformation is still fine, I can apply and correctly transform volumes with it.

Thanks!

any update on this post?

I know that the Elastix module code changed since 5.0.1 because some of my module code which was using it broke in 5.2.2 (I haven’t figured out how to fix it yet, so I just know there was a breaking change). As a simple first attempt, I would suggest that you try forcing the result transform to be linear and see if that works:

slicer.mrmlScene.AddNewNodeByClass('vtkMRMLLinearTransformNode', result_transform_name)

Perhaps the Elastix module is now detecting the type of the transform node, and if it is a general transform node it returns a displacement field transform rather than the previously expected linear matrix. If I recall correctly, the displacement field transform is the default output of Elastix registration, and there was some code in the Elastix module which tried to detect the special case where a linear transformation matrix could be returned instead and converted it. Perhaps that check is now only run if the output transformation node type seems to call for it.

1 Like

By default, displacement field is requested as registration output. Probably this choice was kept for backward compatibility (for a good while Elastix was not able to write ITK transforms and so it was safer and simpler to get a displacement field).

If you want to get a linear transform then you can add the forceDisplacementFieldOutputTransform=False argument to the registerVolumes call.

1 Like

Perfect thanks! Adding the flag solved the issue :ok_hand:

1 Like