I am running a radiomics project that requires segmentation/mask of medical imaging files. The simplest example is that MRI scans are rigidly registered to a CT scan and contours/segments applied.
The contours/segments are referenced to the CT scan at default and not the MRI. What I want is to resample the MRIs such that if the segments are loaded with the MRI that they align with the MRI.
In the DICOM header file for the registration file between the MR and CT there is a DICOM tag “FrameOfReferenceTransformationMatrix” which stores the information of the rigid registration of the MR to the CT. This consists of a list of 16 numbers ending with 0 0 0 1.
I’ve plugged in the numbers into a ITK file as follows
However the transform that is applied does not work in the way I want it to. The image IS resampled but it is not aligning to the same reference point as the CT. I’ve rearranged the matrix numbers but this doesn’t seem to help the problem. The only way to get alignment is to manually put in numbers.
If it is not working correctly, you might want to invert the transform or resample the other way around: resample segmentation to the image grid of the MRI.
Thanks for your response. After spending more time with the documentation i’ve realised that TranslationTransform was not the correct transform to use. Just a few more questions if possible
The transformation seems to be slightly misaligned (translation x,y seems a few mm off). It’s strange because when I use Slicer 3D with the same matrix the alignment is perfect. I’ve inverted the transform and resampled but none of these fix the problem. any thoughts? Is this a LPS vs RAS issue? This is the main problem i’m facing right now.
Some people have suggested using Versor3DRigid or Euler3DRigid transformations. From what I gather this is essentially the same as Affine without the skew/scale and using a different system to represent the rotations. For an image registration problem like this, is AffineTransform the usual default transform to use?
Rigid transforms are far more common than affine. Affine is usually used as a stage leading up to a deformable transform. Versor3DRigid has better computational properties than Euler3DRigid.
ITK and Slicer should have the same treatment of images and transforms. The difference of maybe half a pixel might be explainable, but more than that usually means you are not doing something exactly the same way.
I think what is happening is that with slicer, it’s reading in more information than I originally considered. It looks like the transform module automatically resamples and resizes images which i wasn’t doing in ITK. I was actually using another program plastimatch which was automatically doing that without me knowing.
It looks like i’ll have to go back to the drawing board with ITK/sitk and resample/resize/re-space images before running the transform.