question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Get Affine Transformation Matrix from TransformParameters

See original GitHub issue

I’m using ITK to perform a affine coregistration on 3D MRI scans. Now similar to what is suggested in https://github.com/InsightSoftwareConsortium/ITKElastix/blob/master/examples/ITK_Example08_SimpleTransformix.ipynb I would like to perform the affine transformation on another image but we are using another library for that.

So I would need a full affine matrix for the transformation that describes the affine coregistration.

I noticed that the registration returns the transform parameters:

result_image, result_transform_parameters = itk.elastix_registration_method( ...
parameter_map = transform_parameters.GetParameterMap(0)
transform_parameters = np.array(parameter_map['TransformParameters'], dtype=float)

From other GitHub issues I gathered that the last 3 values of the 12 values in transform_parameters is for the translation and the first 9 are for the rotation. Not sure if that is correct.

Based on this I started playing around and got close to the correct affine transformation matrix (the resulting images are similar but not quite right).

rotation = transform_parameters[:9].reshape(3, 3)
translation = transform_parameters[-3:][..., np.newaxis]
translation = -np.flip(translation)
reg_affine: np.ndarray = np.append(rotation, translation, axis=1) 
reg_affine = np.append(reg_affine, [[0,0 ,0,1]], axis=0) 

The translation might be right but the rotation is slightly off. What am I missing / what is wrong? Also why do I need to flip and negate the translation? Do I need to do something similar with the rotation matrix?

Would really appreciate some insight. The ITK methods are a blackbox to me.


Not sure what example data I can share. Here some example values for the above variables:

transform_parameters = [ 9.98573286e-01, -3.92533565e-03, -7.45617495e-03,  6.11828178e-04,
                        9.98081930e-01,  7.21948277e-03,  2.74329272e-03, -1.22292851e-02,
                        1.00763651e+00, -1.52612188e-01,  8.89476641e-01,  2.55258072e+00]

with the resulting affine matrix:

reg_affine = [[ 1.00763651e+00, -1.22292851e-02,  2.74329272e-03, -2.55258072e+00],
             [ 7.21948277e-03,  9.98081930e-01,  6.11828178e-04, -8.89476641e-01],
             [-7.45617495e-03, -3.92533565e-03,  9.98573286e-01, 1.52612188e-01],
             [ 0.00000000e+00,  0.00000000e+00,  0.00000000e+00, 1.00000000e+00]

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:28 (12 by maintainers)

github_iconTop GitHub Comments

1reaction
ntatsiskcommented, Dec 19, 2022

Hi @Spenhouet, I undestand that it has been long since you raised this issue and maybe your project has moved forward by now. However, I just created a PR here https://github.com/InsightSoftwareConsortium/itk-torch-transform-bridge/pull/6 that seems to do what you were aiming to do. In particular, the test_regisration() function inside the test_cases.py file is tested (locally at my pc) using the data that you shared here (fixed_2mm.nii.gz, moving_2mm.nii.gz) and does a registration with Elastix and then transforms affinely using MONAI. Hopefully, this is helpful to you.

Some notes:

  • The PR is still draft so likely to change soon
  • I am using ITK to read the images instead of nibabel because I think the problem gets even more complicated otherwise. I don’t know if it was a requirement for you to use nibabel in the first place.
  • I had trouble loading real_fixed.nii.gz, real_moving.nii.gz using ITK for some reason, and that’s why I used the original images that you shared.

Let me know if you have any comments, or if you happen to test the code and it works for you. Any feedback will help improve the PR as well.

1reaction
Spenhouetcommented, Mar 18, 2022

@mstaring @dzenanz A classic happened: For the example sample our code works now, and the solution also makes sense but we did now run into a sample where it does not work. I’m expecting that you were both right that we do in fact need to also factor in the center of rotation. But we struggle again to get how. We already considered the formula you shared and also did more research. I did again post the full question here: https://stackoverflow.com/questions/71529039/how-factor-the-itk-centerofrotationpoint-in-a-affine-transformation-matrix

Maybe you could have a look if you see an obvious mistake or answer.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to factor the ITK CenterOfRotationPoint in an affine ...
Where A is the direction/rotation matrix, t the translation matrix, c the center of rotation (CoR), and moving_ras the affine of the moving ......
Read more >
itk::AffineTransform< TParametersValueType, VDimension ...
An affine transformation is defined mathematically as a linear transformation plus a constant offset. If A is a constant n x n matrix...
Read more >
Affine transformation — PROJ 9.1.1 documentation
The affine transformation applies translation and scaling/rotation terms on the x,y,z coordinates, and translation and scaling on the temporal coordinate.
Read more >
Transform Parameters - elastix
MatrixTranslation : the parameters as matrix and translation, so written in the same way as the parameters of the normal AffineTransform. ... This...
Read more >
Affine transformation - Wikipedia
In Euclidean geometry, an affine transformation or affinity is a geometric transformation that preserves lines and parallelism, but not necessarily ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found