diff --git a/skimage/viewer/plugins/measure.py b/skimage/viewer/plugins/measure.py new file mode 100644 index 00000000..49f53963 --- /dev/null +++ b/skimage/viewer/plugins/measure.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +import numpy as np + +from .base import Plugin +from ..widgets import Text +from ..canvastools import LineTool + + +__all__ = ['Measure'] + + +rad2deg = 180 / np.pi + + +class Measure(Plugin): + name = 'Measure' + draws_on_image = True + + def __init__(self, maxdist=10, **kwargs): + super(Measure, self).__init__(**kwargs) + + self.maxdist = maxdist + self._length = Text('Length:') + self._angle = Text('Angle:') + + self.add_widget(self._length) + self.add_widget(self._angle) + + print self.help() + + def attach(self, image_viewer): + super(Measure, self).attach(image_viewer) + + image = image_viewer.original_image + h, w = image.shape + x = [w / 3, 2 * w / 3] + y = [h / 2] * 2 + self.line_tool = LineTool(self.image_viewer.ax, x, y, + maxdist=self.maxdist, + on_update=self.line_changed) + # initialize displayed values + self.line_changed(np.transpose((x, y))) + + def help(self): + helpstr = ("Line profile tool", + "Select line to measure distance and angle.") + return '\n'.join(helpstr) + + def line_changed(self, end_pts): + x, y = np.transpose(end_pts) + dx = np.diff(x)[0] + dy = np.diff(y)[0] + self._length.text = '%.1f' % np.hypot(dx, dy) + self._angle.text = u'%.1f°' % (180 - np.arctan2(dy, dx) * rad2deg) diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index f6e591a1..bdbfb71e 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -27,7 +27,7 @@ except ImportError: from ..utils import RequiredAttr -__all__ = ['BaseWidget', 'Slider', 'ComboBox'] +__all__ = ['BaseWidget', 'Slider', 'ComboBox', 'Text'] class BaseWidget(QWidget): @@ -50,6 +50,29 @@ class BaseWidget(QWidget): self.callback(self.name, value) +class Text(BaseWidget): + + def __init__(self, name=None, text=''): + super(Text, self).__init__(name) + self._label = QtGui.QLabel() + self.text = text + self.layout = QtGui.QHBoxLayout(self) + if name is not None: + name_label = QtGui.QLabel() + name_label.setText(name) + self.layout.addWidget(name_label) + self.layout.addWidget(self._label) + + + @property + def text(self): + return self._label.text() + + @text.setter + def text(self, text_str): + self._label.setText(text_str) + + class Slider(BaseWidget): """Slider widget for adjusting numeric parameters.