smeisler
(Steven Meisler)
July 10, 2024, 8:20pm
1
Hello community,
I have a .txt file describing a 6-param rigid body alignment output from AFNI 3dvolreg, converted to ITK style. It has 383 transforms, each one corresponding to a volume to the timeseries it is associated with. The first few and last one are listed below:
#Insight Transform File V1.0
#Transform 0
Transform: AffineTransform_double_3_3
Parameters: 1 -8.57331e-05 -2.12192e-05 8.57352e-05 1 9.70602e-05 2.12109e-05 -9.7062e-05 1 0.00492098 -0.0215674 0.0185717
FixedParameters: 0 0 0
#Transform 1
Transform: AffineTransform_double_3_3
Parameters: 1 0.000548586 0.000161739 -0.000548728 0.999999 0.000881086 -0.000161255 -0.000881175 1 -6.95764e-05 -0.0130985 -0.0357127
FixedParameters: 0 0 0
#Transform 2
Transform: AffineTransform_double_3_3
Parameters: 1 0.000680698 0.000177318 -0.000680773 1 0.000424417 -0.000177029 -0.000424537 1 -0.0124846 -0.0175981 -0.132785
FixedParameters: 0 0 0
........
#Transform 382
Transform: AffineTransform_double_3_3
Parameters: 0.999996 0.00230603 0.00149425 -0.00229953 0.999988 -0.00433795 -0.00150424 0.0043345 0.999989 0.0429203 0.174521 -0.231928
FixedParameters: 0 0 0
My goal is to convert this to an .h5 file for compatibility with some of our registration workflows. What I was trying was something like this:
import SimpleITK as sitk
txt_xfm_path = "/path/to/xfm.txt" # File described above
h5_out = "/path/to/xfm.h5" # Desired output file
txt_xfm = sitk.ReadTransform(xfm_path)
xfm_obj = sitk.AffineTransform(txt_xfm)
sitk.WriteTransform(xfm_obj, h5_out)
While this doesn’t throw an error, I get a warning when loading the txt file:
WARNING: In /home/conda/feedstock_root/build_artifacts/libsimpleitk_1701713288428/work/Code/Common/src/sitkTransform.cxx, line 674
There is more than one transform in the file! Only using the first transform.
Is there a way I can load the file and use all of the embedded transforms?
Thanks,
Steven
dzenanz
(Dženan Zukić)
July 10, 2024, 9:04pm
2
That should be possible using ITK (instead of SimpleITK). Transform-related code sample here should get you started.
smeisler
(Steven Meisler)
July 10, 2024, 9:22pm
3
Great, thanks for pointing me there! Yes, it looked like the following worked:
import itk
txt_xfm_path = '/path/to/xfm.txt'
h5_out = "/path/to/xfm.h5"
txt_xfm = itk.transformread(txt_xfm_path)
itk.transformwrite(txt_xfm, h5_out)
Still yet to see if this works with our pipeline as expected, but at the very least, I could say with more confidence that all transforms are contained in that output H5.
Best,
Steven
1 Like
cookpa
(Philip Cook)
July 10, 2024, 10:27pm
4
I have made composite transforms using SimpleITK, using
composite = sitk.CompositeTransform(list_of_transform_objects) sitk.WriteTransform(composite, outFile)
As always, the order of transforms (and whether they need to be inverted with a call to GetInverse()) is important!
EDIT: But it seems SimpleITK won’t read multiple transforms from a txt file.
blowekamp
(Bradley Lowekamp)
July 10, 2024, 11:14pm
5
I had not seen this use case before.
Please add a feature request to the SimpleITK Github issues: Issues · SimpleITK/SimpleITK · GitHub
cookpa
(Philip Cook)
July 11, 2024, 1:48pm
6
Thanks @blowekamp , added
opened 01:47PM - 11 Jul 24 UTC
Feature Request
**Is the feature request related to a problem? Please describe.**
As reported… on [discourse](https://discourse.itk.org/t/simpleitk-convert-txt-to-h5/7041)
Given a list of affine transforms in a single text file, eg
```
#Insight Transform File V1.0
#Transform 0
Transform: AffineTransform_double_3_3
Parameters: 1 -8.57331e-05 -2.12192e-05 8.57352e-05 1 9.70602e-05 2.12109e-05 -9.7062e-05 1 0.00492098 -0.0215674 0.0185717
FixedParameters: 0 0 0
#Transform 1
Transform: AffineTransform_double_3_3
Parameters: 1 0.000548586 0.000161739 -0.000548728 0.999999 0.000881086 -0.000161255 -0.000881175 1 -6.95764e-05 -0.0130985 -0.0357127
FixedParameters: 0 0 0
#Transform 2
Transform: AffineTransform_double_3_3
Parameters: 1 0.000680698 0.000177318 -0.000680773 1 0.000424417 -0.000177029 -0.000424537 1 -0.0124846 -0.0175981 -0.132785
FixedParameters: 0 0 0
```
ITK can read this into a list of transforms
```
>>> import itk
>>> txt_xfm = itk.transformread('transform_list.txt')
>>> txt_xfm
[<itk.itkAffineTransformPython.itkAffineTransformD3; proxy of <Swig Object of type 'itkAffineTransformD3 *' at 0x7ff198551b10> >, <itk.itkAffineTransformPython.itkAffineTransformD3; proxy of <Swig Object of type 'itkAffineTransformD3 *' at 0x7ff1985466f0> >, <itk.itkAffineTransformPython.itkAffineTransformD3; proxy of <Swig Object of type 'itkAffineTransformD3 *' at 0x7ff198551a80> >]
>>>
```
However, SimpleITK will only read the first one
```
>>> import SimpleITK as sitk
>>> transform = sitk.ReadTransform('transform_list.txt')
WARNING: In /Users/runner/work/1/sitk/Code/Common/src/sitkTransform.cxx, line 674
There is more than one transform in the file! Only using the first transform.
```
**Describe the proposed solution**
Return the list of transforms for consistency with ITK Python.
**Describe any alternatives to consider**
Return a composite transform.
**Additional context**
1 Like