Commit 956cfb7e authored by Paul McCarthy's avatar Paul McCarthy 🚵
Browse files

Merge branch 'enh/set-intensity-from-region' into 'master'

Set display range from region

See merge request fsl/fsleyes/fsleyes!293
parents 399b03b7 7cb587fc
.. |right_arrow| unicode:: U+21D2
.. |command_key| unicode:: U+2318
.. |shift_key| unicode:: U+21E7
.. |control_key| unicode:: U+2303
.. |eye_icon| image:: images/eye_icon.png
.. |spanner_icon| image:: images/spanner_icon.png
......@@ -9,8 +10,8 @@ This document contains the ``fsleyes`` release history in reverse
chronological order.
1.3.0 (Under development)
-------------------------
1.3.0 (Monday 18th October 2021)
--------------------------------
Added
......@@ -19,6 +20,10 @@ Added
* The 3D view now allows the display location to be set to the corresponding
location under the mouse on a volume overlay, by shift+clicking (!290).
* The display range for a ``volume`` overlay can now be adjusted interactively
by |command_key| + |shift_key| + right clicking (|control_key| + |shift_key|
on Linux) and dragging to select a region - the display range will be set to
the minimum/maximum voxel intensities within that region (!293).
Changed
......@@ -34,9 +39,12 @@ Changed
Fixed
^^^^^
* The **Display space** |right_arrow| *Scaled voxel coordinates* setting no
longer applies a L/R flip for images with neurological data storage order
(!289).
* The high clipping range is no longer set when loading a Melodic image
with the ``--autoDisplay`` / ``-ad`` option.(!293).
1.2.0 (Monday 13th September 2021)
......
......@@ -196,11 +196,11 @@ def _MelodicImageDisplay(overlay, overlayList, displayCtx):
dmin = 3
dmax = 10
opts.cmap = 'Red-Yellow'
opts.negativeCmap = 'Blue-LightBlue'
opts.useNegativeCmap = True
opts.displayRange = [dmin, dmax]
opts.clippingRange = [dmin, dmax]
opts.cmap = 'Red-Yellow'
opts.negativeCmap = 'Blue-LightBlue'
opts.useNegativeCmap = True
opts.displayRange = [dmin, dmax]
opts.clippingRange.xlo = dmin
# Add the mean as an underlay
idx = overlayList.index(overlay)
......
......@@ -56,6 +56,8 @@ FILTERS = [
r'\*\*\* BUG \*\*\*',
r'In pixman',
r'Set a breakpoint',
r'^ *$',
r'Warning: Expected min height of view:',
]
......
......@@ -1074,8 +1074,10 @@ class Profile(props.SyncableHasProperties, actions.ActionProvider):
return retval
if len(handlers) > 0:
log.debug('{} Handler(s) found for mode {}, event {}'.format(
len(handlers), mode, evType))
log.debug('%i Handler(s) found for mode %s, event %s '
'(ctrl: %s, shift: %s, alt: %s)',
len(handlers), mode, evType, ev.ControlDown(),
ev.ShiftDown(), ev.AltDown())
return handlerWrapper
return None
......
......@@ -33,31 +33,40 @@ class OrthoViewProfile(profiles.Profile):
``OrthoViewProfile`` defines the following *modes* (see the
:class:`.Profile` class documentation):
========== ==============================================================
``nav`` The user can change the currently displayed location. This is
accomplished by updating the :attr:`.DisplayContext.location`
property on left mouse drags.
``slice`` The user can change the current slice shown on a single
canvas.
``zoom`` The user can zoom in/out of a canvas with the mouse wheel, and
draw a rectangle on a canvas in which to zoom. This is
accomplished by updating the :attr:`.SliceCanvasOpts.zoom`
property on mouse wheel changes, and displaying a
:class:`~.annotations.Rect` annotation on left mouse drags.
``pan`` The user can pan around a canvas (if the canvas is zoomed in).
This is accomplished by calling the
:meth:`.SliceCanvas.panDisplayBy` on left mouse drags.
``bricon`` The user can drag the mouse along a canvas to change the
brightness/contrast of the currently selected overlay.
``pick`` If the currently selected overlay is a :class:`.Mesh`,
the user can select the mesh vertex which is nearest to the
mouse click.
========== ==============================================================
================ ========================================================
``nav`` The user can change the currently displayed location.
This is accomplished by updating the
:attr:`.DisplayContext.location` property on left mouse
drags.
``slice`` The user can change the current slice shown on a single
canvas.
``zoom`` The user can zoom in/out of a canvas with the mouse
wheel, and draw a rectangle on a canvas in which to
zoom. This is accomplished by updating the
:attr:`.SliceCanvasOpts.zoom` property on mouse wheel
changes, and displaying a :class:`~.annotations.Rect`
annotation on left mouse drags.
``pan`` The user can pan around a canvas (if the canvas is
zoomed in). This is accomplished by calling the
:meth:`.SliceCanvas.panDisplayBy` on left mouse drags.
``bricon`` The user can drag the mouse along a canvas to change
the brightness/contrast of the currently selected
overlay.
``regionBricon`` The user can draw a rectangle on a canvas; the minimum /
maximum display range of the currently selected overlay
(assuming it is an :class:`.Image` being displayed as
a ``volume``) is set to the minimum/maxmimum intensity
within the region.
``pick`` If the currently selected overlay is a :class:`.Mesh`,
the user can select the mesh vertex which is nearest to
the mouse click.
================ ========================================================
The ``OrthoViewProfile`` class also defines a few :mod:`.actions`:
......@@ -130,7 +139,13 @@ class OrthoViewProfile(profiles.Profile):
# In pick mode, left mouse down
# is the same as left mouse drag.
('pick', 'LeftMouseDown') : ('pick', 'LeftMouseDrag')}
('pick', 'LeftMouseDown') : ('pick', 'LeftMouseDrag'),
# In bricon mode, right click+drag
# invokes regionBricon mode
('bricon', 'RightMouseDown') : ('regionBricon', 'LeftMouseDrag'),
('bricon', 'RightMouseDrag') : ('regionBricon', 'LeftMouseDrag'),
('bricon', 'RightMouseUp') : ('regionBricon', 'LeftMouseUp')}
@staticmethod
......@@ -170,7 +185,8 @@ class OrthoViewProfile(profiles.Profile):
if extraModes is None:
extraModes = []
modes = ['nav', 'slice', 'pan', 'zoom', 'bricon', 'pick'] + extraModes
modes = ['nav', 'slice', 'pan', 'zoom', 'bricon',
'pick', 'regionBricon'] + extraModes
profiles.Profile.__init__(self,
viewPanel,
......@@ -188,10 +204,12 @@ class OrthoViewProfile(profiles.Profile):
self.__ycanvas = viewPanel.getYCanvas()
self.__zcanvas = viewPanel.getZCanvas()
# This attribute will occasionally store a
# reference to a gl.annotations.Rect -
# see the _zoomModeLeftMouse* handlers
self.__lastRect = None
# These attributes will occasionally store
# references to gl.annotations.Rect objects -
# see the _zoomModeRightMouse* and
# _regionBriconModeLeftMouse* handlers
self.__zoomLastRect = None
self.__regionBriconLastRect = None
# This attribute is used by the
# bricon mode methods
......@@ -557,17 +575,17 @@ class OrthoViewProfile(profiles.Profile):
return False
copts = canvas.opts
x, y = [canvasDownPos[copts.xax], canvasDownPos[copts.yax]]
width = canvasPos[copts.xax] - x
height = canvasPos[copts.yax] - y
self.__lastRect = canvas.getAnnotations().rect(x, y,
width,
height,
width=1,
filled=False,
colour=(1, 1, 0))
self.__zoomLastRect = canvas.getAnnotations().rect(
x, y,
width,
height,
width=1,
filled=False,
colour=(1, 1, 0))
canvas.Refresh()
return True
......@@ -588,9 +606,9 @@ class OrthoViewProfile(profiles.Profile):
canvasDownPos is None:
return False
if self.__lastRect is not None:
canvas.getAnnotations().dequeue(self.__lastRect)
self.__lastRect = None
if self.__zoomLastRect is not None:
canvas.getAnnotations().dequeue(self.__zoomLastRect)
self.__zoomLastRect = None
copts = canvas.opts
xlo = min(canvasPos[copts.xax], canvasDownPos[copts.xax])
......@@ -807,3 +825,102 @@ class OrthoViewProfile(profiles.Profile):
loc = opts.transformCoords(loc, 'mesh', 'display')
self.displayCtx.location.xyz = loc
###################
# regionBricon mode
###################
def _regionBriconModeLeftMouseDrag(
self, ev, canvas, mousePos, canvasPos):
"""Handles mouse drags in ``regionBricon`` mode.
Right mouse drags in this mode draw a rectangle on the target
canvas. When the user releases the mouse (see
:meth:`_regionBriconModeLeftMouseUp`), the min/max display range
of the currently selected overlay (assuming it is a ``volume``)
is set to the minimum/maximum intensities within the region.
"""
canvasDownPos = self.getMouseDownLocation()[1]
if canvasPos is None or canvasDownPos is None:
return False
overlay = self.displayCtx.getSelectedOverlay()
if overlay is None:
return
display = self.displayCtx.getDisplay(overlay)
opts = self.displayCtx.getOpts( overlay)
if display.overlayType != 'volume':
return
copts = canvas.opts
x, y = [canvasDownPos[copts.xax], canvasDownPos[copts.yax]]
width = canvasPos[copts.xax] - x
height = canvasPos[copts.yax] - y
self.__regionBriconLastRect = canvas.getAnnotations().rect(
x, y,
width,
height,
width=1,
filled=False,
colour=(0, 1, 1))
canvas.Refresh()
return True
def _regionBriconModeLeftMouseUp(
self, ev, canvas, mousePos, canvasPos):
"""Handles mouse up events in ``regionBricon`` mode.
Sets the min/max display range of the currently selected overlay
(assuming it is a ``volume``) to the minimum/maximum
intensities within the region.
"""
mouseDownPos, canvasDownPos = self.getMouseDownLocation()
if canvasPos is None or \
mouseDownPos is None or \
canvasDownPos is None or \
self.__regionBriconLastRect is None:
return False
# Clear canvas annotation
canvas.getAnnotations().dequeue(self.__regionBriconLastRect)
self.__regionBriconLastRect = None
canvas.Refresh()
# Bail if not volume
overlay = self.displayCtx.getSelectedOverlay()
if overlay is None:
return
display = self.displayCtx.getDisplay(overlay)
opts = self.displayCtx.getOpts( overlay)
if display.overlayType != 'volume':
return
# Turn box coordinates into voxels
coords = opts.transformCoords([canvasDownPos, canvasPos],
'display', 'voxel', vround=True)
coords = coords.astype(np.int)
xlo, ylo, zlo = coords.min(axis=0)
xhi, yhi, zhi = coords.max(axis=0) + 1
slc = (slice(xlo, xhi),
slice(ylo, yhi),
slice(zlo, zhi))
# Calculate min/max, set display range
data = overlay.data[opts.index(slc)]
if data.size == 0:
return
dmin = np.nanmin(data)
dmax = np.nanmax(data)
opts.displayRange = dmin, dmax
return True
#!/usr/bin/env python
import os.path as op
from fsl.data.image import Image
from fsleyes.tests import run_with_orthopanel, realYield, mockMouseEvent
datadir = op.join(op.dirname(__file__), 'testdata')
def test_regionBriconMode():
run_with_orthopanel(_test_regionBriconMode)
def _test_regionBriconMode(ortho, overlayList, displayCtx):
img = Image(op.join(datadir, '3d'))
overlayList.append(img)
realYield()
opts = ortho.displayCtx.getOpts(img)
profile = ortho.currentProfile
zcanvas = ortho.getGLCanvases()[2]
z = int(opts.transformCoords([displayCtx.location],
'display',
'voxel',
vround=True)[0, 2])
vstart = [ 3, 3, z]
vend = [ 10, 10, z]
dstart = opts.transformCoords(vstart, 'voxel', 'display')
dend = opts.transformCoords(vend, 'voxel', 'display')
profile.mode = 'regionBricon'
mockMouseEvent(profile, zcanvas, 'LeftMouseDown', dstart)
mockMouseEvent(profile, zcanvas, 'LeftMouseDrag', dstart)
mockMouseEvent(profile, zcanvas, 'LeftMouseUp', dend)
realYield()
sx, sy, sz = vstart
ex, ey, ez = vend
data = img.data[sx:ex + 1, sy:ey + 1, sz:ez + 1]
dmin = data.min()
dmax = data.max()
assert opts.displayRange == (dmin, dmax)
......@@ -33,10 +33,10 @@ Modifier keys
The following symbols and terms are used to represent various keyboard keys:
- |shift_key|: Shift
- |control_key|: Control
- |command_key|: Command (on macOS; Control on other platforms)
- |alt_key|: Option (on macOS; Alt on other platforms)
- |shift_key|: Shift key
- |control_key|: Control key
- |command_key|: Command key (on macOS; Control key on other platforms)
- |alt_key|: Option key (on macOS; Alt on other platforms)
- |up_key|: Up arrow key
- |down_key|: Down arrow key
- |left_key|: Left arrow key
......@@ -187,20 +187,34 @@ The following actions are available in the ortho view.
.. rst-class:: linewrap-table
======================================== =====================================
Shortcut Action
======================================== =====================================
Left mouse click/drag Change location
Right mouse drag Zoom to rectangle
Middle mouse drag Pan
|command_key| + mouse wheel/scroll Zoom
|alt_key| + mouse drag Pan
|shift_key| + mouse wheel/scroll Change slice
|shift_key| + mouse click/drag Select nearest vertex (when a
:ref:`mesh overlay <overlays_mesh>`
is selected
|command_key| + |shift_key| + mouse drag Adjust brightness/contrast
======================================== =====================================
+-----------------------------------+-----------------------------------------+
| Shortcut | Action |
+-----------------------------------+-----------------------------------------+
| Left mouse click/drag | Change location |
+-----------------------------------+-----------------------------------------+
| Right mouse drag | Zoom to rectangle |
+-----------------------------------+-----------------------------------------+
| Middle mouse drag | Pan |
+-----------------------------------+-----------------------------------------+
| |command_key| + mouse wheel/ | Zoom |
| scroll | |
+-----------------------------------+-----------------------------------------+
| |alt_key| + mouse drag | Pan |
+-----------------------------------+-----------------------------------------+
| |shift_key| + mouse wheel/scroll | Change slice |
+-----------------------------------+-----------------------------------------+
| |shift_key| + mouse click+drag | Select nearest vertex (when a |
| | :ref:`mesh overlay <overlays_mesh>` |
| | is selected) |
+-----------------------------------+-----------------------------------------+
| |command_key| + |shift_key| + | Adjust brightness/contrast with the |
| mouse click+drag | mouse |
+-----------------------------------+-----------------------------------------+
| |command_key| + |shift_key| + | Adjust brightness/contrast by |
| right mouse click+drag | selecting a region (when a |
| | :ref:`volume overlay <overlays_volume>` |
| | is selected) |
+-----------------------------------+-----------------------------------------+
The following actions are available in the lightbox view.
......@@ -211,7 +225,7 @@ The following actions are available in the lightbox view.
======================================== =====================================
Shortcut Action
======================================== =====================================
Left mouse click/drag Change location
Left mouse click+drag Change location
|command_key| + mouse wheel/scroll Zoom
======================================== =====================================
......@@ -221,17 +235,21 @@ The following actions are available in the 3D view.
.. rst-class:: linewrap-table
======================================== =====================================
Shortcut Action
======================================== =====================================
Left mouse click/drag Rotate scene
Moddle mouse click/drag Pan
|command_key| + mouse wheel/scroll Zoom
|alt_key| + mouse click/drag Pan
|shift_key| + mouse click/drag Change location, or select nearest
vertex, when a mesh overlay is
selected
======================================== =====================================
+---------------------------------------+---------------------------------+
| Shortcut | Action |
+---------------------------------------+---------------------------------+
| Left mouse click+drag | Rotate scene |
+---------------------------------------+---------------------------------+
| Middle mouse click+drag | Pan |
+---------------------------------------+---------------------------------+
| |command_key| + mouse wheel/scroll | Zoom |
+---------------------------------------+---------------------------------+
| |alt_key| + mouse click+drag | Pan |
+---------------------------------------+---------------------------------+
| |shift_key| + mouse click+drag | Select nearest vertex (for mesh |
| | overlays) or voxel (for volume |
| | overlays) |
+---------------------------------------+---------------------------------+
Ortho edit mode
......@@ -270,27 +288,27 @@ select-by-intensity tools:
+-------------------------------------+---------------------------------------+
| *All tools* |
+-------------------------------------+---------------------------------------+
| |shift_key| + left mouse click/drag | Change location |
| |shift_key| + left mouse click+drag | Change location |
+-------------------------------------+---------------------------------------+
| |shift_key| + mouse wheel/scroll | Change slice |
+-------------------------------------+---------------------------------------+
| |alt_key| + left mouse click/drag | Pan |
| |alt_key| + left mouse click+drag | Pan |
+-------------------------------------+---------------------------------------+
| |command_key| + mouse wheel/scroll | Zoom |
+-------------------------------------+---------------------------------------+
| Middle mouse click/drag | Pan |
| Middle mouse click+drag | Pan |
+-------------------------------------+---------------------------------------+
| *Pencil tool* |
+-------------------------------------+---------------------------------------+
| Left mouse click/drag | Draw/select voxels |
| Left mouse click+drag | Draw/select voxels |
+-------------------------------------+---------------------------------------+
| Right mouse click/drag | Erase/de-select voxels |
| Right mouse click+drag | Erase/de-select voxels |
+-------------------------------------+---------------------------------------+
| *Eraser tool* |
+-------------------------------------+---------------------------------------+
| Left mouse click/drag | Erase/de-select voxels |
| Left mouse click+drag | Erase/de-select voxels |
+-------------------------------------+---------------------------------------+
| Right mouse click/drag | Draw/select voxels |
| Right mouse click+drag | Draw/select voxels |
+-------------------------------------+---------------------------------------+
| *Pencil and eraser tools* |
+-------------------------------------+---------------------------------------+
......@@ -318,9 +336,9 @@ The following actions are available when using the ortho crop tool.
======================================== =====================================
Shortcut Action
======================================== =====================================
Left mouse click/drag Adjust crop box
|shift_key| + left mouse click/drag Change location
|shift_key| + left mouse click/drag Change location
|alt_key| + left mouse click/drag Pan
Left mouse click+drag Adjust crop box
|shift_key| + left mouse click+drag Change location
|shift_key| + left mouse click+drag Change location
|alt_key| + left mouse click+drag Pan
|command_key| + mouse wheel/scroll Zoom
======================================== =====================================
......@@ -75,6 +75,11 @@ You can interact with an ortho view in a number of ways:
currently selected overlay. Moving the mouse vertically will adjust the
contrast, and horizontally will adjust the brightness.
- Hold down the |shift_key| key and the |command_key|/|control_key| key, then
right-click and drag the mouse to select a region in the currently selected
image. When you release the mouse, the image display range will be set to
the minimum/maxmimum voxel intensities within the selected region.
- You can reset the view to its default zoom/pan settings by pressing the
|reset_zoom_icon| button on the :ref:`ortho toolbar
<ortho_lightbox_views_ortho_toolbar>`, or selecting the *Settings*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment