Registration

Registration algorithms for WSI alignment

core.registration.registration.convert_4x4_to_3x3_transform(transform_4x4)[source]

Convert 4x4 transformation matrix to 3x3 affine matrix.

core.registration.registration.create_displacement_field(source_points, transformed_points, image_shape, method='linear', sigma=10.0, max_displacement=10.0)[source]

Generate dense displacement field from sparse non-rigid registration results. Uses float32 arrays and LinearNDInterpolator for reduced memory and faster interpolation.

core.registration.registration.find_mutual_nearest_neighbors(fixed_points, moving_points, sample_size: int = 5000)[source]

Find mutual nearest neighbors (MNN) between two point sets.

If either set exceeds sample_size, a random subsample is drawn first to keep memory and compute costs manageable.

core.registration.registration.perform_cpd_registration(moving_points, fixed_points, beta=0.5, alpha=0.01, max_iterations=200, tolerance=1e-09)[source]

Perform Coherent Point Drift (CPD) non-rigid registration.

Returns:

(transformed_points, convergence_info)
  • transformed_points (np.ndarray): Registered moving points.

  • convergence_info (dict): Dictionary with keys 'q' (final objective value) and 'iterations' (number of EM iterations completed).

Return type:

tuple

core.registration.registration.perform_icp_registration(moving_points, fixed_points, threshold=50000.0)[source]

Perform ICP registration on 2D point sets.

Parameters:
  • moving_points (np.ndarray) – Moving point set (N, 2).

  • fixed_points (np.ndarray) – Fixed point set (M, 2).

  • threshold (float) – Maximum correspondence distance.

Returns:

(transformation_matrix, transformed_points)

Return type:

tuple

core.registration.registration.perform_rigid_registration(source_prep, target_prep, source_mask, target_mask)[source]

Perform rigid registration between source and target images.

Parameters:
  • source_prep (np.ndarray) – Preprocessed source image.

  • target_prep (np.ndarray) – Preprocessed target image.

  • source_mask (np.ndarray) – Source tissue mask.

  • target_mask (np.ndarray) – Target tissue mask.

Returns:

(warped_image, transformation_matrix)

Return type:

tuple

core.registration.registration.perform_shape_aware_registration(fixed_df, moving_df, shape_attribute='area', shape_weight=0.3, max_iterations=50, tolerance=1e-06)[source]
class core.registration.rigid.ShapeAwarePointSetRegistration(fixed_points, moving_points, shape_attribute=None, shape_weight=0.0, max_iterations=50, tolerance=1e-06, allow_scaling=False)[source]

Bases: object

get_transformation_matrix()[source]

Return 3x3 homogeneous transformation matrix.

register()[source]

Perform iterative closest point registration with shape awareness.

class core.registration.rigid.Trimorph[source]

Bases: object

static apply_affine_transformation(fixed_img, moving_img, transform_initializer)[source]
static compute_center_of_mass(mask)[source]
prealignment(fixed_img, moving_img, fixed_mask, moving_mask, dice_overlap=0.5, rotation_step=10)[source]
class core.registration.rigid.XFeatReg(top_k_matches: int = 8000)[source]

Bases: object

register(im1: numpy.ndarray, im2: numpy.ndarray)[source]

Register im2 to im1 using feature matching and affine transform.

warp_corners_and_draw_matches(ref_points, dst_points, img1, img2)[source]

Estimate homography, warp corners of img1 to img2, and visualize matches.

core.registration.rigid.extract_corresponding_tiles(source_wsi, target_wsi, source_mask=None, target_mask=None, transform_matrix=None, patch_index=10, patch_size=(5000, 5000), stride=(5000, 5000), base_resolution=0, target_resolution=10, scale_factor=0.625)[source]

Extracts corresponding tiles from source and target WSIs using a transformation matrix.

Parameters:

source_wsiobject or str

Source WSI object or path to source WSI file

target_wsiobject or str

