Transformation output files

Hi,

Slicer-4.13.0-2021-10-10-linux-amd64

I have a question regarding the format and content of the transformation matrix files outputted from the Slicer GUI versus the command-line. When manually performing a rigid registration within the Slicer GUI, I export the transformation matrix in .txt format and see the following:

#Insight Transform File V1.0
#Transform 0
Transform: AffineTransform_double_3_3
Parameters: 0.9960614071380222 0.030830015314365793 -0.08313352732766315 -0.004910023279263162 0.9553428038834216 0.29545899671453507 0.08853002248740502 -0.2938871164646019 0.951731473628198 -4.0468819155405775 -27.4418351879466 -24.1487889338481
FixedParameters: 0 0 0

I also ran the same registration in command-line:

Slicer --launch BRAINSFit --fixedVolume fixed_t1.nii --movingVolume moving_t1.nii --outputVolume moving-to-fixed_Slicer.nii.gz --transformType Rigid --linearTransform moving-to-fixed_Slicer.txt --initializeTransformMode useMomentsAlign

The moving-to-fixed_Slicer.nii.gz volume outputted from the CLI is the same as the one generated from the Slicer GUI, however, the content and format of the transformation matrix file from the CLI is different:

#Insight Transform File V1.0
#Transform 0
Transform: VersorRigid3DTransform_double_3_3
Parameters: -0.14915351589150105 -0.04344516579667238 -0.009045329415452575 -3.911482366131585 -27.683694094196184 -25.219819365762543
FixedParameters: 3.4742684230541063 4.699249757355889 -0.05058095645894013

Is there a reason for this difference? I’ve been able to use the transformation matrix manually outputted from the Slicer GUI for my workflow, and would like to automate the registration through the CLI. But I would like to have the same format as the transformation matrix manually exported from the GUI. Any help would be greatly appreciated.

Thanks,

Vinny

Hi,

When I run an affine registration between two images in the Slicer GUI vs CLI, the outputted images are again the same between the two, but the transformation matrices, although similar, are different enough to cause deviations when passing points through the transformations. Is this known behaviour or is there something that is missing from the CLI command. Here is the CLI command that I ran for the affine registration:

Slicer --launch BRAINSFit --fixedVolume fixed_t1.nii --movingVolume moving_t1.nii --outputVolume moving-to-fixed_SlicerCLI.nii.gz --transformType Affine --linearTransform affine_CLI.txt --initializeTransformMode useMomentsAlign

Here are the affine matrices from the GUI followed by CLI:

GUI:

#Insight Transform File V1.0
#Transform 0
Transform: AffineTransform_double_3_3
Parameters: 0.9969910985005138 0.0024328052157900973 0.07747793859880853 -0.02554949429826253 0.9539680535768614 0.2988179648144962 -0.07318451237688048 -0.29989837314256385 0.9511598146129817 0.5957013088022176 -9.779392222671147 11.091346021065451
FixedParameters: 0 0 0

CLI:

#Insight Transform File V1.0
#Transform 0
Transform: AffineTransform_double_3_3
Parameters: 0.9970411608367628 0.0022748824367199395 0.07743524660162743 -0.025350088753046847 0.9539358953134315 0.2987708368963429 -0.07316750434063589 -0.2998711858884665 0.950949958153532 0.18483120190382518 -11.850099009857114 8.735680954429876
FixedParameters: 1.7786384902690369 8.312981199696187 -5.499607555825423

Thanks,

Vinny

Slicer uses an RAS coordinate system internally, whereas ITK (and much of the rest of the medical imaging world) has settled on using an LPS coordinate system. Respecting this, exports from Slicer are automatically converted to use LPS, and imports from LPS are handled correctly. However, when you compare the internal representation of a transformation in Slicer with the same transformation in some other program they will not match because of the change in coordinate system.

I know I’ve seen this come up many times in the forum, so if you are looking for more information, keep searching here. Here is one related post I found:

1 Like

Thanks, I am aware of that particular script and have implemented it in my workflow. I found that I had to change the following line from:

ras2lps = np.diag([-1, -1, 1, 1])

to

ras2lps = np.diag([1, 1, -1, 1])

in order to get the same transformation as in the Slicer GUI.

Here is the transformation in Slicer GUI:

When I had employed the above script, I got the following output where the absolute values were similar (not exactly the same) but not the signs (+/-). See below screenshot:

After making the above change in the np.diag, I get the following output, which matches more closely with what’s reported in the Slicer GUI (still slight variation in the values):

the issue is I have ac and pc points given to me in voxel coordinates (from the original T1 image). I used nibabel to convert to physical coordinates. I’d like to bring these points into ac-pc space. I can do this relatively easy using the Slicer GUI. I’m running into problems when using the Slicer command line.

Thanks,

Vinny

The example conversion Python script in the script repository was incorrect. I don’t know where it has come from; it did something completely different than the C++ implementation and unsurprisingly, it did not compute correct results. I’ve replaced it now by a correct script.

1 Like

Thank you Andras, the revision works great.