Skip to content
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

Compile with different pixel types? #137

Closed
NHPatterson opened this issue Oct 28, 2021 · 19 comments
Closed

Compile with different pixel types? #137

NHPatterson opened this issue Oct 28, 2021 · 19 comments

Comments

@NHPatterson
Copy link

Is it possible to compile the wrapped elastix to support pixel types other than float32? I do a lot of registration with very large microscopy planes and having just an unsigned short pixel type would save a lot of memory. I'm happy to try things out on my end if anyone could point me to the relevant code..

Thanks!

@N-Dekker
Copy link
Collaborator

@NHPatterson Thanks for your question, Heath. Do you build the elastix binary yourself? If so, you may need to adjust ELASTIX_IMAGE_2D_PIXELTYPES, ELASTIX_IMAGE_3D_PIXELTYPES, or ELASTIX_IMAGE_4D_PIXELTYPES during your CMake configuration.

You may select a subset of:

char;unsigned char;short;unsigned short;int;unsigned int;long;unsigned long;float;double

@NHPatterson
Copy link
Author

@N-Dekker I haven't been compiling elastix locally, but have been using ITKElastix from pypi in my whole slide image registration wsireg package. I have to be conscious of memory consumption as many of 2D image planes exceed 30000 pixels on each side. Downsampling is an option, but I am curious if ITKElastix has any intention to support more pixel types and how I can contribute to making that happen.

@Svdvoort
Copy link

I agree that having ITKElastix also be compiled with short pixel type by default would be very helpful, and would also keep it in line with the Elastix binary. Right now this leads to problems since ITKElastix and the Elastix binary are compiled with different pixel types, and I feel like it would be most natural to at least have the same pixel types available in both compilations.

@thewtex
Copy link
Member

thewtex commented Oct 17, 2022

If I recall correctly, the current limitation of float32 wrapping is due to a mismatch between the interface classes and Elastix's internal mapping classes. @N-Dekker do you know if there has been progress on this?

xref: SuperElastix/elastix#322

Once we update to the latest Elastix development version, should we be able to enable wrapping for these other types?

@N-Dekker
Copy link
Collaborator

@thewtex Do I understand correctly that the effect of the wrapping below is to support both float and double as input pixel type (but no other types)?

itk_wrap_class("itk::ElastixRegistrationMethod" POINTER)
itk_wrap_image_filter("${WRAP_ITK_REAL}" 2)

itk_wrap_class("itk::ElastixRegistrationMethod" POINTER)
itk_wrap_image_filter("${WRAP_ITK_REAL}" 2)

@dzenanz
Copy link
Member

dzenanz commented Apr 24, 2023

I know that float type is supported by default. I never tried double. Other types are not supported (UC, SS, etc). That seems like the relevant specification. I will let Matt answer. Meanwhile, you could try adding all scalar types there and build it locally.

@thewtex
Copy link
Member

thewtex commented Apr 24, 2023

Do I understand correctly that the effect of the wrapping below is to support both float and double as input pixel type (but no other types)?

Yes, correct. However, this would also need to be addressed: #137 (comment)

@N-Dekker
Copy link
Collaborator

Can you please tell me, how is the itk.elastix_registration_method defined exactly? In Python, help(itk.elastix_registration_method) tells me the following:

Help on function elastix_registration_method in module itk.itkElastixRegistrationMethodPython:

elastix_registration_method(*args, fixed_image: 'itk.Image' = Ellipsis, moving_image: 'itk.Image' = Ellipsis, fixed_mask: 'itk.Image' = Ellipsis, moving_mask: 'itk.Image' = Ellipsis, parameter_object=Ellipsis, initial_transform_parameter_file_name: str = Ellipsis, fixed_point_set_file_name: str = Ellipsis, moving_point_set_file_name: str = Ellipsis, output_directory: str = Ellipsis, log_file_name: str = Ellipsis, log_to_console: bool = Ellipsis, log_to_file: bool = Ellipsis, number_of_threads: int = Ellipsis, **kwargs) -> ...]]
Proxy of C++ itkElastixRegistrationMethodIF2IF2 class.

