pirt.deform - Deformations classes

The deform module implements classes to represent deformations: The DeformationGrid represents a deformation in world coordinates using a spline grid, and the DeformationField represents a deformation in world coordinates using an array for each dimension; it describes the deformation for each pixel/voxel.

The aforementioned classes are actually base classes; one should use DeformationFieldBackward, DeformationFieldForward, DeformationGridBackward or DeformationGridForward.

The base deformation class

class pirt.Deformation

This class is an abstract base class for deformation grids and deformation fields.

A deformation maps one image (1D, 2D or 3D) to another. A deformation can be represented using a B-spline grid, or using a field (i.e. array). A deformation is either forward mapping or backward mapping.

add(other)

Combine two deformations by addition.

Returns a DeformationGrid instance if both deforms are grids. Otherwise returns deformation field. The mapping (forward/backward) is taken from the left deformation.

Notes

Note that the resulting deformation is not necesarily diffeomorphic even if the individual deformations are.

Although diffeomorphisms can in general not be averaged, the constraint of Choi used in this framework enables us to do so (add the individual deformations and scale with 1/n).

This function can also be invoked using the plus operator.

apply_deformation(data, interpolation=3)

Apply the deformation to the given data. Returns the deformed data.

Parameters:
data : numpy array

The data to deform

interpolation : {0,1,3}

The interpolation order (if backward mapping is used).

as_backward()

Returns the same deformation as a backward mapping. Returns the original if already in backward mapping.

as_backward_inverse()

Returns the inverse deformation as a forward mapping. Returns the inverse of the original if already in forward mapping. If in backward mapping, the data is the same, but wrapped in a DeformationFieldBackward instance.

Note: backward and forward mappings with the same data are each-others reverse.

as_deformation_field()

Obtain a deformation fields instance that represents the same deformation. If this is already a deformation field, returns self.

as_forward()

Returns the same deformation as a forward mapping. Returns the original if already in forward mapping.

as_forward_inverse()

Returns the inverse deformation as a forward mapping. Returns the inverse of the original if already in forward mapping. If in backward mapping, the data is the same, but wrapped in a Deformation{Field/Grid}Backward instance.

Note: backward and forward mappings with the same data are each-others reverse.

as_other(other)

Returns the deformation as a forward or backward mapping, so it matches the other deformations.

compose(def1, def2)

compose(other):

Combine two deformations by composition. The left is the “static” deformation, and the right is the “delta” deformation.

Always returns a DeformationField instance. The mapping (forward/backward) of the result is taken from the left deformation.

Notes

Let “h = f.compose(g)” and “o” the mathematical composition operator. Then mathematically “h(x) = g(f(x))” or “h = g o f”.

Practically, new deformation vectors are created by sampling in one deformation, at the locations specified by the vectors of the other.

For forward mapping we sample in g at the locations of f. For backward mapping we sample in f at the locations of g.

Since we cannot impose the field values for a B-spline grid without resorting to some multi-scale approach (which would use composition and is therefore infinitely recursive), the result is always a deformation field.

If the deformation to sample in (f for forward mapping, g for backward) is a B-spline grid, the composition does not introduce any errors; sampling in a field introduces interpolation errors. Since the static deformation f is often a DeformationField, forward mapping is preferred with regard to the accuracy of composition.

copy()

Copy this deformation instance (deep copy).

field_sampling

For each dim, the sampling (distance between pixels/voxels) of the field (all 1’s if isotropic).

field_shape

The shape of the deformation field.

forward_mapping

Returns True if this deformation is forward mapping.

get_deformation_locations()

Get a tuple of arrays (x,y,z order) that represent sample locations to apply the deformation. The locations are absolute and expressed in pixel coordinates. As such, they can be fed directly to interp() or project().

get_field(d)

Get the field corresponding to the given dimension.

get_field_in_points(pp, d, interpolation=1)

Obtain the field for dimension d in the specied points. The interpolation value is used only if this is a deformation field.

The points pp should be a point set (x-y-z order).

inverse()

Get the inverse deformation. This is only valid if the current deformation is diffeomorphic. The result is always a DeformationField instance.

is_identity

Returns True if this is an identity deform, or null deform; representing no deformation at all.

ndim

The number of dimensions of the deformation.

scale(factor)

Scale the deformation (in-place) with the given factor. Note that the result is diffeomorphic only if the original is diffeomorphic and the factor is between -1 and 1.

show(axes=None, axesAdjust=True)

