From 736de2c4032843279e61a5433ad37ab46a46c8d1 Mon Sep 17 00:00:00 2001 From: blink1073 Date: Wed, 16 Jul 2014 14:10:10 -0500 Subject: [PATCH 1/7] Rename module to be more explicit --- skimage/viewer/tests/{test_viewer.py => test_tools.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename skimage/viewer/tests/{test_viewer.py => test_tools.py} (100%) diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_tools.py similarity index 100% rename from skimage/viewer/tests/test_viewer.py rename to skimage/viewer/tests/test_tools.py From 9576df45f8695f9d4303d74654d80f8a14daf5b3 Mon Sep 17 00:00:00 2001 From: blink1073 Date: Wed, 16 Jul 2014 19:38:23 -0500 Subject: [PATCH 2/7] Add tests for all of viewer subpackage, with necessary file mods --- skimage/viewer/canvastools/base.py | 2 +- skimage/viewer/canvastools/linetool.py | 2 +- skimage/viewer/canvastools/painttool.py | 2 +- skimage/viewer/canvastools/recttool.py | 2 +- skimage/viewer/plugins/base.py | 3 +- skimage/viewer/tests/test_plugins.py | 179 ++++++++++++++++++ skimage/viewer/tests/test_tools.py | 234 ++++++++++++++++++++---- skimage/viewer/tests/test_utils.py | 36 ++++ skimage/viewer/tests/test_viewer.py | 77 ++++++++ skimage/viewer/tests/test_widgets.py | 105 +++++++++++ skimage/viewer/viewers/core.py | 10 +- skimage/viewer/widgets/history.py | 5 +- 12 files changed, 609 insertions(+), 48 deletions(-) create mode 100644 skimage/viewer/tests/test_plugins.py create mode 100644 skimage/viewer/tests/test_utils.py create mode 100644 skimage/viewer/tests/test_viewer.py create mode 100644 skimage/viewer/tests/test_widgets.py diff --git a/skimage/viewer/canvastools/base.py b/skimage/viewer/canvastools/base.py index 6fcda9c43a3..7f61ce2ca6d 100644 --- a/skimage/viewer/canvastools/base.py +++ b/skimage/viewer/canvastools/base.py @@ -115,7 +115,7 @@ def _on_key_press(self, event): @property def geometry(self): """Geometry information that gets passed to callback functions.""" - raise NotImplementedError + return None class ToolHandles(object): diff --git a/skimage/viewer/canvastools/linetool.py b/skimage/viewer/canvastools/linetool.py index c32d0ea7124..d777e50b38e 100644 --- a/skimage/viewer/canvastools/linetool.py +++ b/skimage/viewer/canvastools/linetool.py @@ -191,7 +191,7 @@ def _shrink_scan_line(self): self.callback_on_change(self.geometry) -if __name__ == '__main__': +if __name__ == '__main__': # pragma: no cover import matplotlib.pyplot as plt from skimage import data diff --git a/skimage/viewer/canvastools/painttool.py b/skimage/viewer/canvastools/painttool.py index 66cec08daf3..6af8b5d38a2 100644 --- a/skimage/viewer/canvastools/painttool.py +++ b/skimage/viewer/canvastools/painttool.py @@ -198,7 +198,7 @@ def at(self, row, col): return [slice(ymin, ymax), slice(xmin, xmax)] -if __name__ == '__main__': +if __name__ == '__main__': # pragma: no cover np.testing.rundocs() from skimage import data diff --git a/skimage/viewer/canvastools/recttool.py b/skimage/viewer/canvastools/recttool.py index d4ae113e255..f055e43949f 100644 --- a/skimage/viewer/canvastools/recttool.py +++ b/skimage/viewer/canvastools/recttool.py @@ -201,7 +201,7 @@ def geometry(self): return self.extents -if __name__ == '__main__': +if __name__ == '__main__': # pragma: no cover import matplotlib.pyplot as plt from skimage import data diff --git a/skimage/viewer/plugins/base.py b/skimage/viewer/plugins/base.py index baded1cba82..6b162fd8b22 100644 --- a/skimage/viewer/plugins/base.py +++ b/skimage/viewer/plugins/base.py @@ -239,7 +239,8 @@ def closeEvent(self, event): def clean_up(self): self.remove_image_artists() - self.image_viewer.plugins.remove(self) + if self in self.image_viewer.plugins: + self.image_viewer.plugins.remove(self) self.image_viewer.reset_image() self.image_viewer.redraw() diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py new file mode 100644 index 00000000000..3f5eb575990 --- /dev/null +++ b/skimage/viewer/tests/test_plugins.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +import numpy as np +import skimage +import skimage.data as data +from skimage.filter.rank import median +from skimage.morphology import disk +from skimage.viewer import ImageViewer +from skimage.viewer.qt import qt_api +from numpy.testing import assert_equal, assert_allclose, assert_almost_equal +from numpy.testing.decorators import skipif +from skimage.viewer.plugins import ( + LineProfile, Measure, CannyPlugin, LabelPainter, Crop, ColorHistogram, + PlotPlugin) +from skimage.viewer.plugins.base import Plugin +from skimage.viewer.widgets import Slider + + +def setup_line_profile(image, limits='image'): + viewer = ImageViewer(skimage.img_as_float(image)) + plugin = LineProfile(limits) + viewer += plugin + return plugin + + +@skipif(qt_api is None) +def test_line_profile(): + """ Test a line profile using an ndim=2 image""" + plugin = setup_line_profile(data.camera()) + line_image, scan_data = plugin.output() + for inp in [line_image.nonzero()[0].size, + line_image.sum() / line_image.max(), + scan_data.size]: + assert_equal(inp, 172) + assert_equal(line_image.shape, (512, 512)) + assert_allclose(scan_data.max(), 0.9139, rtol=1e-3) + assert_allclose(scan_data.mean(), 0.2828, rtol=1e-3) + + +@skipif(qt_api is None) +def test_line_profile_rgb(): + """ Test a line profile using an ndim=3 image""" + plugin = setup_line_profile(data.chelsea(), limits=None) + for i in range(6): + plugin.line_tool._thicken_scan_line() + line_image, scan_data = plugin.output() + assert_equal(line_image[line_image == 128].size, 755) + assert_equal(line_image[line_image == 255].size, 151) + assert_equal(line_image.shape, (300, 451)) + assert_equal(scan_data.shape, (152, 3)) + assert_allclose(scan_data.max(), 0.772, rtol=1e-3) + assert_allclose(scan_data.mean(), 0.4355, rtol=1e-3) + + +@skipif(qt_api is None) +def test_line_profile_dynamic(): + """Test a line profile updating after an image transform""" + image = data.coins()[:-50, :] # shave some off to make the line lower + image = skimage.img_as_float(image) + viewer = ImageViewer(image) + + lp = LineProfile(limits='dtype') + viewer += lp + + line = lp.get_profiles()[-1][0] + assert line.size == 129 + assert_almost_equal(np.std(image), 46.478, 3) + assert_almost_equal(np.std(line), 0.226, 3) + assert_almost_equal(np.max(line) - np.min(line), 0.725, 1) + + viewer.image = median(image) + + line = lp.get_profiles()[-1][0] + assert_almost_equal(np.std(image), 51.364, 3) + assert_almost_equal(np.std(line), 56.3555, 3) + assert_almost_equal(np.max(line) - np.min(line), 172.0, 1) + + +@skipif(qt_api is None) +def test_measure(): + image = data.camera() + viewer = ImageViewer(image) + m = Measure() + viewer += m + + m.line_changed([(0, 0), (10, 10)]) + assert_equal(str(m._length.text), '14.1') + assert_equal(str(m._angle.text[:5]), u'135.0') + + +@skipif(qt_api is None) +def test_canny(): + image = data.camera() + viewer = ImageViewer(image) + c = CannyPlugin() + viewer += c + + canny_edges = viewer.show(False) + viewer.close() + edges = canny_edges[0][0] + assert edges.sum() == 2852 + + +@skipif(qt_api is None) +def test_label_painter(): + image = data.camera() + moon = data.moon() + viewer = ImageViewer(image) + lp = LabelPainter() + viewer += lp + + assert_equal(lp.radius, 5) + lp.label = 1 + assert_equal(lp.label, '1') + lp.label = 2 + assert_equal(lp.label, '2') + assert_equal(lp.paint_tool.radius, 2) + lp._on_new_image(moon) + assert_equal(lp.paint_tool.shape, moon.shape) + + +@skipif(qt_api is None) +def test_crop(): + image = data.camera() + viewer = ImageViewer(image) + c = Crop() + viewer += c + + c.crop((0, 100, 0, 100)) + assert_equal(viewer.image.shape, (101, 101)) + + +@skipif(qt_api is None) +def test_color_histogram(): + image = skimage.img_as_float(data.load('color.png')) + viewer = ImageViewer(image) + ch = ColorHistogram(dock='right') + viewer += ch + + assert_almost_equal(viewer.image.std(), 0.352, 3), + ch.ab_selected((0, 100, 0, 100)), + assert_almost_equal(viewer.image.std(), 0.325, 3) + + +@skipif(qt_api is None) +def test_plot_plugin(): + viewer = ImageViewer(data.moon()) + plugin = PlotPlugin(image_filter=lambda x: x) + viewer += plugin + + assert_equal(viewer.image, data.moon()) + plugin._update_original_image(data.coins()) + assert_equal(viewer.image, data.coins()) + viewer.close() + + +@skipif(qt_api is None) +def test_plugin(): + img = skimage.img_as_float(data.moon()) + viewer = ImageViewer(img) + + def median_filter(img, radius=3): + return median(img, selem=disk(radius=radius)) + + plugin = Plugin(image_filter=median_filter) + viewer += plugin + + plugin += Slider('radius', 1, 5) + + assert_almost_equal(np.std(viewer.image), 12.556, 3) + + plugin.filter_image() + + assert_almost_equal(np.std(viewer.image), 12.931, 3) + + plugin.show() + plugin.close() + plugin.clean_up() + img, _ = plugin.output() + assert_equal(img, viewer.image) diff --git a/skimage/viewer/tests/test_tools.py b/skimage/viewer/tests/test_tools.py index 7fa4e374142..853dd3d8c8d 100644 --- a/skimage/viewer/tests/test_tools.py +++ b/skimage/viewer/tests/test_tools.py @@ -1,48 +1,208 @@ -import skimage -import skimage.data as data +from collections import namedtuple + +import numpy as np +from skimage import data from skimage.viewer import ImageViewer +from skimage.viewer.canvastools import ( + LineTool, ThickLineTool, RectangleTool, PaintTool) +from skimage.viewer.canvastools.base import CanvasToolBase from skimage.viewer.qt import qt_api -from numpy.testing import assert_equal, assert_allclose +from numpy.testing import assert_equal from numpy.testing.decorators import skipif -def setup_line_profile(image): - from skimage.viewer.plugins.lineprofile import LineProfile - viewer = ImageViewer(skimage.img_as_float(image)) - plugin = LineProfile() - viewer += plugin - return plugin +def get_end_points(image): + h, w = image.shape[0:2] + x = [w / 3, 2 * w / 3] + y = [h / 2] * 2 + return np.transpose([x, y]) + + +def create_mouse_event(ax, button=1, xdata=0, ydata=0, key=None): + """ + *name* + the event name + + *canvas* + the FigureCanvas instance generating the event + + *guiEvent* + the GUI event that triggered the matplotlib event + + *x* + x position - pixels from left of canvas + + *y* + y position - pixels from bottom of canvas + + *inaxes* + the :class:`~matplotlib.axes.Axes` instance if mouse is over axes + + *xdata* + x coord of mouse in data coords + + *ydata* + y coord of mouse in data coords + + *button* + button pressed None, 1, 2, 3, 'up', 'down' (up and down are used + for scroll events) + + *key* + the key depressed when the mouse event triggered (see + :class:`KeyEvent`) + + *step* + number of scroll steps (positive for 'up', negative for 'down') + """ + event = namedtuple('Event', + ('name canvas guiEvent x y inaxes xdata ydata ' + 'button key step')) + event.button = button + event.x, event.y = ax.transData.transform((xdata, ydata)) + event.xdata, event.ydata = xdata, ydata + event.inaxes = ax + event.canvas = ax.figure.canvas + event.key = key + event.step = 1 + event.guiEvent = None + event.name = 'Custom' + return event + + +@skipif(qt_api is None) +def test_line_tool(): + img = data.camera() + viewer = ImageViewer(img) + + tool = LineTool(viewer.ax, maxdist=10) + tool.end_points = get_end_points(img) + assert_equal(tool.end_points, np.array([[170, 256], [341, 256]])) + + # grab a handle and move it + grab = create_mouse_event(viewer.ax, xdata=170, ydata=256) + tool.on_mouse_press(grab) + move = create_mouse_event(viewer.ax, xdata=180, ydata=260) + tool.on_move(move) + tool.on_mouse_release(move) + assert_equal(tool.geometry, np.array([[180, 260], [341, 256]])) + + # create a new line + new = create_mouse_event(viewer.ax, xdata=10, ydata=10) + tool.on_mouse_press(new) + move = create_mouse_event(viewer.ax, xdata=100, ydata=100) + tool.on_move(move) + tool.on_mouse_release(move) + assert_equal(tool.geometry, np.array([[100, 100], [10, 10]])) + + +@skipif(qt_api is None) +def test_thick_line_tool(): + img = data.camera() + viewer = ImageViewer(img) + + tool = ThickLineTool(viewer.ax, maxdist=10) + tool.end_points = get_end_points(img) + + scroll_up = create_mouse_event(viewer.ax, button='up') + tool.on_scroll(scroll_up) + assert_equal(tool.linewidth, 2) + + scroll_down = create_mouse_event(viewer.ax, button='down') + tool.on_scroll(scroll_down) + assert_equal(tool.linewidth, 1) + + key_up = create_mouse_event(viewer.ax, key='+') + tool.on_key_press(key_up) + assert_equal(tool.linewidth, 2) + + key_down = create_mouse_event(viewer.ax, key='-') + tool.on_key_press(key_down) + assert_equal(tool.linewidth, 1) + + +@skipif(qt_api is None) +def test_rect_tool(): + img = data.camera() + viewer = ImageViewer(img) + + tool = RectangleTool(viewer.ax, maxdist=10) + tool.extents = (100, 150, 100, 150) + + assert_equal(tool.corners, + ((100, 150, 150, 100), (100, 100, 150, 150))) + assert_equal(tool.extents, (100, 150, 100, 150)) + assert_equal(tool.edge_centers, + ((100, 125.0, 150, 125.0), (125.0, 100, 125.0, 150))) + assert_equal(tool.geometry, (100, 150, 100, 150)) + + # grab a corner and move it + grab = create_mouse_event(viewer.ax, xdata=100, ydata=100) + tool.press(grab) + move = create_mouse_event(viewer.ax, xdata=120, ydata=120) + tool.onmove(move) + tool.release(move) + assert_equal(tool.geometry, [120, 150, 120, 150]) + + # create a new line + new = create_mouse_event(viewer.ax, xdata=10, ydata=10) + tool.press(new) + move = create_mouse_event(viewer.ax, xdata=100, ydata=100) + tool.onmove(move) + tool.release(move) + assert_equal(tool.geometry, [10, 100, 10, 100]) @skipif(qt_api is None) -def test_line_profile(): - """ Test a line profile using an ndim=2 image""" - plugin = setup_line_profile(data.camera()) - line_image, scan_data = plugin.output() - for inp in [line_image.nonzero()[0].size, - line_image.sum() / line_image.max(), - scan_data.size]: - assert_equal(inp, 172) - assert_equal(line_image.shape, (512, 512)) - assert_allclose(scan_data.max(), 0.9139, rtol=1e-3) - assert_allclose(scan_data.mean(), 0.2828, rtol=1e-3) +def test_paint_tool(): + img = data.moon() + viewer = ImageViewer(img) + + tool = PaintTool(viewer.ax, img.shape) + + tool.radius = 10 + assert_equal(tool.radius, 10) + tool.label = 2 + assert_equal(tool.label, 2) + assert_equal(tool.shape, img.shape) + + start = create_mouse_event(viewer.ax, xdata=100, ydata=100) + tool.on_mouse_press(start) + move = create_mouse_event(viewer.ax, xdata=110, ydata=110) + tool.on_move(move) + tool.on_mouse_release(move) + assert_equal(tool.overlay[tool.overlay == 2].size, 761) + + tool.label = 5 + start = create_mouse_event(viewer.ax, xdata=20, ydata=20) + tool.on_mouse_press(start) + move = create_mouse_event(viewer.ax, xdata=40, ydata=40) + tool.on_move(move) + tool.on_mouse_release(move) + assert_equal(tool.overlay[tool.overlay == 5].size, 881) + assert_equal(tool.overlay[tool.overlay == 2].size, 761) + + enter = create_mouse_event(viewer.ax, key='enter') + tool.on_mouse_press(enter) + + tool.overlay = tool.overlay * 0 + assert_equal(tool.overlay.sum(), 0) @skipif(qt_api is None) -def test_line_profile_rgb(): - """ Test a line profile using an ndim=3 image""" - plugin = setup_line_profile(data.chelsea()) - for i in range(6): - plugin.line_tool._thicken_scan_line() - line_image, scan_data = plugin.output() - assert_equal(line_image[line_image == 128].size, 755) - assert_equal(line_image[line_image == 255].size, 151) - assert_equal(line_image.shape, (300, 451)) - assert_equal(scan_data.shape, (152, 3)) - assert_allclose(scan_data.max(), 0.772, rtol=1e-3) - assert_allclose(scan_data.mean(), 0.4355, rtol=1e-3) - - -if __name__ == "__main__": - from numpy.testing import run_module_suite - run_module_suite() +def test_base_tool(): + img = data.moon() + viewer = ImageViewer(img) + + tool = CanvasToolBase(viewer.ax) + tool.set_visible(False) + tool.set_visible(True) + + enter = create_mouse_event(viewer.ax, key='enter') + tool._on_key_press(enter) + + tool.redraw() + tool.remove() + + tool = CanvasToolBase(viewer.ax, useblit=False) + tool.redraw() diff --git a/skimage/viewer/tests/test_utils.py b/skimage/viewer/tests/test_utils.py new file mode 100644 index 00000000000..b72d99abc39 --- /dev/null +++ b/skimage/viewer/tests/test_utils.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +from skimage.viewer.qt import qt_api, QtCore, QtGui +from numpy.testing.decorators import skipif +from skimage.viewer import utils +from skimage.viewer.utils import dialogs + + +@skipif(qt_api is None) +def test_event_loop(): + utils.init_qtapp() + timer = QtCore.QTimer() + timer.singleShot(10, QtGui.QApplication.quit) + utils.start_qtapp() + + +def test_format_filename(): + fname = dialogs._format_filename(('apple', 2)) + assert fname == 'apple' + fname = dialogs._format_filename('') + assert fname is None + + +def test_open_file_dialog(): + utils.init_qtapp() + timer = QtCore.QTimer() + timer.singleShot(10, QtGui.QApplication.quit) + filename = dialogs.open_file_dialog() + assert filename is None + + +def test_save_file_dialog(): + utils.init_qtapp() + timer = QtCore.QTimer() + timer.singleShot(10, QtGui.QApplication.quit) + filename = dialogs.save_file_dialog() + assert filename is None diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py new file mode 100644 index 00000000000..00ef848c895 --- /dev/null +++ b/skimage/viewer/tests/test_viewer.py @@ -0,0 +1,77 @@ + +from skimage import data +from skimage.viewer import ImageViewer, CollectionViewer +from skimage.transform import pyramid_gaussian +from skimage.viewer.plugins import OverlayPlugin +from skimage.filter import sobel +from skimage.viewer.qt import qt_api, QtGui, QtCore +from numpy.testing import assert_equal +from numpy.testing.decorators import skipif + + +@skipif(qt_api is None) +def test_viewer(): + lena = data.lena() + coins = data.coins() + + view = ImageViewer(lena) + import tempfile + _, filename = tempfile.mkstemp(suffix='.png') + + view.show(False) + view.close() + view.save_to_file(filename) + view.open_file(filename) + assert_equal(view.image, lena) + view.image = coins + assert_equal(view.image, coins), + view.save_to_file(filename), + view.open_file(filename), + view.reset_image(), + assert_equal(view.image, coins) + + +def make_key_event(key): + return QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, + QtCore.Qt.NoModifier) + + +@skipif(qt_api is None) +def test_collection_viewer(): + + img = data.lena() + img_collection = tuple(pyramid_gaussian(img)) + + view = CollectionViewer(img_collection) + make_key_event(48) + + view.update_index('', 2), + assert_equal(view.image, img_collection[2]) + view.keyPressEvent(make_key_event(53)) + assert_equal(view.image, img_collection[5]) + view._format_coord(10, 10) + + +@skipif(qt_api is None) +def test_viewer_with_overlay(): + img = data.coins() + ov = OverlayPlugin(image_filter=sobel) + viewer = ImageViewer(img) + viewer += ov + + import tempfile + _, filename = tempfile.mkstemp(suffix='.png') + + ov.color = 2 + assert_equal(ov.color, 'yellow') + viewer.save_to_file(filename) + ov.display_filtered_image(img) + assert_equal(ov.overlay, img) + ov.overlay = None + assert_equal(ov.overlay, None) + ov.overlay = img + assert_equal(ov.overlay, img) + assert_equal(ov.filtered_image, img) + + + diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py new file mode 100644 index 00000000000..a17465eecbe --- /dev/null +++ b/skimage/viewer/tests/test_widgets.py @@ -0,0 +1,105 @@ + +import os +from skimage import data, img_as_float, io +from skimage.viewer import ImageViewer +from skimage.viewer.widgets import ( + Slider, OKCancelButtons, SaveButtons, ComboBox, Text) +from skimage.viewer.plugins.base import Plugin + +from skimage.viewer.qt import qt_api, QtGui, QtCore +from numpy.testing import assert_almost_equal, assert_equal +from numpy.testing.decorators import skipif + + +def get_image_viewer(): + image = data.coins() + viewer = ImageViewer(img_as_float(image)) + viewer += Plugin() + return viewer + + +@skipif(qt_api is None) +def test_combo_box(): + viewer = get_image_viewer() + cb = ComboBox('hello', ('a', 'b', 'c')) + viewer.plugins[0] += cb + + assert_equal(cb.val, 'a') + assert_equal(cb.index, 0) + cb.index = 2 + assert_equal(cb.val, 'c'), + assert_equal(cb.index, 2) + + +@skipif(qt_api is None) +def test_text_widget(): + viewer = get_image_viewer() + txt = Text('hello', 'hello, world!') + viewer.plugins[0] += txt + + assert_equal(str(txt.text), 'hello, world!') + txt.text = 'goodbye, world!' + assert_equal(str(txt.text), 'goodbye, world!') + + +@skipif(qt_api is None) +def test_slider_int(): + viewer = get_image_viewer() + sld = Slider('radius', 2, 10, value_type='int') + viewer.plugins[0] += sld + + assert_equal(sld.val, 4) + sld.val = 6 + assert_equal(sld.val, 6) + sld.editbox.setText('5') + sld._on_editbox_changed() + assert_equal(sld.val, 5) + + +@skipif(qt_api is None) +def test_slider_float(): + viewer = get_image_viewer() + sld = Slider('alpha', 2.1, 3.1, value=2.1, value_type='float', + orientation='vertical', update_on='move') + viewer.plugins[0] += sld + + assert_equal(sld.val, 2.1) + sld.val = 2.5 + assert_almost_equal(sld.val, 2.5, 2) + sld.editbox.setText('0.1') + sld._on_editbox_changed() + assert_almost_equal(sld.val, 2.5, 2) + + +@skipif(qt_api is None) +def test_save_buttons(): + viewer = get_image_viewer() + sv = SaveButtons() + viewer.plugins[0] += sv + + import tempfile + _, filename = tempfile.mkstemp(suffix='.png') + os.remove(filename) + + timer = QtCore.QTimer() + timer.singleShot(100, lambda: QtGui.QApplication.quit()) + + sv.save_to_stack() + sv.save_to_file(filename) + + img = img_as_float(data.imread(filename)) + assert_almost_equal(img, viewer.image) + + img = io.pop() + assert_almost_equal(img, viewer.image) + + +@skipif(qt_api is None) +def test_ok_buttons(): + viewer = get_image_viewer() + ok = OKCancelButtons() + viewer.plugins[0] += ok + + ok.update_original_image(), + ok.close_plugin() + diff --git a/skimage/viewer/viewers/core.py b/skimage/viewer/viewers/core.py index 32c10cd4704..476017efd69 100644 --- a/skimage/viewer/viewers/core.py +++ b/skimage/viewer/viewers/core.py @@ -174,9 +174,10 @@ def _add_widget_size(self, widget, dimension='width'): h = viewer_size.height() self.resize(w + dx, h + dy) - def open_file(self): + def open_file(self, filename=None): """Open image file and display in viewer.""" - filename = dialogs.open_file_dialog() + if filename is None: + filename = dialogs.open_file_dialog() if filename is None: return image = io.imread(filename) @@ -187,7 +188,7 @@ def _update_original_image(self, image): self.image = image.copy() # update displayed image self.original_image_changed.emit(image) - def save_to_file(self): + def save_to_file(self, filename=None): """Save current image to file. The current behavior is not ideal: It saves the image displayed on @@ -195,7 +196,8 @@ def save_to_file(self): not preserved (resizing the viewer window will alter the size of the saved image). """ - filename = dialogs.save_file_dialog() + if filename is None: + filename = dialogs.save_file_dialog() if filename is None: return if len(self.ax.images) == 1: diff --git a/skimage/viewer/widgets/history.py b/skimage/viewer/widgets/history.py index ce20b559f41..d1df8689a78 100644 --- a/skimage/viewer/widgets/history.py +++ b/skimage/viewer/widgets/history.py @@ -81,8 +81,9 @@ def save_to_stack(self): NOTE: The io stack only works in interactive sessions.''') notify(msg) - def save_to_file(self): - filename = dialogs.save_file_dialog() + def save_to_file(self, filename=None): + if filename is None: + filename = dialogs.save_file_dialog() if filename is None: return image = self.plugin.filtered_image From 1a01f1a83b8e386276a53179b6e330cc74ea9061 Mon Sep 17 00:00:00 2001 From: blink1073 Date: Wed, 16 Jul 2014 19:58:13 -0500 Subject: [PATCH 3/7] Fix failing tests --- skimage/viewer/plugins/lineprofile.py | 22 ++++++++++++---------- skimage/viewer/tests/test_plugins.py | 19 ++++++++++--------- skimage/viewer/tests/test_widgets.py | 7 ++++--- skimage/viewer/widgets/core.py | 2 +- 4 files changed, 27 insertions(+), 23 deletions(-) diff --git a/skimage/viewer/plugins/lineprofile.py b/skimage/viewer/plugins/lineprofile.py index d0011c75cda..6e5b2c1f41e 100644 --- a/skimage/viewer/plugins/lineprofile.py +++ b/skimage/viewer/plugins/lineprofile.py @@ -46,7 +46,7 @@ def attach(self, image_viewer): if self._limit_type == 'image': self.limits = (np.min(image), np.max(image)) elif self._limit_type == 'dtype': - self._limit_type = dtype_range[image.dtype.type] + self.limits = dtype_range[image.dtype.type] elif self._limit_type is None or len(self._limit_type) == 2: self.limits = self._limit_type else: @@ -91,6 +91,7 @@ def get_profiles(self): profile: list of 1d arrays Profile of intensity values. Length 1 (grayscale) or 3 (rgb). """ + self._update_data() profiles = [data.get_ydata() for data in self.profile] return self.line_tool.end_points, profiles @@ -103,8 +104,15 @@ def _autoscale_view(self): def line_changed(self, end_points): x, y = np.transpose(end_points) self.line_tool.end_points = end_points - scan = measure.profile_line(self.image_viewer.original_image, - *end_points[:, ::-1], + self._update_data() + self.ax.relim() + + self._autoscale_view() + self.redraw() + + def _update_data(self): + scan = measure.profile_line(self.image_viewer.image, + *self.line_tool.end_points[:, ::-1], linewidth=self.line_tool.linewidth) self.scan_data = scan if scan.ndim == 1: @@ -117,11 +125,6 @@ def line_changed(self, end_points): self.profile[i].set_xdata(np.arange(scan.shape[0])) self.profile[i].set_ydata(scan[:, i]) - self.ax.relim() - - self._autoscale_view() - self.redraw() - def reset_axes(self, scan_data): # Clear lines out for line in self.ax.lines: @@ -147,7 +150,7 @@ def output(self): The line scan values across the image. """ end_points = self.line_tool.end_points - line_image = np.zeros(self.image_viewer.original_image.shape[:2], + line_image = np.zeros(self.image_viewer.image.shape[:2], np.uint8) width = self.line_tool.linewidth if width > 1: @@ -162,4 +165,3 @@ def output(self): rr, cc = draw.line(y1, x1, y2, x2) line_image[rr, cc] = 255 return line_image, self.scan_data - diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py index 3f5eb575990..e8c1641669d 100644 --- a/skimage/viewer/tests/test_plugins.py +++ b/skimage/viewer/tests/test_plugins.py @@ -17,7 +17,7 @@ def setup_line_profile(image, limits='image'): viewer = ImageViewer(skimage.img_as_float(image)) - plugin = LineProfile(limits) + plugin = LineProfile(limits=limits) viewer += plugin return plugin @@ -63,16 +63,17 @@ def test_line_profile_dynamic(): line = lp.get_profiles()[-1][0] assert line.size == 129 - assert_almost_equal(np.std(image), 46.478, 3) + assert_almost_equal(np.std(viewer.image), 0.208, 3) assert_almost_equal(np.std(line), 0.226, 3) assert_almost_equal(np.max(line) - np.min(line), 0.725, 1) - viewer.image = median(image) + viewer.image = skimage.img_as_float(median(image, + selem=disk(radius=3))) line = lp.get_profiles()[-1][0] - assert_almost_equal(np.std(image), 51.364, 3) - assert_almost_equal(np.std(line), 56.3555, 3) - assert_almost_equal(np.max(line) - np.min(line), 172.0, 1) + assert_almost_equal(np.std(viewer.image), 0.198, 3) + assert_almost_equal(np.std(line), 0.220, 3) + assert_almost_equal(np.max(line) - np.min(line), 0.639, 1) @skipif(qt_api is None) @@ -110,10 +111,10 @@ def test_label_painter(): assert_equal(lp.radius, 5) lp.label = 1 - assert_equal(lp.label, '1') + assert_equal(str(lp.label), '1') lp.label = 2 - assert_equal(lp.label, '2') - assert_equal(lp.paint_tool.radius, 2) + assert_equal(str(lp.paint_tool.label), '2') + assert_equal(lp.paint_tool.radius, 5) lp._on_new_image(moon) assert_equal(lp.paint_tool.shape, moon.shape) diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index a17465eecbe..61450146639 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -4,6 +4,7 @@ from skimage.viewer import ImageViewer from skimage.viewer.widgets import ( Slider, OKCancelButtons, SaveButtons, ComboBox, Text) +from skimage.viewer.utils import init_qtapp from skimage.viewer.plugins.base import Plugin from skimage.viewer.qt import qt_api, QtGui, QtCore @@ -24,10 +25,10 @@ def test_combo_box(): cb = ComboBox('hello', ('a', 'b', 'c')) viewer.plugins[0] += cb - assert_equal(cb.val, 'a') + assert_equal(str(cb.val), 'a') assert_equal(cb.index, 0) cb.index = 2 - assert_equal(cb.val, 'c'), + assert_equal(str(cb.val), 'c'), assert_equal(cb.index, 2) @@ -102,4 +103,4 @@ def test_ok_buttons(): ok.update_original_image(), ok.close_plugin() - + diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index 2bbf53d28d0..74fe9de4316 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -244,7 +244,7 @@ def __init__(self, name, items, ptype='kwarg', callback=None): @property def val(self): - return self._combo_box.value() + return self._combo_box.currentText() @property def index(self): From 0b73d691440cf87e8633afb2861842f210d5429a Mon Sep 17 00:00:00 2001 From: blink1073 Date: Wed, 16 Jul 2014 20:39:37 -0500 Subject: [PATCH 4/7] Address travis failures --- skimage/viewer/canvastools/linetool.py | 2 +- skimage/viewer/tests/test_plugins.py | 14 +++++++------- skimage/viewer/tests/test_viewer.py | 6 +++--- skimage/viewer/tests/test_widgets.py | 1 - 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/skimage/viewer/canvastools/linetool.py b/skimage/viewer/canvastools/linetool.py index d777e50b38e..fed183833a8 100644 --- a/skimage/viewer/canvastools/linetool.py +++ b/skimage/viewer/canvastools/linetool.py @@ -69,7 +69,7 @@ def on_enter(pts): @property def end_points(self): - return self._end_pts + return self._end_pts.astype(int) @end_points.setter def end_points(self, pts): diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py index e8c1641669d..59b1f3e4ec1 100644 --- a/skimage/viewer/tests/test_plugins.py +++ b/skimage/viewer/tests/test_plugins.py @@ -32,8 +32,8 @@ def test_line_profile(): scan_data.size]: assert_equal(inp, 172) assert_equal(line_image.shape, (512, 512)) - assert_allclose(scan_data.max(), 0.9139, rtol=1e-3) - assert_allclose(scan_data.mean(), 0.2828, rtol=1e-3) + assert_allclose(scan_data.max(), 0.9176, rtol=1e-3) + assert_allclose(scan_data.mean(), 0.2812, rtol=1e-3) @skipif(qt_api is None) @@ -43,12 +43,12 @@ def test_line_profile_rgb(): for i in range(6): plugin.line_tool._thicken_scan_line() line_image, scan_data = plugin.output() - assert_equal(line_image[line_image == 128].size, 755) + assert_equal(line_image[line_image == 128].size, 750) assert_equal(line_image[line_image == 255].size, 151) assert_equal(line_image.shape, (300, 451)) - assert_equal(scan_data.shape, (152, 3)) + assert_equal(scan_data.shape, (151, 3)) assert_allclose(scan_data.max(), 0.772, rtol=1e-3) - assert_allclose(scan_data.mean(), 0.4355, rtol=1e-3) + assert_allclose(scan_data.mean(), 0.4359, rtol=1e-3) @skipif(qt_api is None) @@ -64,7 +64,7 @@ def test_line_profile_dynamic(): line = lp.get_profiles()[-1][0] assert line.size == 129 assert_almost_equal(np.std(viewer.image), 0.208, 3) - assert_almost_equal(np.std(line), 0.226, 3) + assert_almost_equal(np.std(line), 0.229, 3) assert_almost_equal(np.max(line) - np.min(line), 0.725, 1) viewer.image = skimage.img_as_float(median(image, @@ -85,7 +85,7 @@ def test_measure(): m.line_changed([(0, 0), (10, 10)]) assert_equal(str(m._length.text), '14.1') - assert_equal(str(m._angle.text[:5]), u'135.0') + assert_equal(str(m._angle.text[:5]), '135.0') @skipif(qt_api is None) diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py index 00ef848c895..75f7413c4c6 100644 --- a/skimage/viewer/tests/test_viewer.py +++ b/skimage/viewer/tests/test_viewer.py @@ -2,7 +2,7 @@ from skimage import data from skimage.viewer import ImageViewer, CollectionViewer from skimage.transform import pyramid_gaussian -from skimage.viewer.plugins import OverlayPlugin +from skimage.viewer.plugins import OverlayPlugin, recent_mpl_version from skimage.filter import sobel from skimage.viewer.qt import qt_api, QtGui, QtCore from numpy.testing import assert_equal @@ -52,7 +52,7 @@ def test_collection_viewer(): view._format_coord(10, 10) -@skipif(qt_api is None) +@skipif(qt_api is None or not recent_mpl_version()) def test_viewer_with_overlay(): img = data.coins() ov = OverlayPlugin(image_filter=sobel) @@ -74,4 +74,4 @@ def test_viewer_with_overlay(): assert_equal(ov.filtered_image, img) - + diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index 61450146639..54b9b7bb5ed 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -4,7 +4,6 @@ from skimage.viewer import ImageViewer from skimage.viewer.widgets import ( Slider, OKCancelButtons, SaveButtons, ComboBox, Text) -from skimage.viewer.utils import init_qtapp from skimage.viewer.plugins.base import Plugin from skimage.viewer.qt import qt_api, QtGui, QtCore From 97d920cc6b3102c3a7c6765568031957f4e1e7d7 Mon Sep 17 00:00:00 2001 From: blink1073 Date: Wed, 16 Jul 2014 21:04:13 -0500 Subject: [PATCH 5/7] Another travis fix --- skimage/viewer/tests/test_viewer.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py index 75f7413c4c6..f87e49b3dd0 100644 --- a/skimage/viewer/tests/test_viewer.py +++ b/skimage/viewer/tests/test_viewer.py @@ -2,7 +2,8 @@ from skimage import data from skimage.viewer import ImageViewer, CollectionViewer from skimage.transform import pyramid_gaussian -from skimage.viewer.plugins import OverlayPlugin, recent_mpl_version +from skimage.viewer.plugins import OverlayPlugin +from skimage.viewer.plugins.overlayplugin import recent_mpl_version from skimage.filter import sobel from skimage.viewer.qt import qt_api, QtGui, QtCore from numpy.testing import assert_equal From acbac35616779d6f625f7ed706d55a64b4c67b6c Mon Sep 17 00:00:00 2001 From: blink1073 Date: Thu, 17 Jul 2014 12:33:59 -0500 Subject: [PATCH 6/7] Skip tests if matplotlib is not present --- skimage/viewer/tests/test_plugins.py | 40 ++++++++++++++++------------ skimage/viewer/tests/test_tools.py | 26 +++++++++++------- skimage/viewer/tests/test_utils.py | 13 ++++++--- skimage/viewer/tests/test_viewer.py | 20 +++++++++----- skimage/viewer/tests/test_widgets.py | 29 +++++++++++--------- 5 files changed, 79 insertions(+), 49 deletions(-) diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py index 59b1f3e4ec1..2f4d5ef55c3 100644 --- a/skimage/viewer/tests/test_plugins.py +++ b/skimage/viewer/tests/test_plugins.py @@ -4,15 +4,21 @@ import skimage.data as data from skimage.filter.rank import median from skimage.morphology import disk -from skimage.viewer import ImageViewer -from skimage.viewer.qt import qt_api from numpy.testing import assert_equal, assert_allclose, assert_almost_equal from numpy.testing.decorators import skipif -from skimage.viewer.plugins import ( - LineProfile, Measure, CannyPlugin, LabelPainter, Crop, ColorHistogram, - PlotPlugin) -from skimage.viewer.plugins.base import Plugin -from skimage.viewer.widgets import Slider + +try: + from skimage.viewer.qt import qt_api + from skimage.viewer import ImageViewer + from skimage.viewer.plugins import ( + LineProfile, Measure, CannyPlugin, LabelPainter, Crop, ColorHistogram, + PlotPlugin) + from skimage.viewer.plugins.base import Plugin + from skimage.viewer.widgets import Slider +except ImportError: + skip_all = True +else: + skip_all = False def setup_line_profile(image, limits='image'): @@ -22,7 +28,7 @@ def setup_line_profile(image, limits='image'): return plugin -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_line_profile(): """ Test a line profile using an ndim=2 image""" plugin = setup_line_profile(data.camera()) @@ -36,7 +42,7 @@ def test_line_profile(): assert_allclose(scan_data.mean(), 0.2812, rtol=1e-3) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_line_profile_rgb(): """ Test a line profile using an ndim=3 image""" plugin = setup_line_profile(data.chelsea(), limits=None) @@ -51,7 +57,7 @@ def test_line_profile_rgb(): assert_allclose(scan_data.mean(), 0.4359, rtol=1e-3) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_line_profile_dynamic(): """Test a line profile updating after an image transform""" image = data.coins()[:-50, :] # shave some off to make the line lower @@ -76,7 +82,7 @@ def test_line_profile_dynamic(): assert_almost_equal(np.max(line) - np.min(line), 0.639, 1) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_measure(): image = data.camera() viewer = ImageViewer(image) @@ -88,7 +94,7 @@ def test_measure(): assert_equal(str(m._angle.text[:5]), '135.0') -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_canny(): image = data.camera() viewer = ImageViewer(image) @@ -101,7 +107,7 @@ def test_canny(): assert edges.sum() == 2852 -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_label_painter(): image = data.camera() moon = data.moon() @@ -119,7 +125,7 @@ def test_label_painter(): assert_equal(lp.paint_tool.shape, moon.shape) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_crop(): image = data.camera() viewer = ImageViewer(image) @@ -130,7 +136,7 @@ def test_crop(): assert_equal(viewer.image.shape, (101, 101)) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_color_histogram(): image = skimage.img_as_float(data.load('color.png')) viewer = ImageViewer(image) @@ -142,7 +148,7 @@ def test_color_histogram(): assert_almost_equal(viewer.image.std(), 0.325, 3) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_plot_plugin(): viewer = ImageViewer(data.moon()) plugin = PlotPlugin(image_filter=lambda x: x) @@ -154,7 +160,7 @@ def test_plot_plugin(): viewer.close() -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_plugin(): img = skimage.img_as_float(data.moon()) viewer = ImageViewer(img) diff --git a/skimage/viewer/tests/test_tools.py b/skimage/viewer/tests/test_tools.py index 853dd3d8c8d..8cffd323942 100644 --- a/skimage/viewer/tests/test_tools.py +++ b/skimage/viewer/tests/test_tools.py @@ -2,14 +2,20 @@ import numpy as np from skimage import data -from skimage.viewer import ImageViewer -from skimage.viewer.canvastools import ( - LineTool, ThickLineTool, RectangleTool, PaintTool) -from skimage.viewer.canvastools.base import CanvasToolBase -from skimage.viewer.qt import qt_api from numpy.testing import assert_equal from numpy.testing.decorators import skipif +try: + from skimage.viewer.qt import qt_api + from skimage.viewer import ImageViewer + from skimage.viewer.canvastools import ( + LineTool, ThickLineTool, RectangleTool, PaintTool) + from skimage.viewer.canvastools.base import CanvasToolBase +except ImportError: + skip_all = True +else: + skip_all = False + def get_end_points(image): h, w = image.shape[0:2] @@ -70,7 +76,7 @@ def create_mouse_event(ax, button=1, xdata=0, ydata=0, key=None): return event -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_line_tool(): img = data.camera() viewer = ImageViewer(img) @@ -96,7 +102,7 @@ def test_line_tool(): assert_equal(tool.geometry, np.array([[100, 100], [10, 10]])) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_thick_line_tool(): img = data.camera() viewer = ImageViewer(img) @@ -121,7 +127,7 @@ def test_thick_line_tool(): assert_equal(tool.linewidth, 1) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_rect_tool(): img = data.camera() viewer = ImageViewer(img) @@ -153,7 +159,7 @@ def test_rect_tool(): assert_equal(tool.geometry, [10, 100, 10, 100]) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_paint_tool(): img = data.moon() viewer = ImageViewer(img) @@ -189,7 +195,7 @@ def test_paint_tool(): assert_equal(tool.overlay.sum(), 0) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_base_tool(): img = data.moon() viewer = ImageViewer(img) diff --git a/skimage/viewer/tests/test_utils.py b/skimage/viewer/tests/test_utils.py index b72d99abc39..30d74a51047 100644 --- a/skimage/viewer/tests/test_utils.py +++ b/skimage/viewer/tests/test_utils.py @@ -1,8 +1,12 @@ # -*- coding: utf-8 -*- -from skimage.viewer.qt import qt_api, QtCore, QtGui from numpy.testing.decorators import skipif -from skimage.viewer import utils -from skimage.viewer.utils import dialogs + +try: + from skimage.viewer.qt import qt_api, QtCore, QtGui + from skimage.viewer import utils + from skimage.viewer.utils import dialogs +except ImportError: + qt_api = None @skipif(qt_api is None) @@ -13,6 +17,7 @@ def test_event_loop(): utils.start_qtapp() +@skipif(qt_api is None) def test_format_filename(): fname = dialogs._format_filename(('apple', 2)) assert fname == 'apple' @@ -20,6 +25,7 @@ def test_format_filename(): assert fname is None +@skipif(qt_api is None) def test_open_file_dialog(): utils.init_qtapp() timer = QtCore.QTimer() @@ -28,6 +34,7 @@ def test_open_file_dialog(): assert filename is None +@skipif(qt_api is None) def test_save_file_dialog(): utils.init_qtapp() timer = QtCore.QTimer() diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py index f87e49b3dd0..2a232b292c4 100644 --- a/skimage/viewer/tests/test_viewer.py +++ b/skimage/viewer/tests/test_viewer.py @@ -1,16 +1,22 @@ from skimage import data -from skimage.viewer import ImageViewer, CollectionViewer from skimage.transform import pyramid_gaussian -from skimage.viewer.plugins import OverlayPlugin -from skimage.viewer.plugins.overlayplugin import recent_mpl_version from skimage.filter import sobel -from skimage.viewer.qt import qt_api, QtGui, QtCore from numpy.testing import assert_equal from numpy.testing.decorators import skipif +try: + from skimage.viewer.qt import qt_api, QtGui, QtCore + from skimage.viewer.plugins import OverlayPlugin + from skimage.viewer.plugins.overlayplugin import recent_mpl_version + from skimage.viewer import ImageViewer, CollectionViewer +except ImportError: + skip_all = True +else: + skip_all = False -@skipif(qt_api is None) + +@skipif(skip_all or qt_api is None) def test_viewer(): lena = data.lena() coins = data.coins() @@ -37,7 +43,7 @@ def make_key_event(key): QtCore.Qt.NoModifier) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_collection_viewer(): img = data.lena() @@ -53,7 +59,7 @@ def test_collection_viewer(): view._format_coord(10, 10) -@skipif(qt_api is None or not recent_mpl_version()) +@skipif(skip_all or qt_api is None or not recent_mpl_version()) def test_viewer_with_overlay(): img = data.coins() ov = OverlayPlugin(image_filter=sobel) diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index 54b9b7bb5ed..3a29c4bacd2 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -1,15 +1,20 @@ import os from skimage import data, img_as_float, io -from skimage.viewer import ImageViewer -from skimage.viewer.widgets import ( - Slider, OKCancelButtons, SaveButtons, ComboBox, Text) -from skimage.viewer.plugins.base import Plugin - -from skimage.viewer.qt import qt_api, QtGui, QtCore from numpy.testing import assert_almost_equal, assert_equal from numpy.testing.decorators import skipif +try: + from skimage.viewer.qt import qt_api, QtGui, QtCore + from skimage.viewer import ImageViewer + from skimage.viewer.widgets import ( + Slider, OKCancelButtons, SaveButtons, ComboBox, Text) + from skimage.viewer.plugins.base import Plugin +except ImportError: + skip_all = True +else: + skip_all = False + def get_image_viewer(): image = data.coins() @@ -18,7 +23,7 @@ def get_image_viewer(): return viewer -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_combo_box(): viewer = get_image_viewer() cb = ComboBox('hello', ('a', 'b', 'c')) @@ -31,7 +36,7 @@ def test_combo_box(): assert_equal(cb.index, 2) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_text_widget(): viewer = get_image_viewer() txt = Text('hello', 'hello, world!') @@ -42,7 +47,7 @@ def test_text_widget(): assert_equal(str(txt.text), 'goodbye, world!') -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_slider_int(): viewer = get_image_viewer() sld = Slider('radius', 2, 10, value_type='int') @@ -56,7 +61,7 @@ def test_slider_int(): assert_equal(sld.val, 5) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_slider_float(): viewer = get_image_viewer() sld = Slider('alpha', 2.1, 3.1, value=2.1, value_type='float', @@ -71,7 +76,7 @@ def test_slider_float(): assert_almost_equal(sld.val, 2.5, 2) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_save_buttons(): viewer = get_image_viewer() sv = SaveButtons() @@ -94,7 +99,7 @@ def test_save_buttons(): assert_almost_equal(img, viewer.image) -@skipif(qt_api is None) +@skipif(skip_all or qt_api is None) def test_ok_buttons(): viewer = get_image_viewer() ok = OKCancelButtons() From 243d5505370d7405fa32a04bdac1a52cb689e678 Mon Sep 17 00:00:00 2001 From: blink1073 Date: Thu, 17 Jul 2014 19:52:45 -0500 Subject: [PATCH 7/7] Make skip condition cleaner --- skimage/viewer/tests/test_plugins.py | 25 ++++++++++++------------- skimage/viewer/tests/test_tools.py | 15 +++++++-------- skimage/viewer/tests/test_viewer.py | 11 +++++------ skimage/viewer/tests/test_widgets.py | 17 ++++++++--------- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/skimage/viewer/tests/test_plugins.py b/skimage/viewer/tests/test_plugins.py index 2f4d5ef55c3..7ef62730a58 100644 --- a/skimage/viewer/tests/test_plugins.py +++ b/skimage/viewer/tests/test_plugins.py @@ -15,10 +15,9 @@ PlotPlugin) from skimage.viewer.plugins.base import Plugin from skimage.viewer.widgets import Slider + viewer_available = not qt_api is None except ImportError: - skip_all = True -else: - skip_all = False + viewer_available = False def setup_line_profile(image, limits='image'): @@ -28,7 +27,7 @@ def setup_line_profile(image, limits='image'): return plugin -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_line_profile(): """ Test a line profile using an ndim=2 image""" plugin = setup_line_profile(data.camera()) @@ -42,7 +41,7 @@ def test_line_profile(): assert_allclose(scan_data.mean(), 0.2812, rtol=1e-3) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_line_profile_rgb(): """ Test a line profile using an ndim=3 image""" plugin = setup_line_profile(data.chelsea(), limits=None) @@ -57,7 +56,7 @@ def test_line_profile_rgb(): assert_allclose(scan_data.mean(), 0.4359, rtol=1e-3) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_line_profile_dynamic(): """Test a line profile updating after an image transform""" image = data.coins()[:-50, :] # shave some off to make the line lower @@ -82,7 +81,7 @@ def test_line_profile_dynamic(): assert_almost_equal(np.max(line) - np.min(line), 0.639, 1) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_measure(): image = data.camera() viewer = ImageViewer(image) @@ -94,7 +93,7 @@ def test_measure(): assert_equal(str(m._angle.text[:5]), '135.0') -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_canny(): image = data.camera() viewer = ImageViewer(image) @@ -107,7 +106,7 @@ def test_canny(): assert edges.sum() == 2852 -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_label_painter(): image = data.camera() moon = data.moon() @@ -125,7 +124,7 @@ def test_label_painter(): assert_equal(lp.paint_tool.shape, moon.shape) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_crop(): image = data.camera() viewer = ImageViewer(image) @@ -136,7 +135,7 @@ def test_crop(): assert_equal(viewer.image.shape, (101, 101)) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_color_histogram(): image = skimage.img_as_float(data.load('color.png')) viewer = ImageViewer(image) @@ -148,7 +147,7 @@ def test_color_histogram(): assert_almost_equal(viewer.image.std(), 0.325, 3) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_plot_plugin(): viewer = ImageViewer(data.moon()) plugin = PlotPlugin(image_filter=lambda x: x) @@ -160,7 +159,7 @@ def test_plot_plugin(): viewer.close() -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_plugin(): img = skimage.img_as_float(data.moon()) viewer = ImageViewer(img) diff --git a/skimage/viewer/tests/test_tools.py b/skimage/viewer/tests/test_tools.py index 8cffd323942..9f02e7625b0 100644 --- a/skimage/viewer/tests/test_tools.py +++ b/skimage/viewer/tests/test_tools.py @@ -11,10 +11,9 @@ from skimage.viewer.canvastools import ( LineTool, ThickLineTool, RectangleTool, PaintTool) from skimage.viewer.canvastools.base import CanvasToolBase + viewer_available = not qt_api is None except ImportError: - skip_all = True -else: - skip_all = False + viewer_available = False def get_end_points(image): @@ -76,7 +75,7 @@ def create_mouse_event(ax, button=1, xdata=0, ydata=0, key=None): return event -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_line_tool(): img = data.camera() viewer = ImageViewer(img) @@ -102,7 +101,7 @@ def test_line_tool(): assert_equal(tool.geometry, np.array([[100, 100], [10, 10]])) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_thick_line_tool(): img = data.camera() viewer = ImageViewer(img) @@ -127,7 +126,7 @@ def test_thick_line_tool(): assert_equal(tool.linewidth, 1) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_rect_tool(): img = data.camera() viewer = ImageViewer(img) @@ -159,7 +158,7 @@ def test_rect_tool(): assert_equal(tool.geometry, [10, 100, 10, 100]) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_paint_tool(): img = data.moon() viewer = ImageViewer(img) @@ -195,7 +194,7 @@ def test_paint_tool(): assert_equal(tool.overlay.sum(), 0) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_base_tool(): img = data.moon() viewer = ImageViewer(img) diff --git a/skimage/viewer/tests/test_viewer.py b/skimage/viewer/tests/test_viewer.py index 2a232b292c4..cd6c7acbcc1 100644 --- a/skimage/viewer/tests/test_viewer.py +++ b/skimage/viewer/tests/test_viewer.py @@ -10,13 +10,12 @@ from skimage.viewer.plugins import OverlayPlugin from skimage.viewer.plugins.overlayplugin import recent_mpl_version from skimage.viewer import ImageViewer, CollectionViewer + viewer_available = not qt_api is None except ImportError: - skip_all = True -else: - skip_all = False + viewer_available = False -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_viewer(): lena = data.lena() coins = data.coins() @@ -43,7 +42,7 @@ def make_key_event(key): QtCore.Qt.NoModifier) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_collection_viewer(): img = data.lena() @@ -59,7 +58,7 @@ def test_collection_viewer(): view._format_coord(10, 10) -@skipif(skip_all or qt_api is None or not recent_mpl_version()) +@skipif(not viewer_available or not recent_mpl_version()) def test_viewer_with_overlay(): img = data.coins() ov = OverlayPlugin(image_filter=sobel) diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index 3a29c4bacd2..aeb4ede2a04 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -10,10 +10,9 @@ from skimage.viewer.widgets import ( Slider, OKCancelButtons, SaveButtons, ComboBox, Text) from skimage.viewer.plugins.base import Plugin + viewer_available = not qt_api is None except ImportError: - skip_all = True -else: - skip_all = False + viewer_available = False def get_image_viewer(): @@ -23,7 +22,7 @@ def get_image_viewer(): return viewer -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_combo_box(): viewer = get_image_viewer() cb = ComboBox('hello', ('a', 'b', 'c')) @@ -36,7 +35,7 @@ def test_combo_box(): assert_equal(cb.index, 2) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_text_widget(): viewer = get_image_viewer() txt = Text('hello', 'hello, world!') @@ -47,7 +46,7 @@ def test_text_widget(): assert_equal(str(txt.text), 'goodbye, world!') -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_slider_int(): viewer = get_image_viewer() sld = Slider('radius', 2, 10, value_type='int') @@ -61,7 +60,7 @@ def test_slider_int(): assert_equal(sld.val, 5) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_slider_float(): viewer = get_image_viewer() sld = Slider('alpha', 2.1, 3.1, value=2.1, value_type='float', @@ -76,7 +75,7 @@ def test_slider_float(): assert_almost_equal(sld.val, 2.5, 2) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_save_buttons(): viewer = get_image_viewer() sv = SaveButtons() @@ -99,7 +98,7 @@ def test_save_buttons(): assert_almost_equal(img, viewer.image) -@skipif(skip_all or qt_api is None) +@skipif(not viewer_available) def test_ok_buttons(): viewer = get_image_viewer() ok = OKCancelButtons()