Chained Image Registration

Coarse-to-fine registration composes two registrars: a fast, robust method recovers the large motion, then a deformable method refines it. RegisterImagesChain is the general composition; RegisterImagesGreedyICON is the Greedy-then-ICON pairing, used by Tutorial 2 and by the distance-map stage of the statistical-model fit.

Both implement RegisterImagesBase, so they drop into any workflow that takes a registration_method.

Class Reference

class physiotwin4d.RegisterImagesChain(registrars, log_level=20)[source]

Bases: RegisterImagesBase

Run an ordered list of registrars in sequence, each stage refining the previous stage’s forward_transform via RegisterImagesBase.register_from().

Use this to combine independent registration backends into a multi-stage pipeline (e.g. a fast coarse registrar followed by a refinement stage). Every element of registrars must be a RegisterImagesBase instance. registrars (plural, a list) is distinct from the singular registrar attribute used by classes like RegisterTimeSeriesImages.

See RegisterImagesGreedyICON for a named 2-stage convenience subclass (Greedy followed by ICON refinement).

Chaining is not free accuracy. Every stage’s result is applied unconditionally, so a refinement stage helps only when its own accuracy floor is below the error the previous stage has already reached. A stage whose deformation model is coarser than that error cannot resolve what is left and acts as a low-pass perturbation, giving a slightly worse answer for strictly more runtime. Compare each stage against the one before it on a held-out metric rather than assuming the chain wins.

result["loss"] is the last stage’s loss, measured against data the earlier stages already warped; it is not comparable to a single-stage loss.

Example

>>> chain = RegisterImagesChain([RegisterImagesGreedy(), RegisterImagesICON()])
>>> chain.set_fixed_image(fixed_image)
>>> result = chain.register(moving_image)
__init__(registrars, log_level=20)[source]

Initialize the registration chain.

Parameters:
  • registrars (list[RegisterImagesBase]) – Ordered, non-empty list of RegisterImagesBase instances to run in sequence.

  • log_level (int | str) – Logging level (default: logging.INFO)

Raises:
  • ValueError – If registrars is empty.

  • TypeError – If any element of registrars is not a RegisterImagesBase instance.

registration_method(moving_image, moving_mask=None, moving_labelmap=None, moving_image_pre=None)[source]

Run each registrar in self.registrars in order.

The first stage registers the raw moving image; every later stage sees the moving data pre-warped by the running result and contributes only a refinement, which is composed back on – the same mechanics as RegisterImagesBase.register_from(), run through the delegated registration_method path so masks are not re-converted per stage.

Note

moving_image_pre is ignored: each stage may need different intensity preprocessing (e.g. ICON’s uniGradICON preprocessing vs. Greedy’s no-op), so every stage computes its own preprocessing from the raw moving_image rather than reuse a value computed for a different backend.

Parameters:
  • moving_image (itk.image) – The 3D image to be registered

  • moving_mask (itk.image, optional) – Binary mask for moving image ROI

  • moving_labelmap (itk.image, optional) – Multi-label segmentation for the moving image

  • moving_image_pre (itk.image, optional) – Ignored - see Note above

Returns:

The last stage’s result dict (see RegisterImagesBase.register())

Return type:

dict

class physiotwin4d.RegisterImagesGreedyICON(log_level=20)[source]

Bases: RegisterImagesChain

Greedy registration followed by ICON refinement, using Greedy’s forward_transform to initialize ICON.

Access the two stages by name via .greedy/.icon (e.g. RegisterImagesGreedyICON().greedy.set_number_of_iterations([30, 15, 7, 3])) rather than positional registrars[0]/registrars[1] indexing.

Example

>>> registrar = RegisterImagesGreedyICON()
>>> registrar.greedy.set_number_of_iterations([30, 15, 7, 3])
>>> registrar.icon.set_number_of_iterations(20)
>>> registrar.set_fixed_image(fixed_image)
>>> result = registrar.register(moving_image)
__init__(log_level=20)[source]

Initialize the Greedy-then-ICON registration chain.

Parameters:

log_level (int | str) – Logging level (default: logging.INFO)

property greedy: RegisterImagesGreedy

The Greedy stage of this chain.

property icon: RegisterImagesICON

The ICON stage of this chain.

Basic Usage

from physiotwin4d import RegisterImagesGreedyICON

registrar = RegisterImagesGreedyICON()
# Coarse-to-fine iteration schedule for the Greedy stage.
registrar.greedy.set_number_of_iterations([30, 15, 7, 3])
# Mass preservation suits non-contrast CT; leave it off for contrast.
registrar.icon.set_mass_preservation(True)

The two stages are reachable as .greedy and .icon, so each is tuned with its own setters rather than a merged parameter set.

See Also