SuperElastix / SimpleElastix

Multi-lingual medical image registration library
http://simpleelastix.github.io
Apache License 2.0
509 stars 149 forks source link

How to get Affine matrix resulting from a rigid or affine registration #441

Open romainVala opened 2 years ago

romainVala commented 2 years ago

Hello

sorry if I miss the documentation, but I could not find the information Does someone has a simple example to get the final Affine resulting from a affine coregistration between 2 volumes ?

romainVala commented 2 years ago

I dig a little bit more, and get this :

So I start witht a basic Rigid coregistration with

elastixImageFilter = sitk.ElastixImageFilter()
elastixImageFilter.SetFixedImage(sitk.ReadImage("fixedImage.nii"))
elastixImageFilter.SetMovingImage(sitk.ReadImage("movingImage.nii"))
elastixImageFilter.SetParameterMap(sitk.GetDefaultParameterMap("rigid"))
elastixImageFilter.Execute()
sitk.PrintParameterMap(elastixImageFilter.GetTransformParameterMap() ) 
ParameterMap 0: 
  (CenterOfRotationPoint 0.650002 17.500000 18.650000)
  (CompressResultImage "false")
  (ComputeZYX "false")
  (DefaultPixelValue 0.000000)
  (Direction 1.000000 0.000000 0.000000 0.000000 -1.000000 0.000000 0.000000 0.000000 1.000000)
  (FinalBSplineInterpolationOrder 3.000000)
  (FixedImageDimension 3.000000)
  (FixedInternalImagePixelType "float")
  (HowToCombineTransforms "Compose")
  (Index 0.000000 0.000000 0.000000)
  (InitialTransformParametersFileName "NoInitialTransform")
  (MovingImageDimension 3.000000)
  (MovingInternalImagePixelType "float")
  (NumberOfParameters 6.000000)
  (Origin -89.849998 126.000000 -71.849998)
  (ResampleInterpolator "FinalBSplineInterpolator")
  (Resampler "DefaultResampler")
  (ResultImageFormat "nii")
  (ResultImagePixelType "float")
  (Size 182.000000 218.000000 182.000000)
  (Spacing 1.000000 1.000000 1.000000)
  (Transform "EulerTransform")
  (TransformParameters 0.000018 -0.000087 0.000036 9.998980 10.012400 -10.002100)
  (UseDirectionCosines "true")

It looks like TransformParameters contains the 6 euler parameters, (3 rotation and 3 translation) and I could try and test to deduce the correct Affine, but there should be some function that already do that properly ... ? (it seems to me that it is a quite common usecase ...)

romainVala commented 2 years ago

Ok I found almost the solution: if one do a affine registration (thanks to @kaspermarstal https://github.com/SuperElastix/SimpleElastix/issues/91#issuecomment-300691102 I thing it works the same but with a EulerTransform we get after a rigid registration. But how to build the rotation matrix ?

If I may change your notation, instead of T(x) = A ( x - c ) + t + c I would write Transform(x) = A*x = R(x-c) + t + c where R is the rotation matrix ( 3*3) A 4*4 matrix and x is the homogeneous vector [x,1] ) Thus to get the Affine matrix A A = [ R | T ] (concatenate R and T, and a line [0,0,0,1] ) T = t + c - R*c R = ...