InsightSoftwareConsortium / itk-dreg

A framework for distributed large-scale image registration
http://itk-dreg.readthedocs.io/
Apache License 2.0
5 stars 2 forks source link

Implement `TransformCollection` as an ITK external module #14

Open tbirdso opened 9 months ago

tbirdso commented 9 months ago

Background

itk_dreg.reduce_dfield implements the TransformCollection class. TransformCollection extends the itk.Transform effective interface to composite results from multiple piecewise input transforms to a single point output. itk_dreg.reduce_dfield relies on TransformCollection to sample a single output deformation field result based on multiple subimage registration transforms.

Current Implementation

TransformCollection is implemented as a pure Python class that runs sampling in serial. As a result, its execution time is rather slow.

Meanwhile as a pure Python class TransformCollection is not considered to be a subclass of itk.Transform and thus cannot be provided to ITK process objects as a valid input.

Feature Request

We should create an ITK external module (ITKTransformCollection, ITKTransformBlending, ITKPiecewiseTransform, or similar) and re-implement TransformCollection there as an ITK C++ class.

Suggested steps:

  1. Use ITKModuleTemplate to create the new external module project on GitHub
  2. Implement a transform blending class virtual interface that accepts multiple output point candidates with attached piecewise transform domain information and yields a single point result. Consider whether it makes sense to inherit from or otherwise use or reference ITK interpolator classes.
  3. Implement a simple averaging blending method in C++ that ports TransformCollection.blend_simple_mean logic.
  4. Implement an advanced distance-weighted blending method in C++ that ports TransformCollection.blend_distance_weighted_mean logic.
  5. Implement TransformEntry in C++ according to the specification:
    • Defines a transform with an optional bounds constraint. If an inclusive domain is specified, the transform is bounded and may only transform input points that fall within the domain. If no domain is specified the transform is unbounded and may transform any input point.
    • Accepts an itk.TransformBase input
    • Accepts an optional transform domain. I have used Optional[itk.Image] in itk_dreg to specify that a domain may be an oriented bounding box in 3D physical space as described by an unbuffered itk.Image with metadata. The equivalent representation in C++ would be std::optional<itk::Image<PixelType, Dimension>>. There may be other valid specifiers for a generic 3D region that could be used.
    • Maybe inherits from itk.TransformBase to define a TransformPoint function. This is not required, but would allow the TransformEntry to be used in generic ITK filters to describe a piecewise function. May be reasonable to effectively return a translation of 0 for any input points outside of a bounded domain.
    • Consider using a more descriptive name, such as PiecewiseTransformFunction, BoundedTransform, etc.
  6. Implement the C++ TransformCollection class according to the following specification:
    • Derives from itk.TransformBase
    • Accepts multiple itk.TransformEntry piecewise transform instances
    • Accepts a blending function
    • Implements TransformPoint such that:
      1. Each piecewise transform entry in the collection is evaluated to determine whether the point falls within its bounds;
      2. For each transforms whose bounds contains the input point, transform the point to return an output point candidate;
      3. Apply blending to smooth among output point candidates to return a single output point.
tbirdso commented 9 months ago

Could be a good first issue for someone looking to learn more about ITK C++ module development. Logic is already specified/implemented and available for reference in itk_dreg.reduce_dfield.transform_collection, with tasks outlined above.