Plugin framework for image I/O.

This commit is contained in:
Stefan van der Walt
2009-10-31 21:10:27 +02:00
parent 05a4b73de6
commit 9bec0ef888
6 changed files with 179 additions and 41 deletions
+4 -2
View File
@@ -1,7 +1,9 @@
"""Utilities to read and write images in various formats."""
import pil_plugin
import matplotlib_plugin
from pil_imread import *
from io import *
from plugin import register as register_plugin
from sift import *
from collection import *
+107
View File
@@ -0,0 +1,107 @@
from scikits.image.io.plugin import plugin_store
def _call_plugin(kind, *args, **kwargs):
if not kind in plugin_store:
raise ValueError('Invalid function (%s) requested.' % kind)
plugin_funcs = plugin_store[kind]
if len(plugin_funcs) == 0:
raise RuntimeError('No suitable plugin registered for %s' % kind)
plugin = kwargs.pop('plugin', None)
if plugin is None:
_, func = plugin_funcs[0]
else:
try:
func = [f for (p,f) in plugin_funcs if p == plugin][0]
except IndexError:
raise RuntimeError('Could not find the plugin "%s" for %s.' % \
(plugin, kind))
return func(*args, **kwargs)
def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None,
**plugin_args):
"""Load an image from file.
Parameters
----------
fname : string
Image file name, e.g. ``test.jpg``.
as_grey : bool
If True, convert color images to grey-scale. If `dtype` is not given,
converted color images are returned as 32-bit float images.
Images that are already in grey-scale format are not converted.
dtype : dtype, optional
NumPy data-type specifier. If given, the returned image has this type.
If None (default), the data-type is determined automatically.
plugin : str
Name of plugin to use. By default, the different plugins are
tried (starting with the Python Imaging Library) until a suitable
candidate is found.
Other Parameters
----------------
flatten : bool
Backward compatible keyword, superseded by `as_grey`.
Returns
-------
img_array : ndarray
The different colour bands/channels are stored in the
third dimension, such that a grey-image is MxN, an
RGB-image MxNx3 and an RGBA-image MxNx4.
Other parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
# Backward compatibility
if flatten is not None:
as_grey = flatten
_call_plugin('read', as_grey, dtype, plugin=plugin, **plugin_args)
def imsave(fname, arr, plugin=None, **plugin_args):
"""Save an image to file.
Parameters
----------
fname : str
Target filename.
arr : ndarray of shape (M,N) or (M,N,3) or (M,N,4)
Image data.
plugin : str
Name of plugin to use. By default, the different plugins are
tried (starting with the Python Imaging Library) until a suitable
candidate is found.
Other parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
_call_plugin('save', fname, arr, plugin=plugin, **plugin_args)
def imshow(arr, plugin=None, **plugin_args):
"""Display an image.
Parameters
----------
arr : ndarray
Image data.
plugin : str
Name of plugin to use. By default, the different plugins are
tried (starting with the Python Imaging Library) until a suitable
candidate is found.
Other parameters
----------------
plugin_args : keywords
Passed to the given plugin.
"""
_call_plugin('show', arr, plugin=None, **plugin_args)
+8
View File
@@ -0,0 +1,8 @@
import plugin
try:
import matplotlib.pyplot as plt
except ImportError:
pass
else:
plugin.register('matplotlib', show=plt.imshow, save=plt.imsave)
-39
View File
@@ -1,39 +0,0 @@
__all__ = ['imread']
import numpy as np
def imread(fname, flatten=False, dtype=None):
"""Load an image from file.
Parameters
----------
fname : string
Image file name, e.g. ``test.jpg``.
flatten : bool
If True, convert color images to grey-scale. If `dtype` is not given,
converted color images are returned as 32-bit float images.
Images that are already in grey-scale format are not converted.
dtype : dtype, optional
NumPy data-type specifier. If given, the returned image has this type.
If None (default), the data-type is determined automatically.
Returns
-------
img_array : ndarray
The different colour bands/channels are stored in the
third dimension, such that a grey-image is MxN, an
RGB-image MxNx3 and an RGBA-image MxNx4.
"""
try:
from PIL import Image
except ImportError:
raise ImportError("Could not import the Python Imaging Library (PIL)"
" required to load image files. Please refer to"
" http://pypi.python.org/pypi/PIL/ for installation"
" instructions.")
im = Image.open(fname)
if flatten and not im.mode in ('1', 'L', 'I', 'F', 'I;16', 'I;16L', 'I;16B'):
im = im.convert('F')
return np.array(im, dtype=dtype)
+23
View File
@@ -0,0 +1,23 @@
__all__ = ['imread']
import numpy as np
import plugin
try:
from PIL import Image
has_pil = True
except ImportError:
has_pil = False
def imread(fname, as_grey=False, dtype=None):
"""Load an image from file.
"""
im = Image.open(fname)
if as_grey and \
not im.mode in ('1', 'L', 'I', 'F', 'I;16', 'I;16L', 'I;16B'):
im = im.convert('F')
return np.array(im, dtype=dtype)
if has_pil:
plugin.register('PIL', read=imread)
+37
View File
@@ -0,0 +1,37 @@
"""Handle image reading, writing and plotting plugins.
"""
plugin_store = {'read': [],
'save': [],
'show': []}
def register(name, **kwds):
"""Register an image I/O plugin.
Parameters
----------
name : str
Name of this plugin.
read : callable, optional
Function with signature
``read(filename, as_grey=False, dtype=None, **plugin_specific_args)``
that reads images.
save : callable, optional
Function with signature
``write(filename, arr, **plugin_specific_args)``
that writes an image to disk.
show : callable, optional
Function with signature
``show(X, **plugin_specific_args)`` that displays an image.
"""
for kind in kwds:
if kind not in plugin_store.keys():
raise ValueError('Tried to register invalid plugin method.')
func = kwds[kind]
if not callable(func):
raise ValueError('Can only register functions as plugins.')
plugin_store[kind].append((name, func))