-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
External initial transform causes a failure in ConvertToItkTransform #245
Comments
If this is expected behavior, perhaps documentation could be improved. What is the difference between |
Thanks for reporting this issue, @dzenanz Can you please post the complete code example? Or at least tell me how I just tried passing an |
def register_landmarks(fixed_landmarks, moving_landmarks):
transform_type = itk.Transform[itk.D, 3, 3]
landmark_transformer = itk.LandmarkBasedTransformInitializer[transform_type].New()
rigid_transform = itk.Similarity3DTransform[itk.D].New()
landmark_transformer.SetFixedLandmarks(fixed_landmarks)
landmark_transformer.SetMovingLandmarks(moving_landmarks)
landmark_transformer.SetTransform(rigid_transform)
landmark_transformer.InitializeTransform()
return rigid_transform
def main():
print("Fiducial registration")
fixed_fiducials = read_slicer_fiducials(fixed_pts_fpath)
moving_fiducials = read_slicer_fiducials(moving_pts_fpath)
fiducial_transform = register_landmarks(fixed_fiducials, moving_fiducials)
# write to file to work around this bug
itk_fiducial_filename = str(output_dir / "fiducial_transform.tfm")
elx_fiducial_filename = str(output_dir / "fiducial_transform.txt")
itk.transformwrite([fiducial_transform], itk_fiducial_filename)
out_elastix_transform = open(elx_fiducial_filename, "w")
out_elastix_transform.writelines(['(Transform "File")\n',
'(TransformFileName "./fiducial_transform.tfm")\n'])
out_elastix_transform.close()
# invoke ITKElastix |
Thanks @dzenanz I made that an issue: |
@dzenanz Sorry I still haven't been able to reproduce the error you reported, "Failed to convert transform object SimilarityTransformElastix". Would it be possible for you to post a minimal example to reproduce the issue, that I could simply copy-and-paste into a Jupyter Notebook? In the mean time, Marius (@mstaring) already pinpointed some limitations of the use of an external initial transform to me. It appears that some very specific metrics components may not support an external initial transform. Specifically "TransformBendingEnergyPenalty" (and maybe some other metrics as well). To be investigated. However, when the specified metric does not allow using an external initial transform, a different error message will appear, saying "Not implemented for AdvancedTransformAdapter" To be continued... |
Below is the code which triggers the error. To be used from a jupyter notebook or a script in examples directory. I based it on https://github.com/InsightSoftwareConsortium/ITKElastix/blob/4fbdc9c9ca32aa740d8842c0892b817cf8ef0f41/examples/ITK_Example04_InitialTransformAndMultiThreading.ipynb.
import itk
# Import Images
fixed_image = itk.imread('data/CT_2D_head_fixed.mha', itk.F)
moving_image = itk.imread('data/CT_2D_head_moving.mha', itk.F)
# Import Default Parameter Map
parameter_object = itk.ParameterObject.New()
parameter_map_rigid = parameter_object.GetDefaultParameterMap('rigid')
parameter_map_rigid['Transform'] = ['SimilarityTransform']
parameter_object.AddParameterMap(parameter_map_rigid)
# Load Elastix Image Filter Object with initial transfrom and number of threads
elastix_object = itk.ElastixRegistrationMethod.New(fixed_image,moving_image)
elastix_object.SetParameterObject(parameter_object)
initial_transform = itk.Similarity2DTransform[itk.D].New()
elastix_object.SetExternalInitialTransform(initial_transform)
# Set additional options
elastix_object.SetLogToConsole(False)
# Update filter object (required)
elastix_object.UpdateLargestPossibleRegion()
# Results of Registration
result_image = elastix_object.GetOutput()
comb_transform = elastix_object.GetCombinationTransform()
itk_transform = elastix_object.ConvertToItkTransform(comb_transform)
elastix_transform_parameters = elastix_object.GetTransformParameterObject() |
Thansk @dzenanz Looks like it can be further reduced to: import itk
fixed_image = itk.imread('data/CT_2D_head_fixed.mha', itk.F)
moving_image = itk.imread('data/CT_2D_head_moving.mha', itk.F)
parameter_object = itk.ParameterObject.New()
parameter_map_rigid = parameter_object.GetDefaultParameterMap('rigid')
parameter_object.AddParameterMap(parameter_map_rigid)
elastix_object = itk.ElastixRegistrationMethod.New(fixed_image,moving_image)
elastix_object.SetParameterObject(parameter_object)
initial_transform = itk.Similarity2DTransform[itk.D].New()
elastix_object.SetExternalInitialTransform(initial_transform)
elastix_object.Update()
comb_transform = elastix_object.GetCombinationTransform()
itk_transform = elastix_object.ConvertToItkTransform(comb_transform) Right? Which produces:
|
I just tried to do the very same in C++: using ImageType = itk::Image<float>;
const auto fixed_image = itk::ReadImage<ImageType>("data/CT_2D_head_fixed.mha");
const auto moving_image = itk::ReadImage<ImageType>("data/CT_2D_head_moving.mha");
const auto parameter_object = elx::ParameterObject::New();
const auto parameter_map_rigid = elx::ParameterObject::GetDefaultParameterMap("rigid");
parameter_object->AddParameterMap(parameter_map_rigid);
const auto elastix_object = itk::ElastixRegistrationMethod<ImageType, ImageType>::New();
elastix_object->SetFixedImage(fixed_image);
elastix_object->SetMovingImage(moving_image);
elastix_object->SetParameterObject(parameter_object);
const auto initial_transform = itk::Similarity2DTransform<double>::New();
elastix_object->SetExternalInitialTransform(initial_transform);
elastix_object->Update();
const auto comb_transform = elastix_object->GetCombinationTransform();
const auto itk_transform = elastix_object->ConvertToItkTransform(*comb_transform);
But in C++, it seems to work fine: no error, no exception! Do you have a clue? |
Nothing better than " |
I think this issue should have been fixed by:
Could it be that that PR is not yet included with your ITKElastix version? |
Without that PR, there is an error "there is no |
PR SuperElastix/elastix#949 was merged to SuperElastix/elastix/main on August 22. While itk-elastix-0.18.0 was released before, on August 17: https://github.com/InsightSoftwareConsortium/ITKElastix/releases/tag/v0.18.0 I think the elastix PR still has to be included with ITKElastix. The next release...! |
Hopefully you can update elastix via a PR? Bumping the version number in |
Using parameter_object.WriteParameterFile(elastix_transform_parameters, "rigid_transform.txt") causes this error:
Is different code needed now? Or do we need a fix in elastix and to update version within itk-elastix? |
If
Does that help already? Otherwise I'd have to try it myself. |
I tried the plural version, and it has its own problem: #246 (comment). |
produces:
The code does not crash if
elastix_object.SetInitialTransform(initial_transform)
orelastix_object.SetInitialTransformParameterFileName(initial_transform_txt_path)
is invoked instead.The text was updated successfully, but these errors were encountered: