mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-11 19:19:59 +08:00
Merge pull request #1905 from stefanv/novice_undo
Add comparison and reset capability to novice module
This commit is contained in:
+22
-1
@@ -10,7 +10,8 @@ from ..exposure import is_low_contrast
|
||||
from .._shared.utils import all_warnings, warn
|
||||
|
||||
|
||||
__all__ = ['imread', 'imread_collection', 'imsave', 'imshow', 'show']
|
||||
__all__ = ['imread', 'imsave', 'imshow', 'show',
|
||||
'imread_collection', 'imshow_collection']
|
||||
|
||||
|
||||
def imread(fname, as_grey=False, plugin=None, flatten=None,
|
||||
@@ -155,6 +156,26 @@ def imshow(arr, plugin=None, **plugin_args):
|
||||
return call_plugin('imshow', arr, plugin=plugin, **plugin_args)
|
||||
|
||||
|
||||
def imshow_collection(ic, plugin=None, **plugin_args):
|
||||
"""Display a collection of images.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
ic : ImageCollection
|
||||
Collection to display.
|
||||
plugin : str
|
||||
Name of plugin to use. By default, the different plugins are
|
||||
tried until a suitable candidate is found.
|
||||
|
||||
Other parameters
|
||||
----------------
|
||||
plugin_args : keywords
|
||||
Passed to the given plugin.
|
||||
|
||||
"""
|
||||
return call_plugin('imshow_collection', ic, plugin=plugin, **plugin_args)
|
||||
|
||||
|
||||
def show():
|
||||
'''Display pending images.
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
[matplotlib]
|
||||
description = Display or save images using Matplotlib
|
||||
provides = imshow, imread, _app_show
|
||||
|
||||
provides = imshow, imread, imshow_collection, _app_show
|
||||
|
||||
@@ -147,6 +147,7 @@ def imshow(im, ax=None, show_cbar=None, **kwargs):
|
||||
if kwargs.get('cmap', None) == 'viridis':
|
||||
kwargs['cmap'] = viridis
|
||||
lo, hi, cmap = _get_display_range(im)
|
||||
|
||||
kwargs.setdefault('interpolation', 'nearest')
|
||||
kwargs.setdefault('cmap', cmap)
|
||||
kwargs.setdefault('vmin', lo)
|
||||
@@ -160,8 +161,20 @@ def imshow(im, ax=None, show_cbar=None, **kwargs):
|
||||
plt.colorbar(ax_im, cax=cax)
|
||||
ax.set_adjustable('box-forced')
|
||||
ax.get_figure().tight_layout()
|
||||
|
||||
return ax_im
|
||||
|
||||
|
||||
def imshow_collection(ic, *args, **kwargs):
|
||||
"""Display all images in the collection.
|
||||
|
||||
"""
|
||||
fig, axes = plt.subplots(1, len(ic))
|
||||
for n, image in enumerate(ic):
|
||||
kwargs['ax'] = axes[n]
|
||||
imshow(image, *args, **kwargs)
|
||||
|
||||
|
||||
imread = plt.imread
|
||||
show = plt.show
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[test]
|
||||
description = Test plugin
|
||||
provides = imsave, imshow, imread, imread_collection
|
||||
provides = imsave, imshow, imread, imread_collection, imshow_collection
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# This mock-up is called by ../tests/test_plugin.py
|
||||
# to verify the behaviour of the plugin infrastructure
|
||||
|
||||
from skimage.io import ImageCollection
|
||||
|
||||
|
||||
def imread(fname, dtype=None):
|
||||
assert fname == 'test.png'
|
||||
@@ -20,3 +22,8 @@ def imshow(arr, plugin_arg=None):
|
||||
def imread_collection(x, conserve_memory=True):
|
||||
assert conserve_memory == False
|
||||
assert x == '*.png'
|
||||
return ImageCollection([0, 1], load_func=lambda x: x)
|
||||
|
||||
|
||||
def imshow_collection(x):
|
||||
assert len(x) == 2
|
||||
|
||||
@@ -46,7 +46,8 @@ plugin_meta_data = {}
|
||||
preferred_plugins = {
|
||||
# Default plugins for all types (overridden by specific types below).
|
||||
'all': ['pil', 'matplotlib', 'qt', 'freeimage'],
|
||||
'imshow': ['matplotlib']
|
||||
'imshow': ['matplotlib'],
|
||||
'imshow_collection': ['matplotlib']
|
||||
}
|
||||
|
||||
|
||||
@@ -59,13 +60,15 @@ def _clear_plugins():
|
||||
'imsave': [],
|
||||
'imshow': [],
|
||||
'imread_collection': [],
|
||||
'imshow_collection': [],
|
||||
'_app_show': []}
|
||||
_clear_plugins()
|
||||
|
||||
|
||||
def _load_preferred_plugins():
|
||||
# Load preferred plugin for each io function.
|
||||
io_types = ['imsave', 'imshow', 'imread_collection', 'imread']
|
||||
io_types = ['imsave', 'imshow', 'imread_collection', 'imshow_collection',
|
||||
'imread']
|
||||
for p_type in io_types:
|
||||
_set_plugin(p_type, preferred_plugins['all'])
|
||||
|
||||
@@ -190,8 +193,8 @@ def call_plugin(kind, *args, **kwargs):
|
||||
if len(plugin_funcs) == 0:
|
||||
msg = ("No suitable plugin registered for %s.\n\n"
|
||||
"You may load I/O plugins with the `skimage.io.use_plugin` "
|
||||
"command. A list of all available plugins can be found using "
|
||||
"`skimage.io.plugins()`.")
|
||||
"command. A list of all available plugins are shown in the "
|
||||
"`skimage.io` docstring.")
|
||||
raise RuntimeError(msg % kind)
|
||||
|
||||
plugin = kwargs.pop('plugin', None)
|
||||
@@ -216,7 +219,7 @@ def use_plugin(name, kind=None):
|
||||
----------
|
||||
name : str
|
||||
Name of plugin.
|
||||
kind : {'imsave', 'imread', 'imshow', 'imread_collection'}, optional
|
||||
kind : {'imsave', 'imread', 'imshow', 'imread_collection', 'imshow_collection'}, optional
|
||||
Set the plugin for this function. By default,
|
||||
the plugin is set for all functions.
|
||||
|
||||
|
||||
@@ -41,7 +41,8 @@ def test_show():
|
||||
|
||||
|
||||
def test_collection():
|
||||
io.imread_collection('*.png', conserve_memory=False, plugin='test')
|
||||
ic = io.imread_collection('*.png', conserve_memory=False, plugin='test')
|
||||
io.imshow_collection(ic)
|
||||
|
||||
|
||||
def test_use():
|
||||
|
||||
@@ -56,9 +56,9 @@ Changing `size` resizes the picture.
|
||||
|
||||
>>> picture.size = (45, 30)
|
||||
|
||||
We can preview the changes we made to the picture with our earlier command:
|
||||
We can preview the changes we made to the picture with the ``compare`` command:
|
||||
|
||||
>>> picture.show() # doctest: +SKIP
|
||||
>>> picture.compare() # doctest: +SKIP
|
||||
|
||||
You can iterate over pixels, which have RGB values between 0 and 255,
|
||||
and know their location in the picture.
|
||||
@@ -88,6 +88,13 @@ True
|
||||
>>> picture.modified
|
||||
False
|
||||
|
||||
An image can also be restored to its original state after modification:
|
||||
|
||||
>>> picture[0:20, 0:20] = (0, 0, 0)
|
||||
>>> picture.compare() # doctest: +SKIP
|
||||
>>> picture.reset()
|
||||
>>> picture.compare() # doctest: +SKIP
|
||||
|
||||
"""
|
||||
from ._novice import Picture, open, colors, color_dict
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ from .. import io, img_as_ubyte
|
||||
from ..transform import resize
|
||||
from ..color import color_dict
|
||||
from ..io.util import file_or_url_context, is_url
|
||||
from ..io.collection import ImageCollection
|
||||
|
||||
import six
|
||||
from six.moves.urllib import request
|
||||
@@ -303,8 +304,9 @@ class Picture(object):
|
||||
|
||||
@array.setter
|
||||
def array(self, array):
|
||||
self._array = array
|
||||
self._xy_array = array_to_xy_origin(array)
|
||||
self._array = array.astype(np.uint8)
|
||||
self._xy_array = array_to_xy_origin(self._array)
|
||||
self._array_backup = self._array.copy()
|
||||
|
||||
@property
|
||||
def xy_array(self):
|
||||
@@ -329,6 +331,12 @@ class Picture(object):
|
||||
self._path = os.path.abspath(path)
|
||||
self._format = imghdr.what(path)
|
||||
|
||||
def reset(self):
|
||||
"""Reset image to its original state, removing modifications.
|
||||
|
||||
"""
|
||||
self.array = self._array_backup
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
"""The path to the picture."""
|
||||
@@ -388,6 +396,13 @@ class Picture(object):
|
||||
io.imshow(self.array)
|
||||
io.show()
|
||||
|
||||
def compare(self):
|
||||
"""Compare the image to its unmodified version."""
|
||||
images = [self._array_backup, self.array]
|
||||
ic = ImageCollection([0, 1], load_func=lambda x: images[x])
|
||||
io.imshow_collection(images)
|
||||
io.show()
|
||||
|
||||
def _makepixel(self, x, y):
|
||||
"""Create a Pixel object for a given x, y location."""
|
||||
rgb = self.xy_array[x, y]
|
||||
|
||||
@@ -2,6 +2,7 @@ import os
|
||||
import tempfile
|
||||
|
||||
import numpy as np
|
||||
from nose.tools import assert_true
|
||||
from numpy.testing import assert_equal, raises, assert_allclose
|
||||
from skimage import novice
|
||||
from skimage.novice._novice import (array_to_xy_origin, xy_to_array_origin,
|
||||
@@ -135,8 +136,18 @@ def test_modified_on_set_pixel():
|
||||
assert pic.modified
|
||||
|
||||
|
||||
def test_reset():
|
||||
pic = novice.Picture(SMALL_IMAGE_PATH)
|
||||
v = pic[0, 0]
|
||||
pic[0, 0] = (1, 1, 1)
|
||||
pic.reset()
|
||||
assert_true(pic[0, 0] == v)
|
||||
|
||||
|
||||
def test_update_on_save():
|
||||
pic = novice.Picture(array=np.zeros((3, 3, 3)))
|
||||
pic[0, 0] = (255, 255, 255) # prevent attempting to save low-contrast image
|
||||
|
||||
with all_warnings(): # precision loss
|
||||
pic.size = (6, 6)
|
||||
assert pic.modified
|
||||
|
||||
Reference in New Issue
Block a user