diff --git a/fsl/data/image.py b/fsl/data/image.py index 5a7b68a083530c7c2185f2871efef85bbe97ece5..e1a839dc0b2039af959322074a02f464acea7739 100644 --- a/fsl/data/image.py +++ b/fsl/data/image.py @@ -90,7 +90,12 @@ class Image(props.HasProperties): """ - def __init__(self, image, xform=None, name=None, loadData=True): + def __init__(self, + image, + xform=None, + name=None, + header=None, + loadData=True): """Initialise an Image object with the given image data or file name. :arg image: A string containing the name of an image file to load, @@ -102,6 +107,11 @@ class Image(props.HasProperties): :arg name: A name for the image. + :arg header: If not ``None``, assumed to be a + :class:`nibabel.nifti1.Nifti1Header` to be used as the + image header. Not applied to images loaded from file, + or existing :mod:`nibabel` images. + :arg loadData: Defaults to ``True``. If ``False``, the image data is not loaded - this is useful if you're only interested in the header data, as the file will be loaded much @@ -113,6 +123,9 @@ class Image(props.HasProperties): self.imageFile = None self.tempFile = None + if header is not None: + header = header.copy() + # The image parameter may be the name of an image file if isinstance(image, basestring): @@ -136,10 +149,14 @@ class Image(props.HasProperties): # to 1mm^3 in real world space) elif isinstance(image, np.ndarray): - if xform is None: xform = np.identity(4) + if xform is None: + if header is None: xform = np.identity(4) + else: xform = header.get_best_affine() if name is None: name = 'Numpy array' - self.nibImage = nib.nifti1.Nifti1Image(image, xform) + self.nibImage = nib.nifti1.Nifti1Image(image, + xform, + header=header) self.name = name # otherwise, we assume that it is a nibabel image diff --git a/fsl/fslview/actions/copyimage.py b/fsl/fslview/actions/copyimage.py index d3e5345608736709b37c9225006cd74f48d13b72..89fd7c6e3385f93a4355187eb4f098f647073604 100644 --- a/fsl/fslview/actions/copyimage.py +++ b/fsl/fslview/actions/copyimage.py @@ -40,10 +40,10 @@ class CopyImageAction(actions.Action): if image is None: return - data = np.copy(image.data) - xform = image.voxToWorldMat - name = '{}_copy'.format(image.name) - copy = fslimage.Image(data, xform, name) + data = np.copy(image.data) + header = image.nibImage.get_header() + name = '{}_copy'.format(image.name) + copy = fslimage.Image(data, name=name, header=header) # TODO copy display properties diff --git a/fsl/fslview/controls/atlaspanel.py b/fsl/fslview/controls/atlaspanel.py index 0dcaf6e72a6be2c6cd4d6c580e06bea72ac4e744..ae6c30fc62c6629ab403f628c104c499958f2010 100644 --- a/fsl/fslview/controls/atlaspanel.py +++ b/fsl/fslview/controls/atlaspanel.py @@ -119,10 +119,10 @@ class AtlasPanel(fslpanel.FSLViewPanel): log.debug('{}/{} clicked'.format(atlasID, label.name)) if isinstance(atlas, atlases.ProbabilisticAtlas): - pass + self.toggleOverlay(atlasID, labelIndex, False) elif isinstance(atlas, atlases.LabelAtlas): - self.toggleLabelOverlay(atlasID, labelIndex) + self.toggleOverlay(atlasID, labelIndex, True) @@ -146,11 +146,10 @@ class AtlasPanel(fslpanel.FSLViewPanel): pass - def toggleProbabilisticOverlay(self, atlasID, labelIndex): - pass - - def toggleLabelOverlay(self, atlasID, labelIndex): + def toggleOverlay(self, atlasID, labelIndex, label): + """ + """ desc = self.atlasDescs[atlasID] overlayName = '{}/{}'.format(atlasID, desc.labels[labelIndex].name) @@ -166,26 +165,35 @@ class AtlasPanel(fslpanel.FSLViewPanel): if atlas is None: atlas = atlases.loadAtlas(self.atlasDescs[atlasID], True) - if desc.atlasType == 'probabilistic': labelVal = labelIndex + 1 - elif desc.atlasType == 'label': labelVal = labelIndex + if label: + if desc.atlasType == 'probabilistic': + labelVal = labelIndex + 1 + elif desc.atlasType == 'label': + labelVal = labelIndex - mask = np.zeros(atlas.shape, dtype=np.uint8) - mask[atlas.data == labelIndex] = labelVal + mask = np.zeros(atlas.shape, dtype=np.uint8) + mask[atlas.data == labelIndex] = labelVal + else: + mask = atlas.data[..., labelIndex] overlay = fslimage.Image( mask, - atlas.voxToWorldMat, + header=atlas.nibImage.get_header(), name=overlayName) - overlay.imageType = 'mask' + + if label: + overlay.imageType = 'mask' log.debug('Adding overlay {}'.format(overlayName)) self._imageList.append(overlay) display = self._displayCtx.getDisplayProperties(overlay) - display.getDisplayOpts().colour = np.random.random(3) - + if label: + display.getDisplayOpts().colour = np.random.random(3) + else: + display.getDisplayOpts().cmap = 'hot' diff --git a/fsl/fslview/displaycontext/volumeopts.py b/fsl/fslview/displaycontext/volumeopts.py index 4485112421449978edbe10dea0bf78a2d5e0b1cc..00125ed33eb249b9d00f086503e18b8d09a585d3 100644 --- a/fsl/fslview/displaycontext/volumeopts.py +++ b/fsl/fslview/displaycontext/volumeopts.py @@ -52,7 +52,7 @@ class VolumeOpts(fsldisplay.DisplayOpts): """Image values which map to the minimum and maximum colour map colours.""" - clipLow = props.Boolean(default=False) + clipLow = props.Boolean(default=True) """If ``True``, don't display voxel values which are lower than the :attr:`displayRange`. """ diff --git a/fsl/fslview/editor/editor.py b/fsl/fslview/editor/editor.py index 04d94daf85c9b64e732d9f8559c7b5ecf7bce885..356221338282c828d43980358a16b2967b787d80 100644 --- a/fsl/fslview/editor/editor.py +++ b/fsl/fslview/editor/editor.py @@ -260,10 +260,10 @@ class Editor(props.HasProperties): image = self._imageList[imageIdx] mask = np.array(self._selection.selection, dtype=np.uint8) - xform = image.voxToWorldMat - name = '{}_mask'.format(image.name) + header = image.nibImage.get_header() + name = '{}_mask'.format(image.name) - roiImage = fslimage.Image(mask, xform, name) + roiImage = fslimage.Image(mask, name=name, header=header) self._imageList.insert(imageIdx + 1, roiImage) @@ -276,8 +276,8 @@ class Editor(props.HasProperties): roi[self._selection.selection] = image.data[self._selection.selection] - xform = image.voxToWorldMat - name = '{}_roi'.format(image.name) + header = image.nibImage.get_header() + name = '{}_roi'.format(image.name) - roiImage = fslimage.Image(roi, xform, name) + roiImage = fslimage.Image(roi, name=name, header=header) self._imageList.insert(imageIdx + 1, roiImage)