Open dzenanz opened 1 year ago
Applying an old trick from https://github.com/InsightSoftwareConsortium/ITKElastix/issues/79#issuecomment-878602486 seems to work, at least from the no-crashing point of view. Is this still the best way to do it? Why doesn't Elastix automatically combine two similarity transforms into one?
@dzenanz have you tried SetExternalInitialTransform
?
I tried it, but at the time ran into a different issue: #245.
So I tried:
parameter_object.WriteParameterFiles( elastix_transform, ["fiducial_transform.txt", str(output_dir / "rigid_transform.txt")], )
and it does not write the
fiducial_transform.txt
anywhere on the disk
Looks like that's the following issue:
I wasn't sure if it was worth fixing, because apparently it behaved like that for more than five years already. So that's why it's still open. ParameterObject::WriteParameterFile
still works well for a single parameter map, fortunately.
With itk-elastix
0.19.0 and code from https://github.com/InsightSoftwareConsortium/ITKElastix/issues/245#issuecomment-1721253341,
parameter_object.WriteParameterFiles(
elastix_transform_parameters,
["fiducial_transform.txt", "rigid_transform.txt"])
produces both files, but content of fiducial_transform.txt
is this:
(NumberOfParameters 0)
(Transform "ExternalTransform")
(TransformAddress "000001FF3C274330")
and subsequent run fails with:
itk::ExceptionObject (000000712F3E9F80)
Location: "ElastixTemplate - Run()"
File: D:\a\im\_skbuild\win-amd64-3.9\cmake-build\_deps\elx-src\Components\Transforms\ExternalTransform/elxAdvancedTransformAdapter.h
Line: 146
Description: ITK ERROR: AdvancedTransformAdapter(0000021F3508AA80): Not implemented for AdvancedTransformAdapter
Error occurred during actual registration.
With
itk-elastix
0.19.0 and ... produces both files, but content offiducial_transform.txt
is this:(NumberOfParameters 0) (Transform "ExternalTransform") (TransformAddress "000001FF3C274330")
If you do elastix_registration_method_object.SetOutputDirectory(
an-existing-directory)
and then run the registration, does it produce the transform parameter files properly? (In the specified output directory, I mean.)
The initial registration does that (produce those files).
ElastixRegistrationMethod::GenerateData()
has some code to specifically write an "ExternalTransform" to a separate ITK compatible transform file, either ".tfm" or ".h5". It's not yet clear to me how to make that functionality available to ParameterObject.WriteParameterFiles
. Do you think it's necessary anyway? Or is it sufficient to just let elastix write the transform files to the output directory specified by SetOutputDirectory?
I am using ParameterObject.WriteParameterFiles
to create initial transform for the next stage of registration.
ElastixRegistrationMethod::GenerateData() has some code to specifically write an "ExternalTransform" to a separate ITK compatible transform file
As I wrote earlier, I am doing this manually now. It would be good if WriteParameterFiles
took care of that when appropriate.
@dzenanz Sorry, can you please clarify your use case? Do I understand correctly that you have a similarity transform, created outside of elastix? Do you have it stored in an ITK ".tfm" or ".h5" file already?
Elastix supports specifying an external ".tfm" or ".h5" file as "TransformFileName" parameter, in an elastix transform parameter map or a transform parameter txt file:
(This support is only implemented for ITK transform files that represent AffineTransform, BSplineTransform, Euler2D, Euler3D, Similarity2D, Similarity3D, TranslationTransform, or a Composite of them.)
Does that help you any further?
The use case is: use landmarks to create an initial transform, then use that to initialize first stage of registration, then result of that to initialize the next stage etc. I explained it a bit here: https://github.com/InsightSoftwareConsortium/ITKElastix/issues/245#issuecomment-1717995997.
I already have a working code, via a workaround of providing the initial transform via TransformFileName
, as described here: https://github.com/InsightSoftwareConsortium/ITKElastix/issues/79#issuecomment-878602486.
It would be good if this workaround was not needed. If fixing that has lousy cost/benefit ratio, than this issue can be closed.
We need to further investigate how ParameterObject.WriteParameterFiles
should deal with the "ExternalTransform" feature. You see, it's a bit tricky, because the pointer to the external transform may be dangling, once the ParameterObject is written to file. It's on our TODO list, thanks.
Why there are no functions to read/write and convert between both transforms?
e.g. something like:
elxTransform = readElastixTransform(elastixTransformFilePath)
itkTranform = convertElastix2ItkTransform(elxTranform)
writeItkTransform(itkTransformFilePath)
itkTransform = readItkTransform(itkTransformFilePath)
elxTranform = convertItk2ElastixTransform(itkTransform)
writeElastixTransform(elastixTransformFilePath)
I have corresponding fiducial points between a pair of images. I use it to compute similarity transform. What is the best way to pass this as initial transform? See #245 for an attempt.
Setting it via
SetInitialTransform
seems to work (the compound registration does not work correctly in Slicer unless it is "split"), but a later call to:produces:
So I tried:
and it does not write the
fiducial_transform.txt
anywhere on the disk, withrigid_transform.txt
having the following content:Passing
rigid_transform.txt
viaSetInitialTransformParameterFileName
to the next (BSpline) stage of registration produces an error:If I do not provide initial transform to the first registration phase, the whole pipeline works - with imperfect results.