Newer
Older
#!/usr/bin/env python
#
# flirt.py - Functions for working with FLIRT matrices.
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#
"""This module contains functions for working with FLIRT affine transformation
matrices. The following functions are available:
.. autosummary::
:nosignatures:
readFlirt
writeFlirt
fromFlirt
toFlirt
flirtMatrixToSform
sformToFlirtMatrix
FLIRT transformation matrices are affine matrices of shape ``(4, 4)`` which
encode a linear transformation from a source image to a reference image. FLIRT
matrices are defined in terms of *FSL coordinates*, which is a coordinate
system where voxels are scaled by pixdims, and with a left-right flip if the
image ``sform`` has a positive determinant.
FLIRT matrices thus encode a transformation from source image FSL coordinates
to reference image FSL coordinates.
"""
import numpy as np
from .affine import concat
def readFlirt(fname):
"""Reads a FLIRT matrix from a file. """
return np.loadtxt(fname)
def writeFlirt(xform, fname):
"""Writes the given FLIRT matrix to a file. """
np.savetxt(fname, xform, fmt='%1.15g')
def fromFlirt(xform, src, ref, from_='voxel', to='world'):
"""Convert a FLIRT affine matrix into another affine.
Given a FLIRT matrix, and the source and reference images with which the
FLIRT matrix is associated, converts the matrix into an affine matrix
which can transform coordinates from the source image ``from_`` coordinate
system to the reference image ``to`` coordinate system.
The ``from_`` and ``to`` arguments specify the desired spaces that the
returned affine should transform between. The default values
(``from_='voxel'`` and ``to='world'`` will generate an affine which
transforms from voxels in the source image to world-coordinates in the
reference image.
Valid values for the ``from_`` and ``to`` arguments are:
- ``voxel``: The voxel coordinate system
- ``fsl``: The FSL coordiante system (voxels scaled by pixdims, with the
X axis inverted if the image sform/qform has a positive determinant)
- ``world`` The world coordinate system
See the :class:`.Nifti` class documentation and the
:meth:`.Nifti.getAffine` method for more details.
:arg xform: ``numpy`` array of shape ``(4, 4)`` containing a FLIRT
transformation matrix.
:arg src: :class:`.Nifti` object, the ``xform`` source image
:arg ref: :class:`.Nifti` object, the ``xform`` reference image
:arg from_: Desired source coordinate system
:returns: ``numpy`` array of shape ``(4, 4)`` containing a matrix
encoding a transformation from the source ``from_`` to
the reference ``to`` coordinate systems.
"""
premat = src.getAffine(from_, 'fsl')
postmat = ref.getAffine('fsl', to)
return concat(postmat, xform, premat)
def toFlirt(xform, src, ref, from_='voxel', to='world'):
:returns: ``numpy`` array of shape ``(4, 4)`` containing a matrix
encoding a transformation from the source ``from_`` to
the reference ``to`` coordinate systems.
:arg src: :class:`.Nifti` object, the ``xform`` source image
:arg ref: :class:`.Nifti` object, the ``xform`` reference image
:arg from_: ``xform`` source coordinate system
:arg to: ``xform`` target coordinate system
:returns: A ``numpy`` array of shape ``(4, 4)`` containing a FLIRT
transformation matrix from ``src`` to ``ref``.
"""
premat = src.getAffine('fsl', from_)
postmat = ref.getAffine(to, 'fsl')
return concat(postmat, xform, premat)
def flirtMatrixToSform(flirtMat, srcImage, refImage):
"""Converts the given ``FLIRT`` transformation matrix into a
transformation from the source image voxel coordinate system to
the reference image world coordinate system.
To construct a transformation from source image voxel coordinates into
reference image world coordinates, we need to combine the following:
1. Source voxels -> Source scaled voxels
2. Source scaled voxels -> Reference scaled voxels (the FLIRT matrix)
3. Reference scaled voxels -> Reference voxels
4. Reference voxels -> Reference world (the reference image sform)
:arg flirtMat: A ``(4, 4)`` transformation matrix
:arg srcImage: Source :class:`.Image`
:arg refImage: Reference :class:`.Image`
"""
return fromFlirt(flirtMat, srcImage, refImage, 'voxel', 'world')
def sformToFlirtMatrix(srcImage, refImage, srcXform=None):
"""Under the assumption that the given ``srcImage`` and ``refImage`` share a
common world coordinate system (defined by their
:attr:`.Nifti.voxToWorldMat` attributes), this function will calculate and
return a transformation matrix from the ``srcImage`` FSL coordinate system
to the ``refImage`` FSL coordinate system, that can be saved to disk and
used with FLIRT, to resample the source image to the space of the
reference image.
:arg srcImage: Source :class:`.Image`
:arg refImage: Reference :class:`.Image`
:arg srcXform: Optionally used in place of the ``srcImage``
:attr:`.Nifti.voxToWorldMat`
"""
srcScaledVoxToVoxMat = srcImage.scaledVoxToVoxMat
srcVoxToWorldMat = srcImage.voxToWorldMat
refWorldToVoxMat = refImage.worldToVoxMat
refVoxToScaledVoxMat = refImage.voxToScaledVoxMat
if srcXform is not None:
srcVoxToWorldMat = srcXform
return concat(refVoxToScaledVoxMat,
refWorldToVoxMat,
srcVoxToWorldMat,
srcScaledVoxToVoxMat)