Illustrates 2D deformations.

It does so by creating an image of a grid and deforming it. The image is displayed in the given (or current) axes. Returns the texture object of the grid image.

Requires visvis.

The base grid deformation class

class pirt.DeformationGrid(image, sampling=5)

A deformation grid represents a deformation using a spline grid.

The ‘grids’ property returns a tuple of SplineGrid instances (one for each dimension). These sub-grids can also obtained by indexing and are in z,y,x order.

Parameters:
image : shape-tuple, numpy-array, Aarray, or FieldDescription

A description of the field that this grid applies to. The image itself is not stored, only the field’s shape and sampling are of interest.

sampling : number

The spacing of the knots in the field. (For anisotropic fields, the spacing is expressed in world units.)

classmethod from_field(field, sampling, weights=None, injective=True, frozenedge=True, fd=None)

Create a DeformationGrid from the given deformation field (z-y-x order). Also see from_field_multiscale()

The optional weights array can be used to individually weight the field elements. Where the weight is zero, the values are not evaluated. The speed can therefore be significantly improved if there are relatively few nonzero elements.

Parameters:
field : list of numpy arrays

These arrays describe the deformation field (one per dimension).

sampling : scalar

The sampling of the returned grid

weights : numpy array

This array can be used to weigh the contributions of the individual elements.

injective : bool

Whether to prevent the grid from folding. This also penetalizes large relative deformations. An injective B-spline grid is diffeomorphic.

frozenedge : bool

Whether the edges should be frozen. This can help the registration process. Also, when used in conjunction with injective, a truly diffeomorphic deformation is obtained: every input pixel maps to a point within the image boundaries.

fd : field

Field description to describe the shape and sampling of the underlying field to be deformed.

classmethod from_field_multiscale(field, sampling, weights=None, fd=None)

Create a DeformationGrid from the given deformation field (z-y-x order). Applies from_field_multiscale() for each of its subgrids.

Parameters:
field : list of numpy arrays

These arrays describe the deformation field (one per dimension).

sampling : scalar

The sampling of the returned grid

weights : numpy array

This array can be used to weigh the contributions of the individual elements.

fd : field

Field description to describe the shape and sampling of the underlying field to be deformed.

classmethod from_points(image, sampling, pp1, pp2, injective=True, frozenedge=True)

Obtains the deformation field described by the two given sets of corresponding points. The deformation describes moving the points pp1 to points pp2. Note that backwards interpolation is used, so technically, the image is re-interpolated by sampling at the points in pp2 from pixels specified by the points in pp1.

Parameters:
image : numpy array or shape

The image (of any dimension) to which the deformation applies.

sampling : scalar

The sampling of the returned grid.

pp1 : PointSet, 2D ndarray

The base points.

pp2 : PointSet, 2D ndarray

The target points.

injective : bool

Whether to prevent the grid from folding. This also penetalizes large relative deformations. An injective B-spline grid is diffeomorphic.

frozenedge : bool

Whether the edges should be frozen. This can help the registration process. Also, when used in conjunction with injective, a truly diffeomorphic deformation is obtained: every input pixel maps to a point within the image boundaries.

classmethod from_points_multiscale(image, sampling, pp1, pp2)

Obtains the deformation field described by the two given sets of corresponding points. The deformation describes moving the points pp1 to points pp2. Applies from_points_multiscale() for each of its subgrids.

See DeformationField.from_points_multiscale() for a sound alternative.

Parameters:
image : numpy array or shape

The image (of any dimension) to which the deformation applies.

sampling : scalar

The sampling of the returned grid.

pp1 : PointSet, 2D ndarray

The base points.

pp2 : PointSet, 2D ndarray

The target points.

show(axes=None, axesAdjust=True, showGrid=True)

For 2D grids, illustrates the deformation and the knots of the grid. A grid image is made that is deformed and displayed in the given (or current) axes. By default the positions of the underlying knots are also shown using markers. Returns the texture object of the grid image.

Requires visvis.

The base field deformation class

class pirt.DeformationField(*fields)

A deformation field represents a deformation using an array for each dimension, thus specifying the deformation at each pixel/voxel. The fields should be in z-y-x order. The deformation is represented in world units (not pixels, unless pixel units are used).

Can be initialized with:
  • DeformationField(field_z, field_y, field_x)
  • DeformationField(image) # Null deformation
  • DeformationField(3) # Null deformation specifying only the ndims

This class has functionality to reshape the fields. This can be usefull during registration if using a scale space pyramid.