Target WSI object or path to target WSI file

source_maskndarray, optional

Mask for the source WSI

target_maskndarray, optional

Mask for the target WSI

transform_matrixndarray, optional

Homogeneous transformation matrix to apply

patch_indexint, default=10

Index of the patch to extract

patch_sizetuple, default=(5000, 5000)

Size of patches to extract

stridetuple, default=(5000, 5000)

Stride for sliding window patch extraction

base_resolutionint, default=0

Base resolution for patch extraction

target_resolutionint, default=10

Target resolution for transformation

scale_factorfloat, default=0.625

Scale factor to apply to the transformation matrix

Returns:

dict

Dictionary containing: - ‘fixed_tile’: The fixed (target) image patch - ‘transformed_tile’: The transformed (source) image patch - ‘transform_40x’: The scaled transformation matrix - ‘location’: The location of the extracted patch - ‘size’: The size of the extracted patch - ‘patch_extractor_fixed’: The patch extractor for the target WSI - ‘patch_extractor_moving’: The patch extractor for the source WSI - ‘transformer’: The AffineWSITransformer used

core.registration.rigid.perform_shape_aware_registration(fixed_df, moving_df, shape_attribute=None, shape_weight=0.0, max_iterations=50, tolerance=1e-06, allow_scaling=False)[source]

Convenience function for shape-aware point set registration.

Returns:

The registration object with transformation parameters transform_matrix: 3x3 homogeneous transformation matrix coords: Nx2 array of registered coordinates

Return type:

registrator

core.registration.rigid.register_wsi_with_fine_tuning(source_wsi, target_wsi, source_mask=None, target_mask=None, initial_transform=None, patch_index=10, patch_size=(5000, 5000), stride=(5000, 5000), base_resolution=0, target_resolution=10, scale_factor=0.625)[source]

Registers a source WSI to a target WSI using an initial transform and fine-tunes the registration using phase cross-correlation on a specific patch.

Parameters:

source_wsiobject or str

Source WSI object or path to source WSI file

target_wsiobject or str

Target WSI object or path to target WSI file

source_maskndarray, optional

Mask for the source WSI

target_maskndarray, optional

Mask for the target WSI

initial_transformndarray, optional

Initial homogeneous transformation matrix to apply

patch_indexint, default=10

Index of the patch to use for fine-tuning

patch_sizetuple, default=(5000, 5000)

Size of patches to extract

stridetuple, default=(5000, 5000)

Stride for sliding window patch extraction

base_resolutionint, default=0

Base resolution for patch extraction

target_resolutionint, default=10

Target resolution for transformation

scale_factorfloat, default=0.625

Scale factor to apply to the transformation matrix

Returns:

dict

Dictionary containing: - ‘final_transform’: The final transformation matrix - ‘registered_image’: The registered image patch - ‘fixed_tile’: The fixed (target) image patch - ‘transformed_tile’: The transformed (source) image patch before fine-tuning - ‘shift’: The calculated shift between patches

core.registration.rigid.rigid_registration(moving_img, fixed_img, moving_mask, fixed_mask, verbose=False)[source]

Aligns a moving image to a fixed image using Trimorph and optionally XFeatReg if needed.

Parameters:
  • fixed_img (np.ndarray) – Fixed image.

  • moving_img (np.ndarray) – Moving image.

  • fixed_mask (np.ndarray) – Fixed mask.

  • moving_mask (np.ndarray) – Moving mask.

  • verbose (bool) – If True, print intermediate steps.

Returns:

Final aligned moving image. final_transform (np.ndarray): Final transformation matrix (3x3). ngf_metrics (dict): Dictionary with NGF metrics before and after optional second registration.

Return type:

moving_img_transformed (np.ndarray)

core.registration.nonrigid.apply_deformation_field(input_tensor: torch.Tensor, vector_field: torch.Tensor, coord_grid: torch.Tensor | None = None, interpolation_method: str = 'bilinear', boundary_handling: str = 'zeros', compute_device: str | torch.device | None = None) torch.Tensor[source]