What does the postfix "IF2IF2" of itkElastixRegistrationMethodIF2IF2 mean? But more interestingly, how does the function body of elastix_registration_method look like?

@dzenanz
Copy link
Member

dzenanz commented Apr 25, 2023

Postfix "IF2IF2" means that it is instantiated with those template parameters, e.g. itkElastixRegistrationMethodIF2IF2 == itk::ElastixRegistrationMethod<<itk::Image<float,2>, itk::Image<float,2>>.

If you look at itkElastixRegistrationMethodPython.cpp (on my computer found in M:\a\ITKElastix-py\Wrapping\Modules\Elastix\) and itkElastixRegistrationMethodPython.py (in M:\a\ITK-py\Wrapping\Generators\Python\itk\) you will find some auto-generated plumbing which invokes stuff compiled from C++ into DLLs.

@N-Dekker
Copy link
Collaborator

Thanks @dzenanz So does that mean that by definition, the Python itk.elastix_registration_method function only supports a single image type, no matter how much we tweak itkElastixRegistrationMethod.wrap, the elastix CMake build config or whatever? Or could this Python function also be extended to support multiple image types?

@dzenanz
Copy link
Member

dzenanz commented Apr 25, 2023

There can be multiple instantiations, e.g. IF2IF2, IF3IF3, ISS2ISS2, ISS3ISS3, etc. While different pixel types and dimensions can be mixed, there is not much advantage to do it in this case.

@dzenanz
Copy link
Member

dzenanz commented Apr 25, 2023

For a really complicated case, take a look at this PR KitwareMedical/ITKUltrasound#223 adding a bunch of weird wrappings to ITKUltrasound.

@N-Dekker
Copy link
Collaborator

Thanks. There must be some manual coding done to wrap a C++ class template into a Python function, right? I mean, SWIG cannot just guess that itk.elastix_registration_method must create an ElastixRegistrationMethod<FixedImage, MovingImage> object, and pass the function parameters to the corresponding object properties, right?

@N-Dekker
Copy link
Collaborator

Yes, the tip of the iceberg of manual specification is https://github.com/InsightSoftwareConsortium/ITKElastix/blob/c36279f04ded427d90d45ac2731e8119647c6c23/wrapping/itkElastixRegistrationMethod.wrap

Thanks, but isn't itk_wrap_image_filter only just instantiating the requested templates? Sorry, I still don't see how it would create the elastix_registration_method function.

@dzenanz
Copy link
Member

dzenanz commented Apr 25, 2023

ITK's general Pythonification functionality turns any class in CamelCaseStyle into a function camel_case_style, and transforms the code into a series of instantiation, method calls (SetInput, SetX, SetY), Update(), and GetOutput().

Also take a look at Wrapping section.

@N-Dekker
Copy link
Collaborator

OK, thanks, I think I finally starts to understand a little bit! So ITKElastix instantiates itkElastixRegistrationMethod for both float and double, at

itk_wrap_class("itk::ElastixRegistrationMethod" POINTER)
itk_wrap_image_filter("${WRAP_ITK_REAL}" 2)
Does it also specify float;double as CMake variables ELASTIX_IMAGE_2D_PIXEL_TYPES, ELASTIX_IMAGE_3D_PIXEL_TYPES, and ELASTIX_IMAGE_4D_PIXEL_TYPES, when doing a CMake configure of elastix? Otherwise elastix still won't instantiate the components (C++ templates) for those pixel types.

@dzenanz
Copy link
Member

dzenanz commented Apr 25, 2023

I believe such options would go into https://github.com/InsightSoftwareConsortium/ITKElastix/blob/main/CMakeLists.txt. As I don't see them there, I assume they are on by default.

@NHPatterson
Copy link
Author

Closed by #211.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants