The niftyreg.linear function performs linear registration for two and three dimensional images. 4D images may also be registered volumewise to a 3D image, or 3D images slicewise to a 2D image. Rigid-body (6 degrees of freedom) and affine (12 degrees of freedom) registration can currently be performed.

niftyreg.linear(source, target, scope = c("affine", "rigid"), init = NULL,
  sourceMask = NULL, targetMask = NULL, symmetric = TRUE, nLevels = 3L,
  maxIterations = 5L, useBlockPercentage = 50L, interpolation = 3L,
  verbose = FALSE, estimateOnly = FALSE, sequentialInit = FALSE,
  internal = NA, precision = c("double", "single"),
  threads = getOption("RNiftyReg.threads"))

Arguments

source

The source image, an object of class "nifti" or "internalImage", or a plain array, or a NIfTI-1 filename. Must have 2, 3 or 4 dimensions.

target

The target image, an object of class "nifti" or "internalImage", or a plain array, or a NIfTI-1 filename. Must have 2 or 3 dimensions.

scope

A string describing the scope, or number of degrees of freedom (DOF), of the registration. The currently supported values are "affine" (12 DOF), "rigid" (6 DOF) or "nonlinear" (high DOF, with the exact number depending on the image sizes).

init

Transformation(s) to be used for initialisation, which may be NULL, for no initialisation, or an affine matrix or control point image (nonlinear only). For multiple registration, where the source image has one more dimension than the target, this may also be a list whose components are likewise NULL or a suitable initial transform.

sourceMask

An optional mask image in source space, whose nonzero region will be taken as the region of interest for the registration. Ignored when symmetric is FALSE.

targetMask

An optional mask image in target space, whose nonzero region will be taken as the region of interest for the registration.

symmetric

Logical value. Should forward and reverse transformations be estimated simultaneously?

nLevels

A single integer specifying the number of levels of the algorithm that should be applied. If zero, no optimisation will be performed, and the final affine matrix will be the same as its initialisation value.

maxIterations

A single integer specifying the maximum number of iterations to be used within each level. Fewer iterations may be used if a convergence test deems the process to have completed.

useBlockPercentage

A single integer giving the percentage of blocks to use for calculating correspondence at each step of the algorithm. The blocks with the highest intensity variance will be chosen.

interpolation

A single integer specifying the type of interpolation to be applied to the final resampled image. May be 0 (nearest neighbour), 1 (trilinear) or 3 (cubic spline). No other values are valid.

verbose

A single logical value: if TRUE, the code will give some feedback on its progress; otherwise, nothing will be output while the algorithm runs. Run time can be seconds or more, depending on the size and dimensionality of the images.

estimateOnly

Logical value: if TRUE, transformations will be estimated, but images will not be resampled.

sequentialInit

If TRUE and source has higher dimensionality than target, transformations which are not explicitly initialised will begin from the result of the previous registration.

internal

If NA, the default, the final resampled image will be returned as a standard R array, but control point maps will be objects of class "internalImage", containing only basic metadata and a C-level pointer to the full image. (See also readNifti.) If TRUE, all image-type objects in the result will be internal images; if FALSE, they will all be R arrays. The default is fine for most purposes, but using TRUE may save memory, while using FALSE can be necessary if there is a chance that external pointers will be invalidated, for example when returning from worker threads.

precision

Working precision for the registration. Using single- precision may be desirable to save memory when coregistering large images.

threads

For OpenMP-capable builds of the package, the maximum number of threads to use.

Value

See niftyreg.

Details

This function performs the dual operations of finding a transformation to optimise image alignment, and resampling the source image into the space of the target image.

The algorithm is based on a block-matching approach and Least Trimmed Squares (LTS) fitting. Firstly, the block matching provides a set of corresponding points between a target and a source image. Secondly, using this set of corresponding points, the best rigid or affine transformation is evaluated. This two-step loop is repeated until convergence to the best transformation is achieved.

In the NiftyReg implementation, normalised cross-correlation between the target and source blocks is used to evaluate correspondence. The block width is constant and has been set to 4 voxels. A coarse-to-fine approach is used, where the registration is first performed on down-sampled images (using a Gaussian filter to resample images), and finally performed on full resolution images.

The source image may have 2, 3 or 4 dimensions, and the target 2 or 3. The dimensionality of the target image determines whether 2D or 3D registration is applied, and source images with one more dimension than the target (i.e. 4D to 3D, or 3D to 2D) will be registered volumewise or slicewise, as appropriate. In the latter case the last dimension of the resulting image is taken from the source image, while all other dimensions come from the target. One affine matrix is returned for each registration performed.

References

The algorithm used by this function is described in the following publication.

M. Modat, D.M. Cash, P. Daga, G.P. Winston, J.S. Duncan & S. Ourselin (2014). Global image registration using a symmetric block-matching approach. Journal of Medical Imaging 1(2):024003.

See also

niftyreg, which can be used as an interface to this function, and niftyreg.nonlinear for nonlinear registration. Also, forward and reverse to extract transformations, and applyTransform to apply them to new images or points.

Author

Jon Clayden <code@clayden.org>