API Change: Attach ImageViewer to Plugin after init.

Plugin is now added to the viewer using an inplace add on the viewer instead of on initialization of the plugin. This change means that operations requiring the viewer must be delayed until attach operation.
This commit is contained in:
Tony S Yu
2012-07-23 00:12:21 -04:00
parent 9d1df0c3ce
commit f47312a3d1
8 changed files with 61 additions and 44 deletions
+14 -11
View File
@@ -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)
+8 -5
View File
@@ -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()
+25 -22
View File
@@ -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)
+5 -2
View File
@@ -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
+3 -2
View File
@@ -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()
+4
View File
@@ -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()
+1 -1
View File
@@ -5,5 +5,5 @@ from skimage.viewer.plugins.canny import CannyPlugin
image = data.camera()
viewer = ImageViewer(image)
CannyPlugin(viewer)
viewer += CannyPlugin()
viewer.show()
+1 -1
View File
@@ -5,5 +5,5 @@ from skimage.viewer.plugins.lineprofile import LineProfile
image = data.camera()
viewer = ImageViewer(image)
LineProfile(viewer)
viewer += LineProfile()
viewer.show()