diff --git a/doc/source/api_changes.txt b/doc/source/api_changes.txt index fdf66821..9e6cf28c 100644 --- a/doc/source/api_changes.txt +++ b/doc/source/api_changes.txt @@ -1,4 +1,5 @@ Version 0.3 ----------- -- Remove ``as_grey``, ``dtype`` keywords from imread and ImageCollection +- Remove ``as_grey``, ``dtype`` keyword from ImageCollection +- Remove ``dtype`` from imread - Generalise ImageCollection to accept a load_func diff --git a/scikits/image/color/colorconv.py b/scikits/image/color/colorconv.py index d7c5f4d2..97b3af69 100644 --- a/scikits/image/color/colorconv.py +++ b/scikits/image/color/colorconv.py @@ -44,7 +44,7 @@ References from __future__ import division __all__ = ['convert_colorspace', 'rgb2hsv', 'hsv2rgb', 'rgb2xyz', 'xyz2rgb', - 'rgb2rgbcie', 'rgbcie2rgb'] + 'rgb2rgbcie', 'rgbcie2rgb', 'rgb2grey', 'rgb2gray'] __docformat__ = "restructuredtext en" @@ -264,7 +264,7 @@ xyz_from_rgb = np.array([[0.412453, 0.357580, 0.180423], rgb_from_xyz = linalg.inv(xyz_from_rgb) # From http://en.wikipedia.org/wiki/CIE_1931_color_space -# Note: Travis' code did not have the divide by 0.17697 +# Note: Travis's code did not have the divide by 0.17697 xyz_from_rgbcie = np.array([[0.49, 0.31, 0.20], [0.17697, 0.81240, 0.01063], [0.00, 0.01, 0.99]]) / 0.17697 @@ -276,6 +276,10 @@ rgbcie_from_rgb = np.dot(rgbcie_from_xyz, xyz_from_rgb) rgb_from_rgbcie = np.dot(rgb_from_xyz, xyz_from_rgbcie) +grey_from_rgb = np.array([[0.2125, 0.7154, 0.0721], + [0, 0, 0], + [0, 0, 0]]) + #------------------------------------------------------------- # The conversion functions that make use of the matrices above #------------------------------------------------------------- @@ -338,6 +342,7 @@ def xyz2rgb(xyz): >>> import os >>> from scikits.image import data_dir >>> from scikits.image.io import imread + >>> from scikits.image.color import rgb2xyz, xyz2rgb >>> lena = imread(os.path.join(data_dir, 'lena.png')) >>> lena_xyz = rgb2xyz(lena) @@ -410,6 +415,7 @@ def rgb2rgbcie(rgb): >>> import os >>> from scikits.image import data_dir >>> from scikits.image.io import imread + >>> from scikits.image.color import rgb2rgbcie >>> lena = imread(os.path.join(data_dir, 'lena.png')) >>> lena_rgbcie = rgb2rgbcie(lena) @@ -443,9 +449,54 @@ def rgbcie2rgb(rgbcie): >>> import os >>> from scikits.image import data_dir >>> from scikits.image.io import imread + >>> from scikits.image.color import rgb2rgbcie, rgbcie2rgb >>> lena = imread(os.path.join(data_dir, 'lena.png')) >>> lena_rgbcie = rgb2rgbcie(lena) >>> lena_rgb = rgbcie2rgb(lena_hsv) """ return _convert(rgb_from_rgbcie, rgbcie) + +def rgb2grey(rgb): + """Compute luminance of an RGB image. + + Parameters + ---------- + rgb : array_like + The image in RGB format, in a 3-D array of shape (.., .., 3). + + Returns + ------- + out : ndarray + The luminance image, a 2-D array. + + Raises + ------ + ValueError + If `rgb2grey` is not a 3-D array of shape (.., .., 3). + + References + ---------- + .. [1] http://www.poynton.com/PDFs/ColorFAQ.pdf + + Notes + ----- + The weights used in this conversion are calibrated for contemporary + CRT phosphors:: + + Y = 0.2125 R + 0.7154 G + 0.0721 B + + Examples + -------- + >>> import os + >>> from scikits.image import data_dir + >>> from scikits.image.io import imread + >>> from scikits.image.color import rgb2grey + + >>> lena = imread(os.path.join(data_dir, 'lena.png')) + >>> lena_grey = rgb2grey(lena) + """ + return _convert(grey_from_rgb, rgb)[..., 0] + +rgb2gray = rgb2grey + diff --git a/scikits/image/color/tests/test_colorconv.py b/scikits/image/color/tests/test_colorconv.py index ac861555..74cf34fd 100644 --- a/scikits/image/color/tests/test_colorconv.py +++ b/scikits/image/color/tests/test_colorconv.py @@ -21,7 +21,8 @@ from scikits.image.color import ( rgb2hsv, hsv2rgb, rgb2xyz, xyz2rgb, rgb2rgbcie, rgbcie2rgb, - convert_colorspace + convert_colorspace, + rgb2grey ) from scikits.image import data_dir @@ -142,6 +143,13 @@ class TestColorconv(TestCase): self.assertRaises(ValueError, convert_colorspace, self.colbars_array, 'RGB', 'nokey') + def test_rgb2grey(self): + x = np.array([1, 1, 1]).reshape((1, 1, 3)) + g = rgb2grey(x) + assert_array_almost_equal(g, 1) + + assert_equal(g.shape, (1, 1)) + if __name__ == "__main__": run_module_suite() diff --git a/scikits/image/io/_plugins/freeimage_plugin.py b/scikits/image/io/_plugins/freeimage_plugin.py index bf2a334e..4e71312b 100644 --- a/scikits/image/io/_plugins/freeimage_plugin.py +++ b/scikits/image/io/_plugins/freeimage_plugin.py @@ -319,11 +319,11 @@ def _array_from_bitmap(bitmap): def n(arr): return arr[..., ::-1].T if len(shape) == 3 and _FI.FreeImage_IsLittleEndian() and \ - dtype.type == np.uint8: + dtype.type == numpy.uint8: b = array[0] g = array[1] r = array[2] - return np.dstack( (n(r), n(g), n(b)) ) + return numpy.dstack( (n(r), n(g), n(b)) ) # We need to copy because array does *not* own its memory # after bitmap is freed. return n(array).copy() @@ -460,8 +460,8 @@ def imread(filename, as_grey=False): img = read(filename) if as_grey and len(img) == 3: # these are the values that wikipedia says are typical - transform = np.array([ 0.30, 0.59, 0.11]) - return np.dot(img, transform) + transform = numpy.array([ 0.30, 0.59, 0.11]) + return numpy.dot(img, transform) return img def imsave(filename, img): diff --git a/scikits/image/io/_plugins/test_freeimage.py b/scikits/image/io/_plugins/test_freeimage.py new file mode 100644 index 00000000..77a92408 --- /dev/null +++ b/scikits/image/io/_plugins/test_freeimage.py @@ -0,0 +1,13 @@ +import os + +import scikits.image as si +import scikits.image.io as sio + +sio.use_plugin('matplotlib', 'imshow') +sio.use_plugin('freeimage', 'imread') + +img = sio.imread(os.path.join(si.data_dir, 'color.png')) + +sio.imshow(img) +sio.show() + diff --git a/scikits/image/io/_plugins/test_plugin.py b/scikits/image/io/_plugins/test_plugin.py index 975d55d9..dbdd542c 100644 --- a/scikits/image/io/_plugins/test_plugin.py +++ b/scikits/image/io/_plugins/test_plugin.py @@ -1,6 +1,5 @@ def imread(fname, as_grey=False, dtype=None): assert fname == 'test.png' - assert as_grey == True assert dtype == 'i4' def imsave(fname, arr): diff --git a/scikits/image/io/collection.py b/scikits/image/io/collection.py index dc3e51db..ea755a77 100644 --- a/scikits/image/io/collection.py +++ b/scikits/image/io/collection.py @@ -23,9 +23,6 @@ class MultiImage(object): conserve_memory : bool, optional Whether to conserve memory by only caching a single frame. Default is True. - dtype : dtype, optional - NumPy data-type specifier. If given, the returned image has this type. - If None (default), the data-type is determined automatically. Attributes ---------- diff --git a/scikits/image/io/io.py b/scikits/image/io/io.py index c920fa64..37b73686 100644 --- a/scikits/image/io/io.py +++ b/scikits/image/io/io.py @@ -1,6 +1,7 @@ __all__ = ['imread', 'imsave', 'imshow', 'show', 'push', 'pop'] from scikits.image.io._plugins import call as call_plugin +from scikits.image.color import rgb2grey import numpy as np # Shared image queue @@ -31,7 +32,7 @@ def pop(): """ return _image_stack.pop() -def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None, +def imread(fname, as_grey=False, plugin=None, flatten=None, **plugin_args): """Load an image from file. @@ -40,12 +41,8 @@ def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None, 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. + If True, convert color images to grey-scale (32-bit floats). 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 (Python Imaging Library by default). @@ -71,8 +68,12 @@ def imread(fname, as_grey=False, dtype=None, plugin=None, flatten=None, if flatten is not None: as_grey = flatten - return call_plugin('imread', fname, as_grey=as_grey, dtype=dtype, - plugin=plugin, **plugin_args) + img = call_plugin('imread', fname, plugin=plugin, **plugin_args) + + if as_grey and getattr(img, 'ndim', 0) >= 3: + img = rgb2grey(img) + + return img def imsave(fname, arr, plugin=None, **plugin_args): """Save an image to file. diff --git a/scikits/image/io/tests/test_pil.py b/scikits/image/io/tests/test_pil.py index 0dbb877f..f039f812 100644 --- a/scikits/image/io/tests/test_pil.py +++ b/scikits/image/io/tests/test_pil.py @@ -9,17 +9,14 @@ from scikits.image.io import imread, imsave from scikits.image.io._plugins.pil_plugin import _palette_is_grayscale def test_imread_flatten(): - # a color image is flattened and returned as float32 + # a color image is flattened img = imread(os.path.join(data_dir, 'color.png'), flatten=True) - assert img.dtype == np.float32 + 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'] -def test_imread_dtype(): - img = imread(os.path.join(data_dir, 'camera.png'), dtype=np.float64) - assert img.dtype == np.float64 - def test_imread_palette(): img = imread(os.path.join(data_dir, 'palette_gray.png')) assert img.ndim == 2