Non-rigid registration

Perform non-rigid registration

Base NonRigidRegistrar

class valis.non_rigid_registrars.NonRigidRegistrar(params=None)[source]

Abstract class for non-rigid registration using displacement fields

Warps moving_img to align with fixed_img using backwards transformations VALIS offers 3 implementations: dense optical flow (OpenCV), SimpleElastix, and groupwise SimpleElastix. Displacement fields can come from other packages, indluding SimpleITK, PIRT, DIPY, etc… Those other methods can be used by subclassing the NonRigidRegistrar classes in VALIS.

moving_img

Image with shape (N,M) thata is warp to align with fixed_img.

Type:

ndarray

fixed_img

Image with shape (N,M) that moving_img is warped to align with.

Type:

ndarray

mask

2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Type:

ndarray

shape

Number of rows and columns in each image. Will be (N,M).

Type:

tuple

grid_spacing

Number of pixels between deformation grid points.

Type:

int

warped_image

Registered copy of moving_img.

Type:

ndarray

deformation_field_img

Image showing deformation applied to a regular grid.

Type:

ndarray

backward_dx

(N,M) array defining the displacements in the x-dimension.

Type:

ndarray

backward_dy

(N,M) array defining the displacements in the y-dimension.

Type:

ndarray

method

Name of registration method.

Type:

str

Note

All NonRigidRegistrar subclasses need to have a calc() method, which must at least take the following arguments: moving_img, fixed_img, mask. calc() should return the displacement field as a (2, N, M) numpy array, with the first element being an array of displacements in the x-dimension, and the second element being an array of displacements in the y-dimension.

Note that the NonRigidRegistrarXY subclass should be used if corresponding points in moving and fixed images can be used to aid the registration.

__init__(params=None)[source]
Parameters:

params (dictionary) –

Keyword: value dictionary of parameters to be used in reigstration. Will get used in the calc() method.

In the case where simple ITK will be used, params should be a SimpleITK.ParameterMap. Note that numeric values needd to be converted to strings.

calc(moving_img, fixed_img, mask, *args, **kwargs)[source]

Cacluate displacement fields

Can record subclass specific atrributes here too

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img. Has shape (N, M).

  • fixed_img (ndarray) – Image moving_img is warped to align with. Has shape (N, M).

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Returns:

bk_dxdy – (2, N, M) numpy array of pixel displacements in the x and y directions. dx = bk_dxdy[0], and dy=bk_dxdy[1].

Return type:

ndarray

register(moving_img, fixed_img, mask=None, **kwargs)[source]

Register images, warping moving_img to align with fixed_img

Uses backwards transforms to register images (i.e. aligning fixed to moving), so the inverse transform needs to be used to warp points from moving_img. This is automatically done in warp_tools.warp_xy

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img.

  • fixed_img (ndarray) – Image moving_img is warped to align with.

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

  • **kwargs (dict, optional) – Additional keyword arguments passed to NonRigidRegistrar.calc

Returns:

  • warped_img (ndarray) – Moving image registered to align with fixed image.

  • warped_grid (ndarray) – Image showing deformation applied to a regular grid.

  • bk_dxdy (ndarray) – (2, N, M) numpy array of pixel displacements in the x and y directions.

Base NonRigidRegistrarXY

class valis.non_rigid_registrars.NonRigidRegistrarXY(params=None)[source]

Bases: NonRigidRegistrar

Abstract class for non-rigid registration using displacement fields

Subclass of NonRigidRegistrar that can (optionally) use corresponding points (xy coordinates) to aid in the registration

moving_img

Image with shape (N,M) thata is warp to align with fixed_img.

Type:

ndarray

fixed_img

Image with shape (N,M) that moving_img is warped to align with.

Type:

ndarray

mask

2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Type:

ndarray

shape

Number of rows and columns in each image. Will be (N,M).

Type:

tuple

grid_spacing

Number of pixels between deformation grid points/

Type:

int

warped_image

Registered copy of moving_img.

Type:

ndarray

deformation_field_img

Image showing deformation applied to a regular grid.

Type:

ndarray

backward_dx

(N,M) array defining the displacements in the x-dimension.

Type:

ndarray

backward_dy

(N,M) array defining the displacements in the y-dimension.

Type:

ndarray

method

Name of registration method.

Type:

str

moving_xy

(N, 2) array containing points in moving_img that correspond to those in the fixed image.

Type:

ndarray, optional

fixed_xy

(N, 2) array containing points in fixed_img that correspond to those in the moving image.

Type:

ndarray, optional

Note

All NonRigidRegistrarXY subclasses need to have a calc() method, which needs to at least take the following arguments: moving_img, fixed_img, mask, moving_xy, fixed_xy. calc() should return the warped moving image, warped regular grid, and the displacement field as an (2, N, M) numpy array.

Note that NonRigidRegistrar should be used if corresponding points in moving and fixed images can not be used to aid the registration.

__init__(params=None)[source]
Parameters:

params (dictionary) –

Keyword: value dictionary of parameters to be used in reigstration. Will get used in the calc() method.

In the case where simple ITK will be used, params should be a SimpleITK.ParameterMap. Note that numeric values needd to be converted to strings.

calc(moving_img, fixed_img, mask, *args, **kwargs)

Cacluate displacement fields

Can record subclass specific atrributes here too

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img. Has shape (N, M).

  • fixed_img (ndarray) – Image moving_img is warped to align with. Has shape (N, M).

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Returns:

bk_dxdy – (2, N, M) numpy array of pixel displacements in the x and y directions. dx = bk_dxdy[0], and dy=bk_dxdy[1].

Return type:

ndarray

register(moving_img, fixed_img, mask=None, moving_xy=None, fixed_xy=None, **kwargs)[source]

Register images, warping moving_img to align with fixed_img

Uses backwards transforms to register images (i.e. aligning fixed to moving), so the inverse transform needs to be used to warp points from moving_img. This is automatically done in warp_tools.warp_xy

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img.

  • fixed_img (ndarray) – Image moving_img is warped to align with.

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

  • moving_xy (ndarray, optional) – (N, 2) array containing points in the moving_img that correspond to those in fixed_img.

  • fixed_xy (ndarray, optional) – (N, 2) array containing points in the fixed_img that correspond to those in the moving_img.

Returns:

  • warped_img (ndarray) – moving_img registered to align with fixed_img.

  • warped_grid (ndarray) – Image showing deformation applied to a regular grid.

  • bk_dxdy (ndarray) – (2, N, M) numpy array of pixel displacements in the x and y directions.

Base NonRigidRegistrarGroupwise

class valis.non_rigid_registrars.NonRigidRegistrarGroupwise(params=None)[source]

Bases: NonRigidRegistrar

Performs groupwise non-rigid registration

This subclass can register a collection (>= 2) of images, and so is not limited to pairs of images.

img_list

List of images, each with shape (N,M) that are to be co-registered

Type:

list of ndarray

mask

2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Type:

ndarray

shape

Number of rows and columns in each image. Will be (N,M).

Type:

tuple of int

warped_image

Registered copy of moving_img.

Type:

ndarray

deformation_field_img

Image showing deformation applied to a regular grid.

Type:

ndarray

backward_dx

(N,M) array defining the displacements in the x-dimension.

Type:

ndarray

backward_dy

(N,M) array defining the displacements in the y-dimension.

Type:

ndarray

grid_spacing

Number of pixels between deformation grid points

Type:

int

method

Name of registration method.

Type:

str

size

Number of images that are being registered as a group

Type:

int

__init__(params=None)[source]
Parameters:

params (dictionary) –

Keyword: value dictionary of parameters to be used in reigstration. Will get used in the calc() method.

In the case where simple ITK will be used, params should be a SimpleITK.ParameterMap. Note that numeric values needd to be converted to strings.

register(img_list, mask=None)[source]

Register images in img_list

Uses backwards transforms to register images (i.e. aligning fixed to moving), so the inverse transform needs to be used to warp points from moving_img. This is automatically done in warp_tools.warp_xy

Parameters:

img_list (list of ndarray) – List of I images, each with shape (N,M) that are to be co-registered.

Returns:

  • warped_img (list of ndarray) – List of moving images registered to align with the fixed image.

  • warped_grid (list of ndarray) – Image showing deformation applied to a regular grid.

  • bk_dxdy (list of ndarray) – List numpy array of pixel displacements in the x and y directions for each image. Has shape (I, N, M, 2).

OpticalFlowWarper

class valis.non_rigid_registrars.OpticalFlowWarper(params=None, optical_flow_obj=None, n_grid_pts=50, sigma_ratio=0.005, paint_size=5000, fold_penalty=1e-06, smoothing_method=None)[source]

Bases: NonRigidRegistrar

Use dense optical flow to register images.

Dense optical flow fields may not be diffeomorphic, and so this class provides options to smooth displacement fields.

