Distance Map Registration

Register models using distance field optimization.

Class Reference

class physiomotion4d.RegisterModelsDistanceMaps(moving_model, fixed_model, reference_image, mask_dilation_mm=20, log_level=20)[source]

Bases: PhysioMotion4DBase

Register anatomical models using distance-map-based deformable registration.

This class provides distance-map-based alignment of 3D surface models with support for rigid, affine, and deformable transformation modes. The registration pipeline generates signed distance maps from models, applies optional binary mask dilation, and uses Greedy for rigid/affine stages and ICON for deformable registration.

Registration Pipelines:
  • None mode: No registration (identity transform)

  • Rigid mode: Greedy rigid registration

  • Affine mode: Greedy affine registration

  • Deformable mode: Greedy affine → ICON deformable registration

Transform Convention:

These are the underlying image-registration (Greedy/ICON) transforms, so they follow the image convention (see docs/developer/transform_conventions):

  • forward_transform: warps the moving image/mask onto the fixed grid. Warping the moving MODEL points/landmarks onto the fixed model uses inverse_transform instead (image and point warps use opposite transforms).

  • inverse_transform: warps the fixed image/mask onto the moving grid.

moving_model

Surface model to be aligned

Type:

pv.PolyData

fixed_model

Target surface model

Type:

pv.PolyData

reference_image

Reference image for coordinate frame

Type:

itk.Image

mask_dilation_mm

Dilation amount in mm for binary registration masks

Type:

float

transform_tools

Transform utility instance

Type:

TransformTools

contour_tools

Model utility instance

Type:

ContourTools

registrar_Greedy

Greedy registration instance

Type:

RegisterImagesGreedy

registrar_ICON

ICON registration instance

Type:

RegisterImagesICON

forward_transform

Optimized moving→fixed transform

Type:

itk.CompositeTransform

inverse_transform

Optimized fixed→moving transform

Type:

itk.CompositeTransform

registered_model

Aligned moving model

Type:

pv.PolyData

Example

>>> # Initialize with models and reference image
>>> registrar = RegisterModelsDistanceMaps(
...     moving_model=model_surface,
...     fixed_model=patient_surface,
...     reference_image=patient_ct,
...     mask_dilation_mm=20,
... )
>>>
>>> # Run rigid registration
>>> result = registrar.register(transform_type='Rigid')
>>>
>>> # Or run affine registration
>>> result = registrar.register(transform_type='Affine')
>>>
>>> # Or run deformable (Greedy affine + ICON)
>>> result = registrar.register(transform_type='Deformable', icon_iterations=50)
>>>
>>> # Get aligned model and transforms
>>> aligned_model = result['registered_model']
>>> forward_transform = result['forward_transform']
__init__(moving_model, fixed_model, reference_image, mask_dilation_mm=20, log_level=20)[source]

Initialize distance-map-based model registration.

Parameters:
  • moving_model (PolyData) – PyVista surface model to be aligned to fixed model

  • fixed_model (PolyData) – PyVista target surface model

  • reference_image (Image) – ITK image providing coordinate frame (origin, spacing, direction) for mask generation. Typically the patient CT/MRI image.

  • mask_dilation_mm (float) – Dilation amount in millimeters for binary registration mask generation. Default: 20mm

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

Note

The moving_model and fixed_model are typically extracted from VTU models using model.extract_surface(algorithm=”dataset_surface”) before passing to this class.

register(transform_type='Deformable', icon_iterations=50)[source]

Perform mask-based registration of moving model to fixed model.

This method executes progressive multi-stage registration:

None transform type:
  1. No registration (identity transform)

Rigid transform type:
  1. Greedy rigid registration

Affine transform type:
  1. Greedy affine registration

Deformable transform type:
  1. Greedy affine registration

  2. ICON deformable registration on the affine-pre-aligned masks

Parameters:
  • transform_type (str) – Registration transform type - ‘None’, ‘Rigid’, ‘Affine’, or ‘Deformable’. Default: ‘Deformable’

  • icon_iterations (int) – Number of ICON optimization iterations for ‘Deformable’ mode. Default: 50

Returns:

  • ‘moving_model’: Aligned moving model (PyVista PolyData)

  • ’forward_transform’: Moving→fixed transform (ITK CompositeTransform)

  • ’inverse_transform’: Fixed→moving transform (ITK CompositeTransform)

Return type:

Dictionary containing

Raises:

ValueError – If transform_type is not ‘None’, ‘Rigid’, ‘Affine’, or ‘Deformable’

Example

>>> # Rigid registration
>>> result = registrar.register(transform_type='Rigid')
>>>
>>> # Affine registration
>>> result = registrar.register(transform_type='Affine')
>>>
>>> # Deformable registration (Greedy affine + ICON)
>>> result = registrar.register(transform_type='Deformable', icon_iterations=100)
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 = PhysioMotion4DBase.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 PhysioMotion4D classes.

Disables the class filter so all classes show their logs.

Example

>>> PhysioMotion4DBase.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

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

Set the logging level for all PhysioMotion4D 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
>>> PhysioMotion4DBase.set_log_level(logging.DEBUG)
>>> # or
>>> PhysioMotion4DBase.set_log_level('DEBUG')

Navigation

ICP with ITK Backend | Model Registration Modules | PCA-Based Registration