diff --git a/skimage/viewer/plugins/base.py b/skimage/viewer/plugins/base.py index 17387b8b..ba68ecb6 100644 --- a/skimage/viewer/plugins/base.py +++ b/skimage/viewer/plugins/base.py @@ -1,4 +1,5 @@ from PyQt4 import QtGui +from PyQt4.QtCore import Qt import matplotlib as mpl @@ -23,17 +24,13 @@ class Plugin(QtGui.QDialog): ---------- image_viewer : ImageViewer Window containing image used in measurement. - image : array - Image used in measurement/manipulation. """ name = 'Plugin' draws_on_image = False - def __init__(self, image_viewer, image_filter=None, height=100, width=400, - useblit=None): - self.image_viewer = image_viewer - QtGui.QDialog.__init__(self, image_viewer) - self.image_viewer.plugins.append(self) + def __init__(self, image_filter=None, height=100, width=400, useblit=None): + QtGui.QDialog.__init__(self) + self.image_viewer = None self.setWindowTitle(self.name) self.layout = QtGui.QGridLayout(self) @@ -42,18 +39,24 @@ class Plugin(QtGui.QDialog): if image_filter is not None: self.image_filter = image_filter - #TODO: Always passing image as first argument may be bad assumption. - self.arguments = [image_viewer.original_image] + self.arguments = [] self.keyword_arguments= {} - self.image = self.image_viewer.image - if useblit is None: useblit = True if mpl.backends.backend.endswith('Agg') else False self.useblit = useblit self.cids = [] self.artists = [] + def attach(self, image_viewer): + self.setParent(image_viewer) + self.setWindowFlags(Qt.Dialog) + + self.image_viewer = image_viewer + self.image_viewer.plugins.append(self) + #TODO: Always passing image as first argument may be bad assumption. + self.arguments.append(self.image_viewer.original_image) + if self.draws_on_image: self.connect_event('draw_event', self.on_draw) diff --git a/skimage/viewer/plugins/canny.py b/skimage/viewer/plugins/canny.py index 97465e6a..5ec6e415 100644 --- a/skimage/viewer/plugins/canny.py +++ b/skimage/viewer/plugins/canny.py @@ -8,15 +8,18 @@ class CannyPlugin(OverlayPlugin): name = 'Canny Filter' - def __init__(self, image_viewer, *args, **kwargs): - height = kwargs.get('height', 100) - width = kwargs.get('width', 400) - super(CannyPlugin, self).__init__(image_viewer, - width=width, height=height) + def __init__(self, *args, **kwargs): + kwargs.setdefault('height', 100) + kwargs.setdefault('width', 400) + super(CannyPlugin, self).__init__(**kwargs) + self.add_widget(Slider('sigma', 0, 5, update_on='release')) self.add_widget(Slider('low threshold', 0, 255, update_on='release')) self.add_widget(Slider('high threshold', 0, 255, update_on='release')) self.add_widget(ComboBox('color', self.color_names, ptype='plugin')) + + def attach(self, image_viewer): + super(CannyPlugin, self).attach(image_viewer) # Update image overlay to default slider values. self.filter_image() diff --git a/skimage/viewer/plugins/lineprofile.py b/skimage/viewer/plugins/lineprofile.py index 32ea967d..f41407b3 100644 --- a/skimage/viewer/plugins/lineprofile.py +++ b/skimage/viewer/plugins/lineprofile.py @@ -33,43 +33,46 @@ class LineProfile(PlotPlugin): name = 'Line Profile' draws_on_image = True - def __init__(self, image_viewer, useblit=None, - linewidth=1, epsilon=5, limits='image'): - super(LineProfile, self).__init__(image_viewer, height=200, width=600, + def __init__(self, useblit=None, linewidth=1, epsilon=5, limits='image'): + super(LineProfile, self).__init__(height=200, width=600, useblit=useblit) - self.linewidth = linewidth self.epsilon = epsilon + self._active_pt = None + self._limit_type = limits + self.line_kwargs = dict(color='y', lw=linewidth, alpha=0.5, marker='s', + markersize=5, solid_capstyle='butt') + print self.help() - if limits == 'image': - self.limits = (np.min(self.image), np.max(self.image)) - elif limits == 'dtype': - self.limits = dtype_range[self.image.dtype.type] - elif limits is None or len(limits) == 2: - self.limits = limits + def attach(self, image_viewer): + super(LineProfile, self).attach(image_viewer) + + image = image_viewer.original_image + + if self._limit_type == 'image': + self.limits = (np.min(image), np.max(image)) + elif self._limit_type == 'dtype': + self.self._limit_type = dtype_range[image.dtype.type] + elif self._limit_type is None or len(self._limit_type) == 2: + self.limits = self._limit_type else: - raise ValueError("Unrecognized `limits`: %s" % limits) + raise ValueError("Unrecognized `limits`: %s" % self._limit_type) - if not limits is None: + if not self._limit_type is None: self.ax.set_ylim(self.limits) - h, w = self.image.shape - + h, w = image.shape self._init_end_pts = np.array([[w/3, h/2], [2*w/3, h/2]]) self.end_pts = self._init_end_pts.copy() x, y = np.transpose(self.end_pts) - self.scan_line = self.image_viewer.ax.plot(x, y, 'y-s', markersize=5, - lw=linewidth, alpha=0.5, - solid_capstyle='butt')[0] + self.scan_line = image_viewer.ax.plot(x, y, **self.line_kwargs)[0] self.artists.append(self.scan_line) - scan_data = profile_line(self.image, self.end_pts) + scan_data = profile_line(image, self.end_pts) self.profile = self.ax.plot(scan_data, 'k-')[0] self._autoscale_view() - self._active_pt = None - self.connect_event('key_press_event', self.on_key_press) self.connect_event('button_press_event', self.on_mouse_press) self.connect_event('button_release_event', self.on_mouse_release) @@ -77,7 +80,6 @@ class LineProfile(PlotPlugin): self.connect_event('scroll_event', self.on_scroll) self.image_viewer.redraw() - print self.help() def help(self): helpstr = ("Line profile tool", @@ -169,7 +171,8 @@ class LineProfile(PlotPlugin): self.scan_line.set_data(np.transpose(self.end_pts)) self.scan_line.set_linewidth(self.linewidth) - scan = profile_line(self.image, self.end_pts, linewidth=self.linewidth) + scan = profile_line(self.image_viewer.original_image, self.end_pts, + linewidth=self.linewidth) self.profile.set_xdata(np.arange(scan.shape[0])) self.profile.set_ydata(scan) diff --git a/skimage/viewer/plugins/overlayplugin.py b/skimage/viewer/plugins/overlayplugin.py index e9a6a42a..3b051e1a 100644 --- a/skimage/viewer/plugins/overlayplugin.py +++ b/skimage/viewer/plugins/overlayplugin.py @@ -16,12 +16,15 @@ class OverlayPlugin(Plugin): 'green': (0, 1, 0), 'cyan': (0, 1, 1)} - def __init__(self, image_viewer, **kwargs): - Plugin.__init__(self, image_viewer, **kwargs) + def __init__(self, **kwargs): + super(OverlayPlugin, self).__init__(**kwargs) self._overlay_plot = None self._overlay = None self.cmap = None self.color_names = self.colors.keys() + + def attach(self, image_viewer): + super(OverlayPlugin, self).attach(image_viewer) #TODO: `color` doesn't update GUI widget when set manually. self.color = 0 diff --git a/skimage/viewer/plugins/plotplugin.py b/skimage/viewer/plugins/plotplugin.py index 38762dc4..66afa676 100644 --- a/skimage/viewer/plugins/plotplugin.py +++ b/skimage/viewer/plugins/plotplugin.py @@ -40,8 +40,9 @@ class PlotPlugin(Plugin): image : array Image used in measurement/manipulation. """ - def __init__(self, image_viewer, **kwargs): - Plugin.__init__(self, image_viewer, **kwargs) + + def attach(self, image_viewer): + super(PlotPlugin, self).attach(image_viewer) # Add plot for displaying intensity profile. self.add_plot() diff --git a/skimage/viewer/viewers/core.py b/skimage/viewer/viewers/core.py index ac004987..fe22d750 100644 --- a/skimage/viewer/viewers/core.py +++ b/skimage/viewer/viewers/core.py @@ -96,6 +96,10 @@ class ImageViewer(QtGui.QMainWindow): self.connect_event('motion_notify_event', self.update_status_bar) + def __iadd__(self, plugin): + plugin.attach(self) + return self + def closeEvent(self, ce): self.close() diff --git a/viewer_examples/plugins/canny.py b/viewer_examples/plugins/canny.py index e84a8270..eaa33330 100644 --- a/viewer_examples/plugins/canny.py +++ b/viewer_examples/plugins/canny.py @@ -5,5 +5,5 @@ from skimage.viewer.plugins.canny import CannyPlugin image = data.camera() viewer = ImageViewer(image) -CannyPlugin(viewer) +viewer += CannyPlugin() viewer.show() diff --git a/viewer_examples/plugins/lineprofile.py b/viewer_examples/plugins/lineprofile.py index 310c23e4..2f1b2cdc 100644 --- a/viewer_examples/plugins/lineprofile.py +++ b/viewer_examples/plugins/lineprofile.py @@ -5,5 +5,5 @@ from skimage.viewer.plugins.lineprofile import LineProfile image = data.camera() viewer = ImageViewer(image) -LineProfile(viewer) +viewer += LineProfile() viewer.show()