__init__(params=None, optical_flow_obj=None, n_grid_pts=50, sigma_ratio=0.005, paint_size=5000, fold_penalty=1e-06, smoothing_method=None)[source]
Parameters:
  • params (dictionary) – Keyword: value dictionary of parameters to be used in reigstration. Will get used in the calc() method.

  • optical_flow_obj (object) – Object that will perform dense optical flow.

  • n_grid_pts (int) – Number of gridpoints used to detect folds. Also the number of gridpoints to use when regularizing he mesh when method = “regularize”.

  • paint_size (int) – Used to determine how much to resize the image to have efficient inpainting. Larger values = longer processing time. Only used if smoothing_method = “inpaint”.

  • fold_penalty (float) – How much to penalize folding/stretching. Larger values will make the deformation field more uniform, which may or may not be desired, as too much can remove all displacements. Only used if smoothing_method = “regularize”

  • sigma_ratio (float) – Determines the amount of Gaussian smoothing, as sigma = max(shape) *sigma_ratio. Larger values do more smoothing. Only used if smoothing_method is “gauss”.

  • smoothing (str) –

    If “gauss”, then a Gaussian blur will be applied to the deformation fields, using sigma defined by sigma_ratio.

    If “inpaint”, folded regions will be detected and removed. Folded regions will then be removed using inpainting.

    If “regularize”, folded regions will be detected and regularized using the method fescribed in “Foldover-free maps in 50 lines of code” Garanzha et al. 2021.

    If “None” then no smoothing will be applied.

calc(moving_img, fixed_img, *args, **kwargs)[source]

Cacluate displacement fields

Can record subclass specific atrributes here too

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img. Has shape (N, M).

  • fixed_img (ndarray) – Image moving_img is warped to align with. Has shape (N, M).

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Returns:

bk_dxdy – (2, N, M) numpy array of pixel displacements in the x and y directions. dx = bk_dxdy[0], and dy=bk_dxdy[1].

Return type:

ndarray

SimpleElastixWarper

class valis.non_rigid_registrars.SimpleElastixWarper(params=None, ammi_weight=0.33, bending_penalty_weight=0.33, kp_weight=0.33)[source]

Bases: NonRigidRegistrarXY

Uses SimpleElastix to register images

May optionally using corresponding points

__init__(params=None, ammi_weight=0.33, bending_penalty_weight=0.33, kp_weight=0.33)[source]
Parameters:
  • ammi_weight (float) – Weight given to the AdvancedMattesMutualInformation metric.

  • bending_penalty_weight (float) – Weight given to the TransformBendingEnergyPenalty metric.

  • kp_weight (float) – Weight given to the CorrespondingPointsEuclideanDistanceMetric metric. Only used if moving_xy and fixed_xy are provided as arguments to the register() method.

calc(moving_img, fixed_img, mask=None, moving_xy=None, fixed_xy=None, *args, **kwargs)[source]

Perform non-rigid registration using SimpleElastix.

Can include corresponding points to help in registration by providing moving_xy and fixed_xy.

static get_default_params(img_shape, grid_spacing_ratio=0.025)[source]

Get default parameters for registration with sitk.ElastixImageFilter

See https://simpleelastix.readthedocs.io/Introduction.html for advice on parameter selection

SimpleElastixGroupwiseWarper

class valis.non_rigid_registrars.SimpleElastixGroupwiseWarper(params=None)[source]

Bases: NonRigidRegistrarGroupwise

Performs groupwise non-rigid registration using SimpleElastix.

SimpleElastixGroupwiseWarper can register a collection (>= 2) of images, and so is not limited to pairs of images.

img_list

List of images, each with shape (N,M) that are to be co-registered.

Type:

list

mask

2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Type:

ndarray

shape

Number of rows and columns in each image. Will have shaape (N,M).

Type:

tuple of int

warped_image

Registered copy of moving_img.

Type:

ndarray

deformation_field_img

Image showing deformation applied to a regular grid.

Type:

ndarray

backward_dx

(N,M) array defining the displacements in the x-dimension.

Type:

ndarray

backward_dy

(N,M) array defining the displacements in the y-dimension.

Type:

ndarray

grid_spacing

Number of pixels between deformation grid points.

Type:

int

method

Name of registration method.

Type:

str

__init__(params=None)[source]
Parameters:

params (dictionary) –

Keyword: value dictionary of parameters to be used in reigstration. Will get used in the calc() method.

In the case where simple ITK will be used, params should be a SimpleITK.ParameterMap. Note that numeric values needd to be converted to strings.

calc(img_list, mask=None, *args, **kwargs)[source]

Cacluate displacement fields

Can record subclass specific atrributes here too

Parameters:
  • moving_img (ndarray) – Image to warp to align with fixed_img. Has shape (N, M).

  • fixed_img (ndarray) – Image moving_img is warped to align with. Has shape (N, M).

  • mask (ndarray) – 2D array with shape (N,M) where non-zero pixel values are foreground, and 0 is background, which is ignnored during registration. If None, then all non-zero pixels in images will be used to create the mask.

Returns:

bk_dxdy – (2, N, M) numpy array of pixel displacements in the x and y directions. dx = bk_dxdy[0], and dy=bk_dxdy[1].

Return type:

ndarray

static get_default_params(img_shape, grid_spacing_ratio=0.025)[source]

See https://simpleelastix.readthedocs.io/Introduction.html for advice on parameter selection