Registration Base Class

Abstract base class for all image registration methods.

Class Reference

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

Bases: PhysioTwin4DBase

Base class for deformable image registration algorithms.

This class provides a common interface and shared functionality for implementing different image registration algorithms. It handles standard operations like image and mask management, preprocessing, and parameter configuration that are common across registration methods.

The base class is designed to support various registration algorithms including deep learning-based methods (Icon, UniGradIcon) and traditional methods (ANTs, ITK). Concrete implementations should inherit from this class and implement the register() method.

Key features: - Standardized interface for different registration algorithms - Fixed and moving image management - Binary mask processing with optional dilation - Modality-specific parameter configuration - Support for region-of-interest registration

net

Algorithm-specific network or registration object

Type:

object

modality

Image modality (‘ct’, ‘mri’, etc.) for parameter optimization

Type:

str

fixed_image

The target/reference image

Type:

itk.image

fixed_image_pre

Preprocessed fixed image

Type:

itk.image

fixed_mask

Binary mask for fixed image ROI

Type:

itk.image

mask_dilation_mm

Mask dilation amount in millimeters

Type:

float

fast_mode

When True, subclasses may use cheaper/less-accurate registration settings to trade quality for speed (e.g. in automated tests). Defaults to False.

Type:

bool

Example

>>> class MyRegistration(RegisterImagesBase):
...     def registration_method(self, moving_image, **kwargs):
...         # Implement specific registration algorithm
...         return {
...             'forward_transform': tfm_forward,  # warps moving image -> fixed grid
...             'inverse_transform': tfm_inverse,  # warps fixed image -> moving grid
...             'loss': 0.0,
...         }
>>>
>>> registrar = MyRegistration()
>>> registrar.set_modality('ct')
>>> registrar.set_fixed_image(reference_image)
>>> result = registrar.register(moving_image)
>>> forward_tfm = result['forward_transform']  # warps moving image -> fixed grid
>>> inverse_tfm = result['inverse_transform']  # warps fixed image -> moving grid

See RegisterImagesChain to combine multiple registrars into a multi-stage pipeline (e.g. a fast coarse registrar followed by a refinement stage), and RegisterImagesGreedyICON for the common Greedy-then-ICON case.

__init__(log_level=20)[source]

Initialize the base image registration class.

Sets up the common registration parameters with default values. Algorithm-specific components (like neural networks or optimization objects) should be initialized in the concrete implementation to avoid unnecessary resource allocation.

Parameters:

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

set_modality(modality)[source]

Set the imaging modality for registration optimization.

Different imaging modalities benefit from different registration parameters. CT images.

Parameters:

modality (str) – The imaging modality. Supported values: ‘ct’, ‘mri’

Return type:

None

Example

>>> registrar.set_modality('ct')
>>> registrar.set_modality('mri')
set_prewarp_background_value(background_value)[source]

Override the value a seeded registration’s pre-warp writes off-grid.

Parameters:

background_value (float) – Intensity written where the fixed grid samples outside the moving image. Leave unset to derive it from the modality; see _prewarp_background_value().

Return type:

None

set_fixed_image(fixed_image)[source]

Set the fixed/target image for registration.

The fixed image serves as the reference coordinate system to which all moving images will be aligned. Setting a new fixed image clears any preprocessed data to ensure consistency.

Parameters:

fixed_image (itk.image) – The 3D reference image that serves as the target for registration

Return type:

None

Example

>>> registrar.set_fixed_image(reference_frame)
set_mask_dilation(mask_dilation_mm)[source]

Set the dilation of the fixed and moving image masks.

Parameters:

mask_dilation_mm (float) – The dilation in millimeters.

Return type:

None

set_fixed_mask(fixed_mask)[source]

Set a binary mask for the fixed image region of interest.

The mask constrains registration to focus on specific anatomical regions, improving accuracy and reducing computation time. The mask is automatically converted to binary format. If mask_dilation_mm is set, the mask is dilated by the specified amount.

Parameters:

fixed_mask (itk.image) – Binary or label mask defining the region of interest in the fixed image. Non-zero values are treated as foreground

Return type:

None

Example

>>> # Use heart mask to focus registration on cardiac structures
>>> registrar.set_fixed_mask(heart_mask)
set_fixed_labelmap(fixed_labelmap)[source]

Set the fixed image labelmap (multi-label segmentation).

Parameters:

