Skip to content
Snippets Groups Projects
Commit 07fc4c17 authored by Paul McCarthy's avatar Paul McCarthy :mountain_bicyclist:
Browse files

ENH: resampleToReference now accepts a custom matrix, allowing us to apply a

transformation (e.g. FLIRT registration) during the resampling. Missed imports
in deprecated fsl.utils.transform
parent 9b9b4caf
No related branches found
No related tags found
No related merge requests found
...@@ -39,7 +39,7 @@ def resampleToPixdims(image, newPixdims, **kwargs): ...@@ -39,7 +39,7 @@ def resampleToPixdims(image, newPixdims, **kwargs):
return resample(image, newShape, **kwargs) return resample(image, newShape, **kwargs)
def resampleToReference(image, reference, **kwargs): def resampleToReference(image, reference, matrix=None, **kwargs):
"""Resample ``image`` into the space of the ``reference``. """Resample ``image`` into the space of the ``reference``.
This is a wrapper around :func:`resample` - refer to its documenttion This is a wrapper around :func:`resample` - refer to its documenttion
...@@ -49,6 +49,7 @@ def resampleToReference(image, reference, **kwargs): ...@@ -49,6 +49,7 @@ def resampleToReference(image, reference, **kwargs):
along the spatial (first three) dimensions. along the spatial (first three) dimensions.
:arg image: :class:`.Image` to resample :arg image: :class:`.Image` to resample
:arg matrix: Optional world-to-world affine alignment matrix
:arg reference: :class:`.Nifti` defining the space to resample ``image`` :arg reference: :class:`.Nifti` defining the space to resample ``image``
into into
""" """
...@@ -56,6 +57,9 @@ def resampleToReference(image, reference, **kwargs): ...@@ -56,6 +57,9 @@ def resampleToReference(image, reference, **kwargs):
oldShape = list(image.shape) oldShape = list(image.shape)
newShape = list(reference.shape[:3]) newShape = list(reference.shape[:3])
if matrix is None:
matrix = np.eye(4)
# If the input image is >3D, pad the # If the input image is >3D, pad the
# new shape so that we only resample # new shape so that we only resample
# along the first 3 dimensions. # along the first 3 dimensions.
...@@ -64,7 +68,9 @@ def resampleToReference(image, reference, **kwargs): ...@@ -64,7 +68,9 @@ def resampleToReference(image, reference, **kwargs):
# Align the two images together # Align the two images together
# via their vox-to-world affines. # via their vox-to-world affines.
matrix = affine.concat(image.worldToVoxMat, reference.voxToWorldMat) matrix = affine.concat(image.worldToVoxMat,
affine.invert(matrix),
reference.voxToWorldMat)
# If the input image is >3D, we # If the input image is >3D, we
# have to adjust the resampling # have to adjust the resampling
...@@ -82,7 +88,12 @@ def resampleToReference(image, reference, **kwargs): ...@@ -82,7 +88,12 @@ def resampleToReference(image, reference, **kwargs):
kwargs['newShape'] = newShape kwargs['newShape'] = newShape
kwargs['matrix'] = matrix kwargs['matrix'] = matrix
return resample(image, **kwargs) data = resample(image, **kwargs)[0]
# The image is now in the same space
# as the reference, so it inherits
# ref's voxel-to-world affine
return data, reference.voxToWorldMat
def resample(image, def resample(image,
...@@ -113,6 +124,12 @@ def resample(image, ...@@ -113,6 +124,12 @@ def resample(image,
particularly on the ``order``, ``matrix``, ``mode`` and particularly on the ``order``, ``matrix``, ``mode`` and
``cval`` arguments. ``cval`` arguments.
.. note:: If a custom resampling ``matrix`` is specified, the adjusted
voxel-to-world afffine cannot be calculated by this function,
so ``None`` will be returned instead.
:arg image: :class:`.Image` object to resample
:arg newShape: Desired shape. May containg floating point values, in which :arg newShape: Desired shape. May containg floating point values, in which
case the resampled image will have shape case the resampled image will have shape
``round(newShape)``, but the voxel sizes will have scales ``round(newShape)``, but the voxel sizes will have scales
...@@ -159,7 +176,8 @@ def resample(image, ...@@ -159,7 +176,8 @@ def resample(image,
- A ``numpy`` array of shape ``(4, 4)``, containing the - A ``numpy`` array of shape ``(4, 4)``, containing the
adjusted voxel-to-world transformation for the spatial adjusted voxel-to-world transformation for the spatial
dimensions of the resampled data. dimensions of the resampled data, or ``None`` if a ``matrix``
was provided.
""" """
if sliceobj is None: sliceobj = slice(None) if sliceobj is None: sliceobj = slice(None)
...@@ -168,6 +186,8 @@ def resample(image, ...@@ -168,6 +186,8 @@ def resample(image,
if mode is None: mode = 'nearest' if mode is None: mode = 'nearest'
if origin == 'center': origin = 'centre' if origin == 'center': origin = 'centre'
ownMatrix = matrix is None
if origin not in ('centre', 'corner'): if origin not in ('centre', 'corner'):
raise ValueError('Invalid value for origin: {}'.format(origin)) raise ValueError('Invalid value for origin: {}'.format(origin))
...@@ -218,7 +238,15 @@ def resample(image, ...@@ -218,7 +238,15 @@ def resample(image,
matrix[:3, :3] = rotmat matrix[:3, :3] = rotmat
matrix[:3, -1] = offsets matrix[:3, -1] = offsets
matrix = affine.concat(image.voxToWorldMat, matrix) # We can only adjust the v2w affine if
# the input space and resampling space
# are aligned (e.g. if we're just
# resampling to different dimensions).
# We can't assume this when a custom
# matrix is specified, so we just give
# up and return None.
if ownMatrix: matrix = affine.concat(image.voxToWorldMat, matrix)
else: matrix = None
return data, matrix return data, matrix
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
import fsl.utils.deprecated as deprecated import fsl.utils.deprecated as deprecated
from fsl.transform.affine import * # noqa from fsl.transform.affine import * # noqa
from fsl.transform.flirt import (flirtMatrixToSform, # noqa
sformToFlirtMatrix)
deprecated.warn('fsl.utils.transform', deprecated.warn('fsl.utils.transform',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment