Applying a transform from .tfm file in ITK

Hi,

I have a transform file in.tfm format that was created with 3D-slicer (attached it here for further reference). Now I’d like to read it from ITK and apply it to a specific point as in the example as in the example below.

def transformread(filename):
    """Read an itk Transform file.
    Parameters
    ----------
    filename:
        Path to the transform file (typically a .h5 file).
    Returns
    -------
    A Python list containing the transforms in the file.
    """
    reader = itk.TransformFileReaderTemplate[itk.D].New()
    reader.SetFileName(f"{filename}")
    reader.Update()

    transforms = []
    transform_list = reader.GetModifiableTransformList()
    while not transform_list.empty():
        transform = transform_list.pop()
        transforms.append(itk.down_cast(transform))
    transforms.reverse()

    return transforms

transforms = transformread('./Transform.tfm')
output_point = transforms[0].TransformPoint([-60.0, 59.0, 34.0])

My question is that, should I convert this transform from RAS to LPS before applying it to the point ? I’m asking because slicer typically models transforms in RAS coordinate system, whereas ITK uses LPS coordinate system. If this is the case, how can I convert it to the proper coordinate system for use with ITK?

Transform.tfm (195 Bytes)

I believe you should not need to do anything related to RAS/LPS differences. @jcfr or @lassoan could confirm.

Slicer stores all data in files in LPS coordinate system (to be compatible with DICOM and most other medical image computing software). Therefore, if your point coordinates are in LPS then you don’t need to deal with any LPS/RAS conversion.

However, ITK transforms store the resampling transform (fixed to moving image) and points must be transformed using the modelling transform, which is the inverse of the resampling transform.

If you have a composite transform (e.g., linear + bspline) then you can compute the inverse by splitting to the transform to components, and apply them the inverse of each component (you missed this inversion) in reverse order (you got this right).

Some years ago ITK could not compute inverse transform at a specific points (only invert an entire displacement field, which is extremely costly operation), so in 3D Slicer we chose VTK to do all real-time operations transformations (concatenate, invert, apply to images and meshes). I’m not sure if the situation in ITK has changed since then. @dzenanz do you know if ITK can compute an inverse transform dynamically at any specific location (without requiring computing an entire displacement field and then inverting that field)?

1 Like

I don’t think that was implemented. Maybe others, including @blowekamp, know more.

It is not clear to me what @isuruwi requirements are for performance or usage for the inverted transform here. I am not aware of @lassoan concerns being addressed in ITK, but I am also not certain they a relevant to the question and solution needed here.

If you want to transform points along with your image then you need the inverse transform (image transformation needs the resampling transform; point transformation needs the inverse of that - the modeling transform). If you transform a point set (e.g., with a few ten thousand points) and all you have from image registration is the resampling transform, then it is much faster if you can compute the inverse transform dynamically, only for those point positions that you want to transform (VTK transform classes can do this, it seems that ITK not yet), than computing a dense displacement field and then invert that field (ITK can do this).

At some point, it would be nice to bring VTK’s dynamic transform computation capabilities (on-demand computation of transformation at any point position by concatenation and inversion of all transform types) to ITK. Maybe by factoring out the computation classes into a common library and use it from both ITK and VTK.

1 Like