fixed_labelmap (itk.Image, optional) – Multi-label segmentation co-registered with the fixed image, or None to clear.

Return type:

None

preprocess(image, modality='ct')[source]

Preprocess the image based on modality-specific requirements.

This method applies preprocessing steps such as intensity normalization, histogram equalization, or noise reduction tailored to the specified imaging modality. Preprocessing enhances image quality and improves registration accuracy.

Parameters:
  • image (itk.image) – The 3D image to preprocess

  • modality (str) – The imaging modality (‘ct’, ‘mri’, etc.)

Returns:

The preprocessed image

Return type:

itk.image

Example

>>> preprocessed_image = registrar.preprocess(raw_image, modality='ct')
registration_method(moving_image, moving_mask=None, moving_labelmap=None, moving_image_pre=None)[source]

Main registration method to align moving image to fixed image.

This method serves as the primary interface for performing image registration. It takes a moving image and optional mask and preprocessed image, and returns the forward and backward transformations.

Note: This is an internal method that should be implemented by subclasses. The public API is register() which wraps this method.

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

  • 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) – Preprocessed moving image

Returns:

Dictionary containing:
  • ”forward_transform”: Warps the moving image onto the fixed grid. Warping moving points/landmarks into fixed space uses “inverse_transform” instead (see register() and docs/developer/transform_conventions).

  • ”inverse_transform”: Warps the fixed image onto the moving grid

  • ”loss”: Registration loss/metric value

Return type:

dict

Raises:

ValueError – If fixed image is not set

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

Register a moving image to the fixed image.

This is the main registration method that must be implemented by concrete subclasses. It should align the moving image to the fixed image using the specific algorithm implemented by the subclass.

To start from a known alignment, use register_from() rather than seeding the backend directly.

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

  • 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) – Preprocessed moving image

Returns:

Dictionary containing transformation results:
  • ”forward_transform”: Warps the moving IMAGE onto the fixed grid, i.e. transform_image(moving, forward_transform, fixed).

  • ”inverse_transform”: Warps the fixed IMAGE onto the moving grid, i.e. transform_image(fixed, inverse_transform, moving).

  • ”loss”: Registration loss/metric value

Return type:

dict

Note

Image warps and point/landmark warps use OPPOSITE members of the transform pair, because ITK image resampling pulls back (it maps a fixed-grid sample to the moving image) while point transforms push forward (they map a point to its corresponding location):

  • Warp the moving image into fixed space -> forward_transform

  • Warp moving points/landmarks into fixed -> inverse_transform

  • Warp the fixed image into moving space -> inverse_transform

  • Warp fixed points/landmarks into moving -> forward_transform

See docs/developer/transform_conventions for the full discussion.

Raises:

NotImplementedError – This method must be implemented by subclasses

register_from(initial_forward_transform, moving_image, moving_mask=None, moving_labelmap=None)[source]

Register starting from a known alignment.

The moving data is warped onto the fixed grid by initial_forward_transform first, register() then measures only the residual misalignment, and the two are composed. This is the single supported way to seed a registration: doing it here rather than inside each backend keeps the pre-warp, the composition and the inversion identical for every algorithm.

The image, the mask and the labelmap are all pre-warped, so they stay in the same frame as each other; the mask and labelmap use nearest-neighbor interpolation to preserve their discrete values.

Parameters:
  • initial_forward_transform (Transform) – Starting alignment, in the same convention as the returned forward_transform – it warps the moving image onto the fixed grid.

  • moving_image (Image) – The 3D image to be registered to the fixed image.

  • moving_mask (Optional[Image]) – Binary mask for the moving image ROI.

  • moving_labelmap (Optional[Image]) – Multi-label segmentation for the moving image.

Returns:

Same keys as register(), with the transforms composed so they map between the original moving image and the fixed image.

Return type:

dict

Raises:

ValueError – If the fixed image has not been set.

get_registered_image()[source]

Get the registered image.

The moving image is an intensity image, so voxels of the fixed grid that fall outside it are filled with _prewarp_background_value() rather than 0, which is a tissue intensity rather than an absence of tissue.

Returns:

The registered image

Return type:

itk.Image

classmethod get_log_classes()

Get the list of classes currently showing logs.

Return type:

list[str]

Returns:

List of class names that are allowed to show logs. Empty list if filter is disabled (all classes shown).

Example

>>> classes = PhysioTwin4DBase.get_log_classes()
>>> print(classes)
['RegisterModelsPCA', 'WorkflowFitStatisticalModelToPatient']
log_critical(message, *args)

Log a critical message with optional %-style formatting.

Parameters:
  • message (str) – The critical message to log (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting

Return type:

None

Example

>>> self.log_critical('System failure at %s', timestamp)
>>> self.log_critical('Critical error: %(msg)s', {'msg': 'Out of memory'})
log_debug(message, *args)

Log a debug message with optional %-style formatting.

Parameters:
  • message (str) – The debug message to log (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting

Return type:

None

Example

>>> self.log_debug('Processing %s with %d items', filename, count)
>>> self.log_debug('Value is %(value)d', {'value': 42})
log_error(message, *args)

Log an error message with optional %-style formatting.

Parameters:
  • message (str) – The error message to log (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting

Return type:

None

Example

>>> self.log_error('Failed to load %s: %s', filename, error_msg)
>>> self.log_error('Error code: %(code)d', {'code': 404})
log_info(message, *args)

Log an info message with optional %-style formatting.

Parameters:
  • message (str) – The info message to log (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting

Return type:

None

Example

>>> self.log_info('Loading file: %s', filepath)
>>> self.log_info('Iteration %(iter)d of %(total)d', {'iter': 5, 'total': 10})
log_progress(current, total, prefix='Progress')

Log progress information.

Parameters:
  • current (int) – Current step/iteration number

  • total (int) – Total number of steps/iterations

  • prefix (str) – Prefix text for the progress message. Default: ‘Progress’

Return type:

None

Example

>>> for i in range(100):
...     self.log_progress(i + 1, 100)
>>> self.log_progress(5, 10, prefix='Processing')

Note

For custom formatted progress messages, use log_info() directly: >>> self.log_info(‘Loading %s: %d/%d’, filename, current, total)

log_section(title, *args, width=70, char='=')

Log a formatted section header with optional %-style formatting.

Useful for visually separating major sections of output.

Parameters:
  • title (str) – The section title (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting of title

  • width (int) – Total width of the header line. Default: 70

  • char (str) – Character to use for the header line. Default: ‘=’

Return type:

None

Example

>>> self.log_section('Stage 1: Initialization')
>>> self.log_section('Processing file: %s', filename)
>>> self.log_section('Stage %(num)d: %(name)s', {'num': 2, 'name': 'Analysis'})
# Outputs:
# ======================================================================
# Stage 2: Analysis
# ======================================================================
log_warning(message, *args)

Log a warning message with optional %-style formatting.

Parameters:
  • message (str) – The warning message to log (can contain %-style placeholders)

  • *args (Any) – Arguments for %-style string formatting

Return type:

None

Example

>>> self.log_warning('Memory usage at %d%%', usage_percent)
>>> self.log_warning('Parameter %(name)s out of range', {'name': 'threshold'})
classmethod set_log_all_classes()

Enable logging output from all PhysioTwin4D classes.

Disables the class filter so all classes show their logs.

Example

>>> PhysioTwin4DBase.set_log_all_classes()
>>> # Now all classes will show their logs
Return type:

None

classmethod set_log_classes(class_names)

Set which classes should show their logging output.

Only log messages from the specified classes will be displayed. All other classes will have their logs hidden.

Parameters:

class_names (list[str]) – List of class names to show logs from. Example: [“RegisterModelsPCA”, “WorkflowFitStatisticalModelToPatient”]

Return type:

None

Example

>>> PhysioTwin4DBase.set_log_classes(['RegisterModelsPCA'])
>>> # Now only RegisterModelsPCA logs will be shown
classmethod set_log_level(log_level)

Set the logging level for all PhysioTwin4D classes.

Parameters:

log_level (int | str) – Logging level. Can be an integer (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL) or a string (‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’).

Return type:

None

Example

>>> import logging
>>> PhysioTwin4DBase.set_log_level(logging.DEBUG)
>>> # or
>>> PhysioTwin4DBase.set_log_level('DEBUG')
logger: Logger
log_level: int

Overview

RegisterImagesBase provides the foundation for all registration implementations.

Key Responsibilities:
  • Define standard registration interface

  • Provide transform management utilities

  • Handle image resampling operations

  • Manage registration parameters

See Also

Navigation

Image Registration Modules | ANTs Registration | ICON Image Registration