InsightSoftwareConsortium / ITKElastix

An ITK Python interface to elastix, a toolbox for rigid and nonrigid registration of images
Apache License 2.0
198 stars 22 forks source link

Error when using keyword arguments for the itk.elastix_registration_method #212

Open ntatsisk opened 1 year ago

ntatsisk commented 1 year ago

It seems that itk.elastix_registration_method doesn't deduce image types correctly when keyword arguments are used for the images instead of just arguments. See minimal example:

import itk
import numpy as np

# Create 3D images
fixed_image = itk.image_from_array(np.random.rand(50, 50, 50).astype(np.float32))
moving_image = itk.image_from_array(np.random.rand(50, 50, 50).astype(np.float32))

# Create parameter object
parameter_object = itk.ParameterObject.New()
parameter_object.SetParameterMap(parameter_object.GetDefaultParameterMap('bspline'))

# This works fine
print("Registration ... ")
result_image, result_parameters = itk.elastix_registration_method(fixed_image, 
                                                                  moving_image, 
                                                                  parameter_object=parameter_object)

# The following doesn't work
print("Registration with keyword arguments ... ")
result_image, result_parameters = itk.elastix_registration_method(fixed_image=fixed_image, 
                                                                  moving_image=moving_image, 
                                                                  parameter_object=parameter_object)

And the output is:

Registration ...
Registration with keyword arguments ...
Traceback (most recent call last):
  File "C:\Users\kntatsis\work\keyword_argument_bug\keyword_bug.py", line 20, in <module>
    result_image, result_parameters = itk.elastix_registration_method(fixed_image=fixed_image,
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\support\helpers.py", line 176, in image_filter_wrapper
    return image_filter(*args, **kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py", line 756, in elastix_registration_method
    instance = itk.ElastixRegistrationMethod.New(*args, **kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\support\template_class.py", line 735, in New
    return self[list(keys)[0]].New(*args, **kwargs)
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\itkElastixRegistrationMethodPython.py", line 521, in New
    template_class.New(obj, *args, **kargs)
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\support\template_class.py", line 800, in New
    itk.set_inputs(self, args, kargs)
  File "C:\Users\kntatsis\miniconda3\envs\itk-elastix-env\lib\site-packages\itk\support\extras.py", line 1580, in set_inputs
    attrib(itk.output(value))
TypeError: Expecting argument of type itkImageF2 or itkImageSourceIF2.

I am not sure if it is discussed/documented somewhere else.

dzenanz commented 1 year ago

Maybe the first argument needs to be positional instead of keyword? @thewtex might know.

thewtex commented 1 year ago

Yes, we dispatch based on the type of the first positional argument (the fixed image).

ntatsisk commented 1 year ago

Thanks for the replies. If I understand correctly there is no plan for this to change for the moment so I guess only better documentation is required.

Related to that, in an ubuntu machine with a fresh environment and installing the ./binder/requirements.txt, I notice that testing the notebooks with pytest --nbmake --nbmake-timeout=3000 examples/*.ipynb leads to a similar error:

========================================================================================== short test summary info ===========================================================================================
FAILED examples/ITK_Example12_DifferentSizeTransformation.ipynb:: - TypeError: Expecting argument of type itkImageSS2 or itkImageSourceISS2.
FAILED examples/ITK_UnitTestExample6_PointSetTransformation.ipynb:: - TypeError: Expecting argument of type itkImageSS2 or itkImageSourceISS2.

I see kwargs instead of args are being used in ITK_Example12_DifferentSizeTransformation.ipynb so the error makes sense:

result_image_large = itk.transformix_filter( moving_image=moving_image_dense, transform_parameter_object=result_transform_parameters, log_to_console=False)

What is puzzling: how do these notebook tests pass in the CI?