Apply a deformation field to warp the input tensor.

core.registration.nonrigid.build_reference_coordinate_system(input_tensor: torch.Tensor | None = None, dimensions: torch.Size | None = None, compute_device: str | torch.device | None = None) torch.Tensor[source]

Build a reference coordinate grid for the given tensor dimensions.

core.registration.nonrigid.compute_deformation_and_apply(source_prep, final_transform, displacement_field, moving_df, fixed_df, padding_params, util, pad_landmarks)[source]

Compute the final deformation field by combining rigid and non-rigid transformations, then apply it to the moving landmark points.

Parameters:
  • source_prep (np.ndarray) – Preprocessed source image used for rigid transformation.

  • final_transform (object) – Transformation model or matrix from rigid registration.

  • displacement_field (torch.Tensor or np.ndarray) – The predicted displacement field (2D vector field).

  • moving_df (pandas.DataFrame) – DataFrame containing moving landmark coordinates with columns [‘global_x’, ‘global_y’].

  • fixed_df (pandas.DataFrame) – DataFrame containing fixed landmark coordinates with columns [‘global_x’, ‘global_y’].

  • padding_params (tuple) – Padding parameters required by pad_landmarks.

  • util (module) – Utility module containing helper functions: - rigid_dot - tc_df_to_np_df - compose_vector_fields - apply_deformation_to_points

  • pad_landmarks (callable) – Function to pad landmark coordinates to match deformation field dimensions.

Returns:

  • deformation_field (np.ndarray) – Combined deformation field, shape (2, H, W).

  • moving_updated (np.ndarray) – Updated (deformed) moving points, scaled back to original coordinates.

  • fixed_points (np.ndarray) – Fixed points, scaled back to original coordinates.

  • moving_points (np.ndarray) – Original moving points, scaled back to original coordinates.

core.registration.nonrigid.compute_normalized_cross_correlation(sources: torch.Tensor, targets: torch.Tensor, device: str | torch.device | None = None, **config_params) torch.Tensor[source]
core.registration.nonrigid.compute_smoothness_regularization(vector_field: torch.Tensor, compute_device: torch.device | None = None, weight_map: torch.Tensor | None = None) torch.Tensor[source]
core.registration.nonrigid.convert_image_to_tensor(img_array: numpy.ndarray, compute_device: str | torch.device = 'cpu') torch.Tensor[source]

Convert a numpy image array to a PyTorch tensor.

core.registration.nonrigid.create_multiscale_representation(input_tensor: torch.Tensor, level_count: int, interpolation_method: str = 'bilinear', scale_factor: float = 2.0) List[torch.Tensor][source]

Build a multi-scale image pyramid from fine to coarse.

core.registration.nonrigid.elastic_image_registration(source: numpy.ndarray, target: numpy.ndarray, similarity_metric: str = 'ncc', similarity_metric_params: Dict[str, Any] = {'size': 7}, compute_device: str | torch.device = 'cuda', verbose: bool = False, output_dir: str | Path | None = None, save_intermediate: bool = False) Tuple[torch.Tensor, torch.Tensor][source]
core.registration.nonrigid.gaussian_smoothing(input_tensor: torch.Tensor, blur_sigma: float) torch.Tensor[source]

Apply Gaussian blur to a tensor. GaussianBlur objects are cached to avoid re-computing kernels.

core.registration.nonrigid.initialize_deformation_field(input_tensor: torch.Tensor) torch.Tensor[source]

Initialize a zero deformation field matching the spatial dimensions of the input tensor.