classmethod from_field_multiscale(field, sampling, weights=None, injective=True, frozenedge=True, fd=None)

Create a DeformationGrid from the given deformation field (z-y-x order).

Uses B-spline grids in a multi-scale approach to regularize the sparse known deformation. This produces a smooth field (minimal bending energy), similar to thin plate splines.

The optional weights array can be used to individually weight the field elements. Where the weight is zero, the values are not evaluated. The speed can therefore be significantly improved if there are relatively few nonzero elements.

Parameters:
field : list of numpy arrays

These arrays describe the deformation field (one per dimension).

sampling : scalar

The smallest sampling of the B-spline grid that is used to create the field.

weights : numpy array

This array can be used to weigh the contributions of the individual elements.

injective : bool or number

Whether to prevent the grid from folding. An injective B-spline grid is diffeomorphic. When a number between 0 and 1 is given, the unfold constraint can be tightened to obtain smoother deformations.

frozenedge : bool

Whether the edges should be frozen. This can help the registration process. Also, when used in conjunction with injective, a truly diffeomorphic deformation is obtained: every input pixel maps to a point within the image boundaries.

fd : field

Field description to describe the shape and sampling of the underlying field to be deformed.

Notes

The algorithmic is based on: Lee S, Wolberg G, Chwa K-yong, Shin SY. “Image Metamorphosis with Scattered Feature Constraints”. IEEE TRANSACTIONS ON VISUALIZATION AND COMPUTER GRAPHICS. 1996;2:337–354.

The injective constraint desctribed in this paper is not applied by this method, but by the DeformationGrid, since it is method specifically for deformations.

classmethod from_points_multiscale(image, sampling, pp1, pp2, injective=True, frozenedge=True)

Obtains the deformation field described by the two given sets of corresponding points. The deformation describes moving the points pp1 to points pp2. Note that backwards interpolation is used, so technically, the image is re-interpolated by sampling at the points in pp2 from pixels specified by the points in pp1.

Uses B-spline grids in a multi-scale approach to regularize the sparse known deformation. This produces a smooth field (minimal bending energy), similar to thin plate splines.

Parameters:
image : numpy array or shape

The image (of any dimension) to which the deformation applies.

sampling : scalar

The sampling of the smallest grid to describe the deform.

pp1 : PointSet, 2D ndarray

The base points.

pp2 : PointSet, 2D ndarray

The target points.

injective : bool or number

Whether to prevent the grid from folding. An injective B-spline grid is diffeomorphic. When a number between 0 and 1 is given, the unfold constraint can be tightened to obtain smoother deformations.

frozenedge : bool

Whether the edges should be frozen. This can help the registration process. Also, when used in conjunction with injective, a truly diffeomorphic deformation is obtained: every input pixel maps to a point within the image boundaries.

Notes

The algorithmic is based on: Lee S, Wolberg G, Chwa K-yong, Shin SY. “Image Metamorphosis with Scattered Feature Constraints”. IEEE TRANSACTIONS ON VISUALIZATION AND COMPUTER GRAPHICS. 1996;2:337–354.

The injective constraint desctribed in this paper is not applied by this method, but by the DeformationGrid, since it is method specifically for deformations.

resize_field(new_shape)

Create a new DeformationField instance, where the underlying field is resized.

The parameter new_shape can be anything that can be converted to a FieldDescription instance.

If the field is already of the correct size, returns self.

test_jacobian(show=True)

Test the determinand of the field’s Jacobian. It should be all positive for the field to be diffeomorphic.

Returns the number of pixels where the Jacobian <= 0. If show==True, will show a figure with these pixels indicated.

The concrete classes to use

class pirt.DeformationGridBackward(*args, **kwargs)

A deformation grid representing a backward mapping; the field represents where the pixels in the deformed image should be sampled to in the original image.

class pirt.DeformationGridForward(*args, **kwargs)

A deformation grid representing a forward mapping; to create the deformed image, the pixels are mapped to their new locations.

class pirt.DeformationFieldBackward(*fields)

A deformation field representing a backward mapping; the field represents where the pixels in the deformed image should be sampled to in the original image.

class pirt.DeformationFieldForward(*fields)

A deformation field representing a forward mapping; to create the deformed image, the pixels are mapped to their new locations.

class pirt.DeformationIdentity

Abstract identity deformation. It is not a grid nor a field, nor is it forward or backward mapping.

It is nothing more than a simple tool to initialize a deformation with.