ITKElastix icon indicating copy to clipboard operation
ITKElastix copied to clipboard

[Elastix Parameters --> ITK Transforms] Provide function to convert Elastix's TransformParameter.txt to ITK transforms

Open prerakmody opened this issue 4 years ago • 15 comments

Context

  • 3D Visualization software like 3D Slicer provide a larger number of visualization modules for different purposes.
  • One of the modules, the Transform module allows loading of .tfm files. These files can be created by using for e.g. sitk.WriteTransform(sitk.BSplineTransform(3), 'BSpline.tfm'). This Transform module is quite handy as it allows for easy visualization of the deformed grids of BSpline.

Is there a roadmap to include these kind of Elastix -> ITK Transform helper functions in ITKElastix?

prerakmody avatar Oct 22 '20 09:10 prerakmody

In the CZI project there are plans to write the elastix TransformParameters also as itk::Transform classes with the help of the itk::TransformFileWriter class, into an hdf5 format. Perhaps the tfm format can be considered also.

mstaring avatar Oct 22 '20 09:10 mstaring

Writing an ITK transform into .tfm file should be no different from writing into .h5.

dzenanz avatar Oct 22 '20 13:10 dzenanz

I already hoped that it would work the same as with images

mstaring avatar Oct 22 '20 13:10 mstaring

Note that with itk-5.2rc3, we can read and write itk.Transform's with itk.transformread and itk.transformwrite. These functions work with a Python list (an ordered sequence of transforms), supporting both tfm and h5 files.

thewtex avatar Mar 09 '21 18:03 thewtex

Discussed more in https://github.com/InsightSoftwareConsortium/ITKElastix/issues/110#issuecomment-794333942

thewtex avatar Mar 09 '21 19:03 thewtex

Has there been some progress on this front? I now need ITK<->Elastix transform equivalence, see simplified code below:

# use manually placed landmarks to initialize the registration
case_landmarks = read_slicer_fiducials('case.fcsv')
case_transform = register_landmarks(case_landmarks, atlas_landmarks)
print(composite_transform)
case_image = itk.imread('case.nrrd')

# Construct elastix parameter map
parameter_object = itk.ParameterObject.New()
resolutions = 4
parameter_map_rigid = parameter_object.GetDefaultParameterMap('rigid', resolutions)
parameter_object.AddParameterMap(parameter_map_rigid)
parameter_map_bspline = parameter_object.GetDefaultParameterMap("bspline", resolutions, 1.0)
parameter_object.AddParameterMap(parameter_map_bspline)
parameter_object.SetParameter("DefaultPixelValue", "-1024")  # we are dealing with CTs

# how do I add case_transform as the initial rigid transform? Inverse operations in @prerakmody's script?

registered, elastix_transform = itk.elastix_registration_method(case_image, atlas_image,
                                                                parameter_object=parameter_object)

final_composite_rigid_and_bspline_transform = ...  # is there anything newer/better than @prerakmody's script?
itk.tranformwrite(final_composite_rigid_and_bspline_transform, 'case-reg.tfm')  # save it to disk in ITK format

# now use the tranform to transfer atlast labels to the case under observation
nearest_interpolator = itk.NearestNeighborInterpolateImageFunction.New(atlas_label)
atlas_labels_transformed = itk.resample_image_filter(atlas_label,
                                                     use_reference_image=True,
                                                     reference_image=case_image,
                                                     transform=final_composite_rigid_and_bspline_transform,
                                                     interpolator=nearest_interpolator)
itk.imwrite(atlas_labels_transformed, 'case-label.nrrd', compression=True)

# continue processing
roi = # construct from atlas_labels_transformed by choosing only some labels
morphometry_filter = itk.BoneMorphometryFeaturesFilter.New(case_image)
morphometry_filter.SetMaskImage(roi)
morphometry_filter.Update()

With this output:

VersorRigid3DTransform (0000029684D682A0)
  RTTI typeinfo:   class itk::VersorRigid3DTransform<double>
  Reference Count: 1
  Modified Time: 18
  Debug: Off
  Object Name: 
  Observers: 
    none
  Matrix: 
    -0.868953 -0.49029 -0.0673497 
    0.472869 -0.782407 -0.405259 
    0.146 -0.383999 0.911718 
  Offset: [24.3469, 32.3288, 1.86287]
  Center: [0, 0, 0]
  Translation: [24.3469, 32.3288, 1.86287]
  Inverse: 
    -0.868953 0.472869 0.146 
    -0.49029 -0.782407 -0.383999 
    -0.0673497 -0.405259 0.911718 
  Singular: 0
  Versor: [ 0.0208332, -0.209063, 0.943806, 0.255126 ]

dzenanz avatar Jul 06 '21 21:07 dzenanz

Reference: https://github.com/SuperElastix/elastix/tree/develop/Testing/Data/Translation(1%2C-2)

thewtex avatar Jul 12 '21 16:07 thewtex

@thewtex

Reference: https://github.com/SuperElastix/elastix/tree/develop/Testing/Data/Translation(1%2C-2)

Explanation: The current "develop" branch of elastix supports elastix transform parameter files that link to an ITK generated HDF5 or TFM file. For example, this is a supported elastix transform parameters file: https://github.com/SuperElastix/elastix/blob/develop/Testing/Data/Translation(1%2C-2)/TransformParameters-link-to-ITK-tfm-file.txt In this case, it links to the following ITK transform file: https://github.com/SuperElastix/elastix/blob/develop/Testing/Data/Translation(1%2C-2)/ITK-Transform.tfm

(Such an elastix transform parameters file may be used as input for both Elastix (as initial transform parameter file) and Transformix.)

At the moment, four ITK transform types are actively tested as input to elastix: Translation, Affine, Euler, and Similarity. I'm still busy preparing to add tests for BSpline.

N-Dekker avatar Jul 12 '21 21:07 N-Dekker

Here is a WIP branch which I uses Elastix's ability to load ITK transform from a file: https://github.com/dzenanz/HASI/commit/f5ebf57864f991716a2f0076e0ee4ea4816c4129.

dzenanz avatar Jul 12 '21 21:07 dzenanz

BTW Elastix (develop branch) also has an experimental option to produce an ITK format TFM or a HDF5 file, as added by https://github.com/SuperElastix/elastix/pull/358

N-Dekker avatar Jul 12 '21 21:07 N-Dekker

A lot of work seems to have been done last year regarding this. What it the latest update here?

dzenanz avatar Feb 18 '22 15:02 dzenanz

Just a quick Q, do these transforms also store output spacing, size, etc. as elastix transforms do?

NHPatterson avatar Feb 18 '22 16:02 NHPatterson

ITK transforms operate in physical space. As such, they are unrelated to spacing or size of any particular image.

dzenanz avatar Feb 18 '22 17:02 dzenanz

Of course, my concern is more convenience of storing this information when doing elastix registrations.

NHPatterson avatar Feb 18 '22 17:02 NHPatterson

@N-Dekker perhaps we can have a notebook based on 0.16.0 that demonstrates how to do this?

thewtex avatar Feb 15 '23 11:02 thewtex