ICP (Iterative Closest Point)
Pure Python implementation of Iterative Closest Point registration.
Class Reference
- class physiomotion4d.RegisterModelsICP(fixed_model, log_level=20)[source]
Bases:
PhysioMotion4DBaseRegister anatomical models using Iterative Closest Point (ICP) algorithm.
This class provides ICP-based alignment of 3D surface models with support for both rigid and affine transformation modes. The registration pipeline uses centroid alignment for initialization followed by VTK’s ICP algorithm.
- Registration Pipelines:
Rigid transform type: Centroid alignment → Rigid ICP
Affine transform type: Centroid alignment → Rigid ICP → Affine ICP
- Transform Convention:
- forward_point_transform: moving → fixed space transformation
(This is the inverse of the transform used to wrap the moving image to the fixed image)
inverse_point_transform: moving → fixed space transformation
- moving_model
Surface model to be aligned
- Type:
pv.PolyData
- fixed_model
Target surface model
- Type:
pv.PolyData
- transform_tools
Transform utility instance
- Type:
- forward_point_transform
Optimized moving→fixed transform
- Type:
itk.AffineTransform
- inverse_point_transform
Optimized fixed→moving transform
- Type:
itk.AffineTransform
- registered_model
Aligned moving model
- Type:
pv.PolyData
Example
>>> # Initialize with model >>> registrar = RegisterModelsICP(fixed_model=patient_surface) >>> >>> # Run rigid registration >>> result = registrar.register( ... transform_type='Rigid', ... max_iterations=200, ... moving_model=model_surface, ... ) >>> >>> # Or run affine registration >>> result = registrar.register( ... transform_type='Affine', ... max_iterations=200, ... moving_model=model_surface, ... ) >>> >>> # Get aligned model and transforms >>> aligned_model = result['registered_model'] >>> forward_point_transform = result['forward_point_transform']
- __init__(fixed_model, log_level=20)[source]
Initialize ICP-based model registration.
- Parameters:
Note
The moving_model is typically extracted from a VTU model using model.extract_surface(algorithm=”dataset_surface”) before passing to this class.
- register(moving_model, transform_type='Affine', max_iterations=2000)[source]
Perform ICP alignment of moving model to fixed model.
This method executes alignment with either rigid or affine transformations:
- Rigid transform type:
Centroid alignment: Translate moving model to align mass centers
Rigid ICP: Refine with rigid-body transformation (rotation + translation)
- Affine transform type:
Centroid alignment: Translate moving model to align mass centers
Rigid ICP: Refine with rigid-body transformation
- Affine ICP: Further refine with affine transformation (includes
scaling/shearing)
- Parameters:
- Returns:
‘registered_model’: Aligned moving model (PyVista PolyData)
- ’forward_point_transform’: Moving→fixed transform
(ITK AffineTransform)
- ’inverse_point_transform’: Fixed→moving transform
(ITK AffineTransform)
- Return type:
Dictionary containing
- Raises:
ValueError – If transform_type is not ‘Rigid’ or ‘Affine’
Example
>>> # Rigid registration >>> result = registrar.register( ... transform_type='Rigid', ... max_iterations=5000, ... moving_model=moving_model, ... ) >>> >>> # Affine registration >>> result = registrar.register( ... transform_type='Affine', ... max_iterations=2000, ... moving_model=moving_model, ... )
- classmethod get_log_classes()
Get the list of classes currently showing logs.
- Return type:
- 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:
- Return type:
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:
- Return type:
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:
- Return type:
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:
- Return type:
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:
- Return type:
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:
- Return type:
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:
- Return type:
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:
- 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:
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:
Example
>>> import logging >>> PhysioMotion4DBase.set_log_level(logging.DEBUG) >>> # or >>> PhysioMotion4DBase.set_log_level('DEBUG')
Navigation
Model Registration Modules | ICP with ITK Backend | Distance Map Registration