From 48ac757ab8303709cdeebb7903440f564664bd60 Mon Sep 17 00:00:00 2001 From: Tony S Yu Date: Sat, 21 Jul 2012 20:29:43 -0500 Subject: [PATCH] Refactor image overlays to special plugin base class. --- skimage/viewer/plugins/base.py | 53 ++++++++++++++++++++++++++------- skimage/viewer/plugins/canny.py | 8 ++--- skimage/viewer/viewers/core.py | 25 +--------------- 3 files changed, 47 insertions(+), 39 deletions(-) diff --git a/skimage/viewer/plugins/base.py b/skimage/viewer/plugins/base.py index 1757f257..eb138295 100644 --- a/skimage/viewer/plugins/base.py +++ b/skimage/viewer/plugins/base.py @@ -6,6 +6,8 @@ import matplotlib.pyplot as plt from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg from skimage.io._plugins.q_color_mixer import IntelligentSlider +from skimage.viewer.utils import clear_red + class PlotCanvas(FigureCanvasQTAgg): """Canvas for displaying images. @@ -33,6 +35,11 @@ class Plugin(QtGui.QDialog): ---------- image_viewer : ImageViewer instance. Window containing image used in measurement/manipulation. + callback : function + Function that gets called to update ImageViewer. Alternatively, this + can also be defined as a method in a Plugin subclass. + height, width : int + Size of plugin window in pixels. useblit : bool If True, use blitting to speed up animation. Only available on some backends. If None, set to True when using Agg backend, otherwise False. @@ -43,8 +50,6 @@ class Plugin(QtGui.QDialog): Window containing image used in measurement. image : array Image used in measurement/manipulation. - overlay : array - Image used in measurement/manipulation. """ name = 'Plugin' draws_on_image = False @@ -65,7 +70,6 @@ class Plugin(QtGui.QDialog): self.arguments = [image_viewer.original_image] self.keyword_arguments= {} - self.overlay = self.image_viewer.overlay self.image = self.image_viewer.image if useblit is None: @@ -152,11 +156,6 @@ class PlotPlugin(Plugin): ---------- image_viewer : ImageViewer instance. Window containing image used in measurement/manipulation. - figure : :class:`~matplotlib.figure.Figure` - If None, create a figure with a single axes. - useblit : bool - If True, use blitting to speed up animation. Only available on some - backends. If None, set to True when using Agg backend, otherwise False. Attributes ---------- @@ -164,10 +163,8 @@ class PlotPlugin(Plugin): Window containing image used in measurement. image : array Image used in measurement/manipulation. - overlay : array - Image used in measurement/manipulation. """ - def __init__(self, image_viewer, useblit=None, **kwargs): + def __init__(self, image_viewer, **kwargs): Plugin.__init__(self, image_viewer, **kwargs) # Add plot for displaying intensity profile. self.add_plot() @@ -188,3 +185,37 @@ class PlotPlugin(Plugin): self.fig.patch.set_facecolor(bgcolor) self.ax = self.canvas.ax self.layout.addWidget(self.canvas, self.row, 0) + + +class OverlayPlugin(Plugin): + """Plugin for ImageViewer that displays an overlay on top of main image. + + Attributes + ---------- + overlay : array + Overlay displayed on top of image. This overlay defaults to a color map + with alpha values varying linearly from 0 to 1. + """ + + def __init__(self, image_viewer, **kwargs): + Plugin.__init__(self, image_viewer, **kwargs) + self.overlay_cmap = clear_red + self._overlay_plot = None + self._overlay = None + + @property + def overlay(self): + return self._overlay + + @overlay.setter + def overlay(self, image): + self._overlay = image + ax = self.image_viewer.ax + if image is None: + ax.images.remove(self._overlay_plot) + self._overlay_plot = None + elif self._overlay_plot is None: + self._overlay_plot = ax.imshow(image, cmap=self.overlay_cmap) + else: + self._overlay_plot.set_array(image) + self.image_viewer.redraw() diff --git a/skimage/viewer/plugins/canny.py b/skimage/viewer/plugins/canny.py index cf3b5253..feeaee0d 100644 --- a/skimage/viewer/plugins/canny.py +++ b/skimage/viewer/plugins/canny.py @@ -1,8 +1,8 @@ -from .base import Plugin +from .base import OverlayPlugin from skimage.filter import canny -class CannyPlugin(Plugin): +class CannyPlugin(OverlayPlugin): name = 'Canny Filter' @@ -22,8 +22,8 @@ class CannyPlugin(Plugin): def callback(self, *args, **kwargs): image = canny(*args, **kwargs) - self.image_viewer.overlay = image + self.overlay = image def closeEvent(self, event): - self.image_viewer.overlay = None + self.overlay = None super(CannyPlugin, self).closeEvent(event) diff --git a/skimage/viewer/viewers/core.py b/skimage/viewer/viewers/core.py index 1f77915d..b6c1db69 100644 --- a/skimage/viewer/viewers/core.py +++ b/skimage/viewer/viewers/core.py @@ -3,7 +3,7 @@ import sys from PyQt4 import QtGui, QtCore from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg -from skimage.viewer.utils import figimage, clear_red +from skimage.viewer.utils import figimage qApp = None @@ -46,9 +46,6 @@ class ImageViewer(QtGui.QMainWindow): Image being viewed. Setting this value will update the displayed frame. original_image : array Plugins typically operate on (but don't change) the original image. - overlay : array - Overlay displayed on top of image. This overlay defaults to a color map - with alpha values varying linearly from 0 to 1. plugins : list List of attached plugins. """ @@ -61,8 +58,6 @@ class ImageViewer(QtGui.QMainWindow): #TODO: Add ImageViewer to skimage.io window manager - self.overlay_cmap = clear_red - self.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.setWindowTitle("Image Viewer") @@ -80,8 +75,6 @@ class ImageViewer(QtGui.QMainWindow): self.ax.autoscale(enable=False) self._image_plot = self.ax.images[0] - self._overlay_plot = None - self._overlay = None self.original_image = image self.image = image @@ -127,22 +120,6 @@ class ImageViewer(QtGui.QMainWindow): self._image_plot.set_array(image) self.redraw() - @property - def overlay(self): - return self._overlay - - @overlay.setter - def overlay(self, image): - self._overlay = image - if image is None: - self.ax.images.remove(self._overlay_plot) - self._overlay_plot = None - elif self._overlay_plot is None: - self._overlay_plot = self.ax.imshow(image, cmap=self.overlay_cmap) - else: - self._overlay_plot.set_array(image) - self.canvas.draw_idle() - def connect_event(self, event, callback): """Connect callback function to matplotlib event and return id.""" cid = self.canvas.mpl_connect(event, callback)