mirror of
https://github.com/wassname/scikit-image.git
synced 2026-07-02 04:42:23 +08:00
Merge pull request #862 from tonysyu/refactor/imread_collection
Add `imread_collection` automatically if plugin provides `imread`
This commit is contained in:
@@ -2,18 +2,18 @@
|
||||
|
||||
from __future__ import with_statement
|
||||
|
||||
__all__ = ['MultiImage', 'ImageCollection', 'imread', 'concatenate_images']
|
||||
|
||||
from glob import glob
|
||||
import re
|
||||
from copy import copy
|
||||
|
||||
import numpy as np
|
||||
from ._io import imread
|
||||
|
||||
import six
|
||||
|
||||
|
||||
__all__ = ['MultiImage', 'ImageCollection', 'concatenate_images',
|
||||
'imread_collection_wrapper']
|
||||
|
||||
|
||||
def concatenate_images(ic):
|
||||
"""Concatenate all images in the image collection into an array.
|
||||
|
||||
@@ -312,6 +312,7 @@ class ImageCollection(object):
|
||||
self._cached = None
|
||||
|
||||
if load_func is None:
|
||||
from ._io import imread
|
||||
self.load_func = imread
|
||||
else:
|
||||
self.load_func = load_func
|
||||
@@ -430,3 +431,29 @@ class ImageCollection(object):
|
||||
If images in the `ImageCollection` don't have identical shapes.
|
||||
"""
|
||||
return concatenate_images(self)
|
||||
|
||||
|
||||
def imread_collection_wrapper(imread):
|
||||
def imread_collection(load_pattern, conserve_memory=True):
|
||||
"""Return an `ImageCollection` from files matching the given pattern.
|
||||
|
||||
Note that files are always stored in alphabetical order. Also note that
|
||||
slicing returns a new ImageCollection, *not* a view into the data.
|
||||
|
||||
See `skimage.io.ImageCollection` for details.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
load_pattern : str or list
|
||||
Pattern glob or filenames to load. The path can be absolute or
|
||||
relative. Multiple patterns should be separated by a colon,
|
||||
e.g. '/tmp/work/*.png:/tmp/other/*.jpg'. Also see
|
||||
implementation notes below.
|
||||
conserve_memory : bool, optional
|
||||
If True, never keep more than one in memory at a specific
|
||||
time. Otherwise, images will be cached once they are loaded.
|
||||
|
||||
"""
|
||||
return ImageCollection(load_pattern, conserve_memory=conserve_memory,
|
||||
load_func=imread)
|
||||
return imread_collection
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
"""Handle image reading, writing and plotting plugins.
|
||||
|
||||
To improve performance, plugins are only loaded as needed. As a result, there
|
||||
can be multiple states for a given plugin:
|
||||
|
||||
available: Defined in an *ini file located in `skimage.io._plugins`.
|
||||
See also `skimage.io.available_plugins`.
|
||||
partial definition: Specified in an *ini file, but not defined in the
|
||||
corresponding plugin module. This will raise an error when loaded.
|
||||
available but not on this system: Defined in `skimage.io._plugins`, but
|
||||
a dependent library (e.g. Qt, PIL) is not available on your system.
|
||||
This will raise an error when loaded.
|
||||
loaded: The real availability is determined when it's explicitly loaded,
|
||||
either because it's one of the default plugins, or because it's
|
||||
loaded explicitly by the user.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
@@ -10,6 +24,8 @@ except ImportError:
|
||||
import os.path
|
||||
from glob import glob
|
||||
|
||||
from .collection import imread_collection_wrapper
|
||||
|
||||
|
||||
__all__ = ['use_plugin', 'call_plugin', 'plugin_info', 'plugin_order',
|
||||
'reset_plugins', 'find_available_plugins', 'available_plugins']
|
||||
@@ -18,11 +34,14 @@ __all__ = ['use_plugin', 'call_plugin', 'plugin_info', 'plugin_order',
|
||||
# The plugin store will save a list of *loaded* io functions for each io type
|
||||
# (e.g. 'imread', 'imsave', etc.). Plugins are loaded as requested.
|
||||
plugin_store = None
|
||||
|
||||
# Dictionary mapping plugin names to a list of functions they provide.
|
||||
plugin_provides = {}
|
||||
# The module names for the plugins in `skimage.io._plugins`.
|
||||
plugin_module_name = {}
|
||||
# Meta-data about plugins provided by *.ini files.
|
||||
plugin_meta_data = {}
|
||||
|
||||
# For each plugin type, default to the first available plugin as defined by
|
||||
# the following preferences.
|
||||
preferred_plugins = {
|
||||
# Default plugins for all types (overridden by specific types below).
|
||||
'all': ['matplotlib', 'pil', 'qt', 'freeimage', 'null'],
|
||||
@@ -105,7 +124,14 @@ def _scan_plugins():
|
||||
print("Plugin `%s` wants to provide non-existent `%s`." \
|
||||
" Ignoring." % (name, p))
|
||||
|
||||
# Add plugins that provide 'imread' as provider of 'imread_collection'.
|
||||
need_to_add_collection = ('imread_collection' not in valid_provides and
|
||||
'imread' in valid_provides)
|
||||
if need_to_add_collection:
|
||||
valid_provides.append('imread_collection')
|
||||
|
||||
plugin_provides[name] = valid_provides
|
||||
|
||||
plugin_module_name[name] = os.path.basename(filename)[:-4]
|
||||
|
||||
_scan_plugins()
|
||||
@@ -135,7 +161,7 @@ def find_available_plugins(loaded=False):
|
||||
d = {}
|
||||
for plugin in plugin_provides:
|
||||
if not loaded or plugin in active_plugins:
|
||||
d[plugin] = [f for f in plugin_provides[plugin] \
|
||||
d[plugin] = [f for f in plugin_provides[plugin]
|
||||
if not f.startswith('_')]
|
||||
|
||||
return d
|
||||
@@ -240,6 +266,14 @@ def use_plugin(name, kind=None):
|
||||
plugin_store[k] = funcs
|
||||
|
||||
|
||||
def _inject_imread_collection_if_needed(module):
|
||||
"""Add `imread_collection` to module if not already present."""
|
||||
if not hasattr(module, 'imread_collection') and hasattr(module, 'imread'):
|
||||
imread = getattr(module, 'imread')
|
||||
func = imread_collection_wrapper(imread)
|
||||
setattr(module, 'imread_collection', func)
|
||||
|
||||
|
||||
def _load(plugin):
|
||||
"""Load the given plugin.
|
||||
|
||||
@@ -264,14 +298,17 @@ def _load(plugin):
|
||||
|
||||
provides = plugin_provides[plugin]
|
||||
for p in provides:
|
||||
if not hasattr(plugin_module, p):
|
||||
if p == 'imread_collection':
|
||||
_inject_imread_collection_if_needed(plugin_module)
|
||||
elif not hasattr(plugin_module, p):
|
||||
print("Plugin %s does not provide %s as advertised. Ignoring." % \
|
||||
(plugin, p))
|
||||
else:
|
||||
store = plugin_store[p]
|
||||
func = getattr(plugin_module, p)
|
||||
if not (plugin, func) in store:
|
||||
store.append((plugin, func))
|
||||
continue
|
||||
|
||||
store = plugin_store[p]
|
||||
func = getattr(plugin_module, p)
|
||||
if not (plugin, func) in store:
|
||||
store.append((plugin, func))
|
||||
|
||||
|
||||
def plugin_info(plugin):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import os
|
||||
import warnings
|
||||
from contextlib import contextmanager
|
||||
|
||||
import numpy as np
|
||||
from numpy.testing import raises
|
||||
@@ -8,28 +9,42 @@ from skimage import io
|
||||
from skimage import data_dir
|
||||
|
||||
|
||||
@contextmanager
|
||||
def warnings_as_errors():
|
||||
# Temporarily set warnings as errors so we can test the warning is raised.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings('error')
|
||||
yield
|
||||
|
||||
@raises(Warning)
|
||||
def test_null_imread():
|
||||
path = os.path.join(data_dir, 'color.png')
|
||||
with warnings.catch_warnings(): # Temporarily set warnings as errors.
|
||||
warnings.filterwarnings('error')
|
||||
with warnings_as_errors():
|
||||
io.imread(path, plugin='null')
|
||||
|
||||
|
||||
@raises(Warning)
|
||||
def test_null_imsave():
|
||||
with warnings.catch_warnings(): # Temporarily set warnings as errors.
|
||||
warnings.filterwarnings('error')
|
||||
with warnings_as_errors():
|
||||
io.imsave('dummy.png', np.zeros((3, 3)), plugin='null')
|
||||
|
||||
|
||||
@raises(Warning)
|
||||
def test_null_imshow():
|
||||
with warnings.catch_warnings(): # Temporarily set warnings as errors.
|
||||
warnings.filterwarnings('error')
|
||||
with warnings_as_errors():
|
||||
io.imshow(np.zeros((3, 3)), plugin='null')
|
||||
|
||||
|
||||
@raises(Warning)
|
||||
def test_null_imread_collection():
|
||||
# Note that the null plugin doesn't define an `imread_collection` plugin
|
||||
# but this function is dynamically added by the plugin manager.
|
||||
path = os.path.join(data_dir, '*.png')
|
||||
with warnings_as_errors():
|
||||
collection = io.imread_collection(path, plugin='null')
|
||||
collection[0]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from numpy.testing import run_module_suite
|
||||
run_module_suite()
|
||||
|
||||
Reference in New Issue
Block a user