mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-04 15:06:00 +08:00
Revert previous 3 commits to test Travis CI failures.
This commit is contained in:
+9
-1
@@ -1,3 +1,4 @@
|
||||
import os
|
||||
from io import BytesIO
|
||||
|
||||
import numpy as np
|
||||
@@ -94,7 +95,14 @@ def imread(fname, as_grey=False, plugin=None, flatten=None,
|
||||
as_grey = flatten
|
||||
|
||||
with file_or_url_context(fname) as fname:
|
||||
img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
|
||||
function = 'imread'
|
||||
# TODO: This should probably use imghdr to get the image format.
|
||||
try:
|
||||
_, extension = os.path.splitext(fname)
|
||||
function = function + extension.lower()
|
||||
except AttributeError: # Buffers don't work with splitext
|
||||
pass
|
||||
img = call_plugin(function, fname, plugin=plugin, **plugin_args)
|
||||
|
||||
if as_grey and getattr(img, 'ndim', 0) >= 3:
|
||||
img = rgb2grey(img)
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
class InheritedConfig(dict):
|
||||
"""Configuration dictionary where non-existent keys can inherit values.
|
||||
|
||||
This class allows you to define parameter names that can match exactly, but
|
||||
if it doesn't, parameter names will be searched based on key inheritance.
|
||||
For example, the key 'size.text' will default to 'size'.
|
||||
|
||||
Note that indexing into the dictionary will raise an error if it doesn't
|
||||
match exactly, while `InheritedConfig.get` will look up values based on
|
||||
inheritance.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
config_values : dict or list of (key, value) pairs
|
||||
Default values for a configuration, where keys are the parameter names
|
||||
and values are the associated value.
|
||||
cascade_map : dict
|
||||
Dictionary defining cascading defaults. If a parameter name is not
|
||||
found, indexing `cascade_map` with the parameter name will return
|
||||
the parameter to look for.
|
||||
kwargs : dict
|
||||
Keyword arguments for initializing dict.
|
||||
"""
|
||||
|
||||
_separator = '.'
|
||||
|
||||
def __init__(self, config_values=None, **kwargs):
|
||||
assert 'config_values' not in kwargs
|
||||
|
||||
if config_values is None:
|
||||
config_values = {}
|
||||
|
||||
super(InheritedConfig, self).__init__(config_values, **kwargs)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.get(key, _raise=True)
|
||||
|
||||
def get(self, key, default=None, _raise=False):
|
||||
"""Return best matching config value for `key`.
|
||||
|
||||
Get value from configuration. The search for `key` is in the following
|
||||
order:
|
||||
|
||||
- `self` (Value in global configuration)
|
||||
- `default`
|
||||
- Alternate key specified by `self.cascade_map`
|
||||
|
||||
This method supports the pattern commonly used for optional keyword
|
||||
arguments to a function. For example::
|
||||
|
||||
>>> def print_value(key, **kwargs):
|
||||
... print kwargs.get(key, 0)
|
||||
>>> print_value('size')
|
||||
0
|
||||
>>> print_value('size', size=1)
|
||||
1
|
||||
|
||||
Instead, you would create a config class and write::
|
||||
|
||||
>>> config = InheritedConfig(size=0)
|
||||
>>> def print_value(key, **kwargs):
|
||||
... print kwargs.get(key, config.get(key))
|
||||
>>> print_value('size')
|
||||
0
|
||||
>>> print_value('size', size=1)
|
||||
1
|
||||
>>> print_value('non-existent')
|
||||
None
|
||||
>>> print_value('size.text')
|
||||
0
|
||||
|
||||
See examples below for a demonstration of the cascading of
|
||||
configuration names.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
key : str
|
||||
Name of config value you want.
|
||||
default : object
|
||||
Default value if `key` doesn't exist in instance.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> config = InheritedConfig(size=0)
|
||||
>>> config.get('size')
|
||||
0
|
||||
>>> top_choice={'size': 1}
|
||||
>>> top_choice.get('size', config.get('size'))
|
||||
1
|
||||
>>> config.get('non-existent', 'unknown')
|
||||
'unknown'
|
||||
>>> config.get('size.text')
|
||||
0
|
||||
>>> config.get('size.text', 2)
|
||||
2
|
||||
>>> top_choice.get('size', config.get('size.text'))
|
||||
1
|
||||
"""
|
||||
if key in self.keys():
|
||||
return super(InheritedConfig, self).__getitem__(key)
|
||||
elif default is not None:
|
||||
return default
|
||||
elif self._separator in key:
|
||||
return self.get(self._parent(key))
|
||||
elif _raise:
|
||||
raise KeyError('%r not in %s' % (key, self.__class__.__name__))
|
||||
else:
|
||||
return None
|
||||
|
||||
def _parent(self, key):
|
||||
"""Return parent key."""
|
||||
parts = key.split(self._separator)
|
||||
return self._separator.join(parts[:-1])
|
||||
|
||||
def __contains__(self, key):
|
||||
if key in self.keys():
|
||||
return True
|
||||
elif self._separator in key:
|
||||
return self.__contains__(self._parent(key))
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
|
||||
doctest.testmod()
|
||||
@@ -10,6 +10,8 @@ except ImportError:
|
||||
import os.path
|
||||
from glob import glob
|
||||
|
||||
from skimage.io.inherited_config import InheritedConfig
|
||||
|
||||
|
||||
__all__ = ['use_plugin', 'call_plugin', 'plugin_info', 'plugin_order',
|
||||
'reset_plugins', 'find_available_plugins', 'available_plugins']
|
||||
@@ -29,6 +31,7 @@ preferred_plugins = {
|
||||
# Use PIL as the default imread plugin, since matplotlib (1.2.x)
|
||||
# is buggy (flips PNGs around, returns bytes as floats, etc.)
|
||||
'imread': ['pil'],
|
||||
'imread.tiff': ['tifffile'],
|
||||
}
|
||||
|
||||
|
||||
@@ -37,11 +40,11 @@ def _clear_plugins():
|
||||
|
||||
"""
|
||||
global plugin_store
|
||||
plugin_store = {'imread': [],
|
||||
'imsave': [],
|
||||
'imshow': [],
|
||||
'imread_collection': [],
|
||||
'_app_show': []}
|
||||
plugin_store = InheritedConfig({'imread': [],
|
||||
'imsave': [],
|
||||
'imshow': [],
|
||||
'imread_collection': [],
|
||||
'_app_show': []})
|
||||
_clear_plugins()
|
||||
|
||||
|
||||
@@ -197,19 +200,15 @@ def use_plugin(name, kind=None):
|
||||
|
||||
See Also
|
||||
--------
|
||||
available_plugins : List of available plugins
|
||||
plugins : List of available plugins
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
To use a plugin named 'null' as the default image reader, you would write:
|
||||
Use the Python Imaging Library to read images:
|
||||
|
||||
>>> from skimage import io
|
||||
>>> io.use_plugin('null', 'imread')
|
||||
|
||||
To see a list of available plugins run ``io.available_plugins``. Note that
|
||||
this lists plugins that are defined, but the full list may not be usable
|
||||
if your system does not have the required libraries installed.
|
||||
>>> from skimage.io import use_plugin
|
||||
>>> use_plugin('pil', 'imread')
|
||||
|
||||
"""
|
||||
if kind is None:
|
||||
|
||||
@@ -1,72 +1,88 @@
|
||||
import sys
|
||||
import os.path
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import assert_raises, assert_equal, assert_allclose
|
||||
from numpy.testing import (assert_raises,
|
||||
assert_equal,
|
||||
assert_array_almost_equal,
|
||||
)
|
||||
from numpy.testing.decorators import skipif
|
||||
|
||||
from skimage import data_dir
|
||||
from skimage.io.collection import ImageCollection, alphanumeric_key
|
||||
from skimage.io import ImageCollection, MultiImage
|
||||
from skimage.io.collection import alphanumeric_key
|
||||
from skimage.io import Image as ioImage
|
||||
|
||||
import six
|
||||
|
||||
|
||||
def test_string_split():
|
||||
test_string = 'z23a'
|
||||
test_str_result = ['z', 23, 'a']
|
||||
assert_equal(alphanumeric_key(test_string), test_str_result)
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
PIL_available = False
|
||||
else:
|
||||
PIL_available = True
|
||||
|
||||
|
||||
def test_string_sort():
|
||||
filenames = ['f9.10.png', 'f9.9.png', 'f10.10.png', 'f10.9.png',
|
||||
'e9.png', 'e10.png', 'em.png']
|
||||
sorted_filenames = ['e9.png', 'e10.png', 'em.png', 'f9.9.png',
|
||||
'f9.10.png', 'f10.9.png', 'f10.10.png']
|
||||
sorted_filenames = sorted(filenames, key=alphanumeric_key)
|
||||
assert_equal(sorted_filenames, sorted_filenames)
|
||||
class TestAlphanumericKey():
|
||||
def setUp(self):
|
||||
self.test_string = 'z23a'
|
||||
self.test_str_result = ['z', 23, 'a']
|
||||
self.filenames = ['f9.10.png', 'f9.9.png', 'f10.10.png', 'f10.9.png',
|
||||
'e9.png', 'e10.png', 'em.png']
|
||||
self.sorted_filenames = \
|
||||
['e9.png', 'e10.png', 'em.png', 'f9.9.png', 'f9.10.png',
|
||||
'f10.9.png', 'f10.10.png']
|
||||
|
||||
def test_string_split(self):
|
||||
assert_equal(alphanumeric_key(self.test_string), self.test_str_result)
|
||||
|
||||
def test_string_sort(self):
|
||||
sorted_filenames = sorted(self.filenames, key=alphanumeric_key)
|
||||
assert_equal(sorted_filenames, self.sorted_filenames)
|
||||
|
||||
|
||||
class TestImageCollection():
|
||||
|
||||
pattern = [os.path.join(data_dir, pic)
|
||||
for pic in ['camera.png', 'color.png']]
|
||||
|
||||
pattern_matched = [os.path.join(data_dir, pic)
|
||||
for pic in ['camera.png', 'moon.png']]
|
||||
pattern = [os.path.join(data_dir, pic) for pic in ['camera.png',
|
||||
'color.png']]
|
||||
pattern_matched = [os.path.join(data_dir, pic) for pic in
|
||||
['camera.png', 'moon.png']]
|
||||
|
||||
def setUp(self):
|
||||
# Generic image collection with images of different shapes.
|
||||
self.images = ImageCollection(self.pattern)
|
||||
# Image collection with images having shapes that match.
|
||||
self.images_matched = ImageCollection(self.pattern_matched)
|
||||
self.collection = ImageCollection(self.pattern)
|
||||
self.collection_matched = ImageCollection(self.pattern_matched)
|
||||
|
||||
def test_len(self):
|
||||
assert len(self.images) == 2
|
||||
assert len(self.collection) == 2
|
||||
|
||||
def test_getitem(self):
|
||||
num = len(self.images)
|
||||
num = len(self.collection)
|
||||
for i in range(-num, num):
|
||||
assert type(self.images[i]) is np.ndarray
|
||||
assert_allclose(self.images[0],
|
||||
self.images[-num])
|
||||
assert type(self.collection[i]) is np.ndarray
|
||||
assert_array_almost_equal(self.collection[0],
|
||||
self.collection[-num])
|
||||
|
||||
# assert_raises expects a callable, hence this thin wrapper function.
|
||||
#assert_raises expects a callable, hence this do-very-little func
|
||||
def return_img(n):
|
||||
return self.images[n]
|
||||
return self.collection[n]
|
||||
assert_raises(IndexError, return_img, num)
|
||||
assert_raises(IndexError, return_img, -num - 1)
|
||||
|
||||
def test_slicing(self):
|
||||
assert type(self.images[:]) is ImageCollection
|
||||
assert len(self.images[:]) == 2
|
||||
assert len(self.images[:1]) == 1
|
||||
assert len(self.images[1:]) == 1
|
||||
assert_allclose(self.images[0], self.images[:1][0])
|
||||
assert_allclose(self.images[1], self.images[1:][0])
|
||||
assert_allclose(self.images[1], self.images[::-1][0])
|
||||
assert_allclose(self.images[0], self.images[::-1][1])
|
||||
assert type(self.collection[:]) is ImageCollection
|
||||
assert len(self.collection[:]) == 2
|
||||
assert len(self.collection[:1]) == 1
|
||||
assert len(self.collection[1:]) == 1
|
||||
assert_array_almost_equal(self.collection[0], self.collection[:1][0])
|
||||
assert_array_almost_equal(self.collection[1], self.collection[1:][0])
|
||||
assert_array_almost_equal(self.collection[1], self.collection[::-1][0])
|
||||
assert_array_almost_equal(self.collection[0], self.collection[::-1][1])
|
||||
|
||||
def test_files_property(self):
|
||||
assert isinstance(self.images.files, list)
|
||||
assert isinstance(self.collection.files, list)
|
||||
|
||||
def set_files(f):
|
||||
self.images.files = f
|
||||
self.collection.files = f
|
||||
assert_raises(AttributeError, set_files, 'newfiles')
|
||||
|
||||
def test_custom_load(self):
|
||||
@@ -79,12 +95,59 @@ class TestImageCollection():
|
||||
assert_equal(ic[1], (2, 'two'))
|
||||
|
||||
def test_concatenate(self):
|
||||
array = self.images_matched.concatenate()
|
||||
expected_shape = (len(self.images_matched),) + self.images[0].shape
|
||||
assert_equal(array.shape, expected_shape)
|
||||
ar = self.collection_matched.concatenate()
|
||||
assert_equal(ar.shape, (len(self.collection_matched),) +
|
||||
self.collection[0].shape)
|
||||
assert_raises(ValueError, self.collection.concatenate)
|
||||
|
||||
def test_concatentate_mismatched_image_shapes(self):
|
||||
assert_raises(ValueError, self.images.concatenate)
|
||||
|
||||
class TestMultiImage():
|
||||
|
||||
def setUp(self):
|
||||
# This multipage TIF file was created with imagemagick:
|
||||
# convert im1.tif im2.tif -adjoin multipage.tif
|
||||
if PIL_available:
|
||||
self.img = MultiImage(os.path.join(data_dir, 'multipage.tif'))
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_len(self):
|
||||
assert len(self.img) == 2
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_getitem(self):
|
||||
num = len(self.img)
|
||||
for i in range(-num, num):
|
||||
assert type(self.img[i]) is np.ndarray
|
||||
assert_array_almost_equal(self.img[0],
|
||||
self.img[-num])
|
||||
|
||||
#assert_raises expects a callable, hence this do-very-little func
|
||||
def return_img(n):
|
||||
return self.img[n]
|
||||
assert_raises(IndexError, return_img, num)
|
||||
assert_raises(IndexError, return_img, -num - 1)
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_files_property(self):
|
||||
assert isinstance(self.img.filename, six.string_types)
|
||||
|
||||
def set_filename(f):
|
||||
self.img.filename = f
|
||||
assert_raises(AttributeError, set_filename, 'newfile')
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_conserve_memory_property(self):
|
||||
assert isinstance(self.img.conserve_memory, bool)
|
||||
|
||||
def set_mem(val):
|
||||
self.img.conserve_memory = val
|
||||
assert_raises(AttributeError, set_mem, True)
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_concatenate(self):
|
||||
ar = self.img.concatenate()
|
||||
assert_equal(ar.shape, (len(self.img),) +
|
||||
self.img[0].shape)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
from skimage.io.inherited_config import InheritedConfig
|
||||
|
||||
|
||||
def test_get_non_existent():
|
||||
config = InheritedConfig()
|
||||
assert config.get('size') is None
|
||||
|
||||
|
||||
def test_get_simple():
|
||||
config = InheritedConfig({'imread': 'matplotlib'})
|
||||
assert config.get('imread') == 'matplotlib'
|
||||
|
||||
|
||||
def test_get_default():
|
||||
config = InheritedConfig()
|
||||
assert config.get('size', 10) == 10
|
||||
|
||||
|
||||
def test_get_best():
|
||||
config = InheritedConfig({'size': 0, 'size.text': 1})
|
||||
assert config.get('size.text') == 1
|
||||
|
||||
|
||||
def test_get_multi_level():
|
||||
config = InheritedConfig({'size': 0})
|
||||
assert config.get('size.text.title') == 0
|
||||
config['size.text'] = 1
|
||||
assert config.get('size.text.title') == 1
|
||||
config['size.text.title'] = 2
|
||||
assert config.get('size.text.title') == 2
|
||||
|
||||
|
||||
def test_contains():
|
||||
config = InheritedConfig({'imread': 'matplotlib'})
|
||||
assert 'imread' in config
|
||||
assert 'imread.jpg' in config
|
||||
|
||||
|
||||
def test_getitem():
|
||||
config = InheritedConfig({'imread': 'a'})
|
||||
assert config['imread'] == 'a'
|
||||
assert config['imread.png'] == 'a'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy import testing
|
||||
testing.run_module_suite()
|
||||
@@ -1,69 +0,0 @@
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing.decorators import skipif
|
||||
from numpy.testing import assert_raises, assert_equal, assert_allclose
|
||||
|
||||
from skimage import data_dir
|
||||
from skimage.io.collection import MultiImage
|
||||
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
PIL_available = False
|
||||
else:
|
||||
PIL_available = True
|
||||
|
||||
import six
|
||||
|
||||
|
||||
class TestMultiImage():
|
||||
|
||||
def setUp(self):
|
||||
# This multipage TIF file was created with imagemagick:
|
||||
# convert im1.tif im2.tif -adjoin multipage.tif
|
||||
if PIL_available:
|
||||
self.img = MultiImage(os.path.join(data_dir, 'multipage.tif'))
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_len(self):
|
||||
assert len(self.img) == 2
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_getitem(self):
|
||||
num = len(self.img)
|
||||
for i in range(-num, num):
|
||||
assert type(self.img[i]) is np.ndarray
|
||||
assert_allclose(self.img[0], self.img[-num])
|
||||
|
||||
# assert_raises expects a callable, hence this thin wrapper function.
|
||||
def return_img(n):
|
||||
return self.img[n]
|
||||
assert_raises(IndexError, return_img, num)
|
||||
assert_raises(IndexError, return_img, -num - 1)
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_files_property(self):
|
||||
assert isinstance(self.img.filename, six.string_types)
|
||||
|
||||
def set_filename(f):
|
||||
self.img.filename = f
|
||||
assert_raises(AttributeError, set_filename, 'newfile')
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_conserve_memory_property(self):
|
||||
assert isinstance(self.img.conserve_memory, bool)
|
||||
|
||||
def set_mem(val):
|
||||
self.img.conserve_memory = val
|
||||
assert_raises(AttributeError, set_mem, True)
|
||||
|
||||
@skipif(not PIL_available)
|
||||
def test_concatenate(self):
|
||||
array = self.img.concatenate()
|
||||
assert_equal(array.shape, (len(self.img),) + self.img[0].shape)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from numpy.testing import run_module_suite
|
||||
run_module_suite()
|
||||
Reference in New Issue
Block a user