Skip to content
Snippets Groups Projects
Commit e2fd9446 authored by Paul McCarthy's avatar Paul McCarthy
Browse files

2D nifti images are supported - they are forced to be 3D.

parent e1afbc10
No related branches found
No related tags found
No related merge requests found
...@@ -146,8 +146,10 @@ class Nifti1(object): ...@@ -146,8 +146,10 @@ class Nifti1(object):
else: else:
self.nibImage = image self.nibImage = image
self.shape = self.nibImage.get_shape() shape, pixdim = self.__determineShape(self.nibImage)
self.pixdim = self.nibImage.get_header().get_zooms()
self.shape = shape
self.pixdim = pixdim
self.voxToWorldMat = np.array(self.nibImage.get_affine()) self.voxToWorldMat = np.array(self.nibImage.get_affine())
self.worldToVoxMat = transform.invert(self.voxToWorldMat) self.worldToVoxMat = transform.invert(self.voxToWorldMat)
...@@ -158,6 +160,39 @@ class Nifti1(object): ...@@ -158,6 +160,39 @@ class Nifti1(object):
if len(self.shape) < 3 or len(self.shape) > 4: if len(self.shape) < 3 or len(self.shape) > 4:
raise RuntimeError('Only 3D or 4D images are supported') raise RuntimeError('Only 3D or 4D images are supported')
def __determineShape(self, nibImage):
"""This method is called by :meth:`__init__`. It figures out the shape
of the image data, and the zooms/pixdims for each data axis. Any empty
trailing dimensions are squeezed, but the returned shape is guaranteed
to be at least 3 dimensions.
"""
nibHdr = nibImage.get_header()
shape = list(nibImage.shape)
pixdims = list(nibHdr.get_zooms())
# Squeeze out empty dimensions, as
# 3D image can sometimes be listed
# as having 4 or more dimensions
for i in reversed(range(len(shape))):
if shape[i] == 1: shape = shape[:i]
else: break
# But make sure the shape is 3D
if len(shape) < 3:
shape = shape + [1] * (3 - len(shape))
# The same goes for the pixdim - if get_zooms()
# doesn't return at least 3 values, we'll fall
# back to the pixdim field in the header.
if len(pixdims) < 3:
pixdims = nibHdr['pixdim'][1:]
pixdims = pixdims[:len(shape)]
return shape, pixdims
def loadData(self): def loadData(self):
...@@ -165,30 +200,26 @@ class Nifti1(object): ...@@ -165,30 +200,26 @@ class Nifti1(object):
be called if the ``loadData`` parameter passed to :meth:`__init__` be called if the ``loadData`` parameter passed to :meth:`__init__`
was ``False``. was ``False``.
""" """
data = self.nibImage.get_data()
# Squeeze out empty dimensions, as # Get the data, and reshape it according
# 3D image can sometimes be listed # to the shape that the __determineShape
# as having 4 or more dimensions # method figured out.
shape = data.shape data = self.nibImage.get_data()
origShape = data.shape
for i in reversed(range(len(shape))): data = data.reshape(self.shape)
if shape[i] == 1: data = data.squeeze(axis=i)
else: break
# Tell numpy to make the
# data array read-only
data.flags.writeable = False data.flags.writeable = False
self.data = data
log.debug('Loaded image data ({}) - original ' log.debug('Loaded image data ({}) - original '
'shape {}, squeezed shape {}'.format( 'shape {}, squeezed shape {}'.format(
self.dataSource, self.dataSource,
shape, origShape,
data.shape)) data.shape))
self.data = data
self.shape = self.shape[ :len(data.shape)]
self.pixdim = self.pixdim[:len(data.shape)]
# TODO: Remove this method, and use the shape attribute directly # TODO: Remove this method, and use the shape attribute directly
def is4DImage(self): def is4DImage(self):
......
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