ITKElastix
ITKElastix copied to clipboard
[Elastix Parameters --> ITK Transforms] Provide function to convert Elastix's TransformParameter.txt to ITK transforms
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?
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.
Writing an ITK transform into .tfm
file should be no different from writing into .h5
.
I already hoped that it would work the same as with images
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.
Discussed more in https://github.com/InsightSoftwareConsortium/ITKElastix/issues/110#issuecomment-794333942
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 ]
Reference: https://github.com/SuperElastix/elastix/tree/develop/Testing/Data/Translation(1%2C-2)
@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.
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.
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
A lot of work seems to have been done last year regarding this. What it the latest update here?
Just a quick Q, do these transforms also store output spacing, size, etc. as elastix transforms do?
ITK transforms operate in physical space. As such, they are unrelated to spacing or size of any particular image.
Of course, my concern is more convenience of storing this information when doing elastix registrations.
@N-Dekker perhaps we can have a notebook based on 0.16.0 that demonstrates how to do this?