core.registration.nonrigid.prepare_image_tensors(source_image: numpy.ndarray, target_image: numpy.ndarray, compute_device: str | torch.device, normalize: bool = True) Tuple[torch.Tensor, torch.Tensor][source]
core.registration.nonrigid.scale_deformation_field(vector_field: torch.Tensor, new_dimensions: torch.Size | Tuple[int, int], interpolation_method: str = 'bilinear') torch.Tensor[source]
core.registration.nonrigid.scale_tensor_to_dimensions(input_tensor: torch.Tensor, target_dimensions: torch.Size, interpolation_method: str = 'bilinear') torch.Tensor[source]

Resize input tensor to the given spatial dimensions.

class core.registration.cpd.CPD(method='rigid')[source]

Bases: object

Class implementing the Coherent Point Drift (CPD) method for rigid, affine and non-rigid point set registration.

__init__(method='rigid')[source]

Initialize CPD class with rigid, affine or non-rigid point set registration.

Parameters:

method (str, optional (default: 'rigid')) – ‘rigid’, ‘affine’ or ‘nonrigid’.

play_animation(X, Y, w=0.1, beta=2, lmbda=2, max_iterations=100, step_interval=0.1, save_animation=False, save_path=None)[source]

Applies the CPD method to the data in Y to match X.

Parameters:
  • X (np.ndarray, shape = (N, D)) – Set containing N D-dimensional data points.

  • Y (np.ndarray, shape = (M, D)) – Set containing M D-dimensional data points.

  • w (float, optional (default: 0.1)) – Assumption on the amount of noise in the point sets.

  • beta (float, optional (default: 2)) – Model of smoothness regularizer (width of Gaussian filter in equation 20).

  • lmbda (float, optional (default: 2)) – Trade-off between goodness of maximum likelihood fit and regularization.

  • max_iterations (int, optional (default: 2)) – Maximum number of iterations for the EM optimization.

  • step_interval (float, optional (default: 0.1)) – Time between animation steps in seconds.

  • save_animation (bool, optional (default: False)) – Whether to save the animation.

  • save_path (str, optional (default: None)) – Path where to save the animation.

Returns:

animation – Animation of the EM optimization progress.

Return type:

matplotlib.animation.FuncAnimation

solve_affine(X, Y, P)[source]

Solves for the affine point set registration.

Parameters:
  • X (np.ndarray, shape = (N, D)) – Set containing N D-dimensional data points.

  • Y (np.ndarray, shape = (M, D)) – Set containing M D-dimensional data points.

  • P (np.ndarray, shape = (M, N)) – Probabilities for point assignments from Y to X.

Returns:

  • theta (tuple, length = 2) – Affine transformation matrix B: np.ndarray of shape = (D, D) Translation vector t: np.ndarray of shape = (D,)

  • var (float) – Isotropic covariances.

solve_nonrigid(X, Y, P, G, var, lmbda)[source]

Solves for the non-rigid point set registration.

Parameters:
  • X (np.ndarray, shape = (N, D)) – Set containing N D-dimensional data points.

  • Y (np.ndarray, shape = (M, D)) – Set containing M D-dimensional data points.

  • P (np.ndarray, shape = (M, N)) – Probabilities for point assignments from Y to X.

  • G (np.ndarray, shape = (M, M)) – Kernel matrix.

  • var (float) – Isotropic covariances.

  • lmbda (float) – Trade-off between goodness of maximum likelihood fit and regularization.

Returns:

  • W (np.ndarray, shape = (M, D)) – Coefficient matrix.

  • var (float) – Isotropic covariances.

solve_rigid(X, Y, P)[source]

Solves for the rigid point set registration.

Parameters:
  • X (np.ndarray, shape = (N, D)) – Set containing N D-dimensional data points.

  • Y (np.ndarray, shape = (M, D)) – Set containing M D-dimensional data points.

  • P (np.ndarray, shape = (M, N)) – Probabilities for point assignments from Y to X.

Returns:

  • theta (tuple, length = 3) – Rotation matrix R: np.ndarray of shape = (D, D) Translation vector t: np.ndarray of shape = (D,) Scale s: float

  • var (float) – Isotropic covariances.