diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 8ba62e0b..012fd53d 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -119,4 +119,7 @@ Perimeter calculation in regionprops. - Olivier Debeir - Rank filters (8- and 16-bits) using sliding window. \ No newline at end of file + Rank filters (8- and 16-bits) using sliding window. + +- Luis Pedro Coelho + imread plugin diff --git a/skimage/io/_plugins/imread_plugin.ini b/skimage/io/_plugins/imread_plugin.ini new file mode 100644 index 00000000..a6a5ddb1 --- /dev/null +++ b/skimage/io/_plugins/imread_plugin.ini @@ -0,0 +1,3 @@ +[imread] +description = Image reading and writing via imread +provides = imread, imsave diff --git a/skimage/io/_plugins/imread_plugin.py b/skimage/io/_plugins/imread_plugin.py new file mode 100644 index 00000000..323fbec8 --- /dev/null +++ b/skimage/io/_plugins/imread_plugin.py @@ -0,0 +1,44 @@ +__all__ = ['imread', 'imsave'] + +import numpy as np +from skimage.utils.dtype import convert + +try: + import imread as _imread +except ImportError: + raise ImportError("Imread could not be found" + "Please refer to http://pypi.python.org/pypi/imread/ " + "for further instructions.") + +def imread(fname, dtype=None): + """Load an image from file. + + Parameters + ---------- + fname : str + Name of input file + + """ + im = _imread.imread(fname) + if dtype is not None: + im = convert(im, dtype) + return im + +def imsave(fname, arr, format_str=None): + """Save an image to disk. + + Parameters + ---------- + fname : str + Name of destination file. + arr : ndarray of uint8 or uint16 + Array (image) to save. + format_str: str,optional + Format to save as. + + Notes + ----- + Currently, only 8-bit precision is supported. + """ + return _imread.imsave(fname, arr, formatstr=format_str) + diff --git a/skimage/io/tests/test_imread.py b/skimage/io/tests/test_imread.py new file mode 100644 index 00000000..afb9eac9 --- /dev/null +++ b/skimage/io/tests/test_imread.py @@ -0,0 +1,73 @@ +import os.path +import numpy as np +from numpy.testing import * +from numpy.testing.decorators import skipif + +from tempfile import NamedTemporaryFile + +from skimage import data_dir +from skimage.io import imread, imsave, use_plugin, reset_plugins + +try: + import imread as _imread + use_plugin('imread') +except ImportError: + imread_available = False +else: + imread_available = True + + +def teardown(): + reset_plugins() + + +@skipif(not imread_available) +def test_imread_flatten(): + # a color image is flattened + img = imread(os.path.join(data_dir, 'color.png'), flatten=True) + assert img.ndim == 2 + assert img.dtype == np.float64 + img = imread(os.path.join(data_dir, 'camera.png'), flatten=True) + # check that flattening does not occur for an image that is grey already. + assert np.sctype2char(img.dtype) in np.typecodes['AllInteger'] + + +@skipif(not imread_available) +def test_imread_palette(): + img = imread(os.path.join(data_dir, 'palette_color.png')) + assert img.ndim == 3 + + +@skipif(not imread_available) +def test_bilevel(): + expected = np.zeros((10, 10), bool) + expected[::2] = 1 + + img = imread(os.path.join(data_dir, 'checker_bilevel.png')) + assert_array_equal(img, expected) + + +class TestSave: + def roundtrip(self, x, scaling=1): + f = NamedTemporaryFile(suffix='.png') + fname = f.name + f.close() + imsave(fname, x) + y = imread(fname) + + assert_array_almost_equal((x * scaling).astype(np.int32), y) + + @skipif(not imread_available) + def test_imsave_roundtrip(self): + dtype = np.uint8 + for shape in [(10, 10), (10, 10, 3), (10, 10, 4)]: + x = np.ones(shape, dtype=dtype) * np.random.random(shape) + + if np.issubdtype(dtype, float): + yield self.roundtrip, x, 255 + else: + x = (x * 255).astype(dtype) + yield self.roundtrip, x + +if __name__ == "__main__": + run_module_suite()