From bf5e6f782753c6bfe1a68d236eca4ce4664830c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Sun, 17 Jul 2016 13:13:08 +0200 Subject: [PATCH 1/5] DOC: image inversion --- .../user_guide/transforming_image_data.rst | 22 ++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.rst b/doc/source/user_guide/transforming_image_data.rst index 883cda41..ac19178f 100644 --- a/doc/source/user_guide/transforming_image_data.rst +++ b/doc/source/user_guide/transforming_image_data.rst @@ -21,7 +21,7 @@ green and blue channels. However, other color models are widely used, such as the `HSV color model `_, where hue, saturation and value are independent channels, or the `CMYK model -`_ used for printing. +`_ used for printing. :mod:`skimage.color` provides utility functions to convert images to and from different color spaces. Integer-type arrays can be @@ -46,7 +46,7 @@ Conversion from RGBA to RGB - Removing alpha channel through alpha blending ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Converting an RGBA image to an RGB image by alpha blending it with a -background is realized with :func:`rgba2rgb` :: +background is realized with :func:`rgba2rgb` :: >>> from skimage.color import rgba2rgb >>> from skimage import data @@ -57,7 +57,7 @@ Conversion between color and gray values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Converting an RGB image to a grayscale image is realized with -:func:`rgb2gray` :: +:func:`rgb2gray` :: >>> from skimage.color import rgb2gray >>> from skimage import data @@ -81,12 +81,24 @@ from RGB to grayscale:: Converting a grayscale image to RGB with :func:`gray2rgb` simply duplicates the gray values over the three color channels. +Image inversion +~~~~~~~~~~~~~~~ + +An inverted image is also called complementary image. For binary images, True values +become False and conversely. For grayscale images, pixel values are replaced by the +difference of the maximum value of the data type and the actual value. For RGB +images, the same operation is done for each channel. This operation can be achieved +with the negation operator ~ on any numpy array:: + + >>> img = data.camera() + >>> inverted_img = ~img + Painting images with labels ~~~~~~~~~~~~~~~~~~~~~~~~~~~ :func:`label2rgb` can be used to superimpose colors on a grayscale image using an array of labels to encode the regions to be represented with the -same color. +same color. .. image:: ../auto_examples/segmentation/images/sphx_glr_plot_join_segmentations_001.png @@ -139,7 +151,7 @@ the boundaries of the bins. The simplest contrast enhancement :func:`rescale_intensity` consists in stretching pixel values to the whole allowed range, using a linear transformation:: - + >>> from skimage import exposure >>> text = data.text() >>> text.min(), text.max() From 2f0b9ace094d13db39018afa71a04b6695e81e5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Mon, 1 Aug 2016 11:35:10 +0200 Subject: [PATCH 2/5] Implement invert function --- skimage/util/__init__.py | 2 ++ skimage/util/invert.py | 33 +++++++++++++++++++++++ skimage/util/tests/test_invert.py | 45 +++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+) create mode 100644 skimage/util/invert.py create mode 100644 skimage/util/tests/test_invert.py diff --git a/skimage/util/__init__.py b/skimage/util/__init__.py index 2500469b..5aee7337 100644 --- a/skimage/util/__init__.py +++ b/skimage/util/__init__.py @@ -7,6 +7,7 @@ from .apply_parallel import apply_parallel from .arraypad import pad, crop from ._regular_grid import regular_grid from .unique import unique_rows +from .invert import invert __all__ = ['img_as_float', @@ -22,4 +23,5 @@ __all__ = ['img_as_float', 'random_noise', 'regular_grid', 'apply_parallel', + 'invert', 'unique_rows'] diff --git a/skimage/util/invert.py b/skimage/util/invert.py new file mode 100644 index 00000000..be0ddef2 --- /dev/null +++ b/skimage/util/invert.py @@ -0,0 +1,33 @@ +import numpy as np +from .dtype import dtype_limits + + +def invert(image): + """Invert an image. + + Substract the image to the maximum value allowed by the dtype maximum. + + Parameters + ---------- + image : ndarray + The input image. + + Returns + ------- + invert : ndarray + Inverted image. + + Examples + -------- + >>> img = np.array([[100, 0, 200], + ... [0, 50, 0], + ... [30, 0, 255]], np.uint8) + >>> invert(img) + array([[155, 255, 55], + [255, 205, 255], + [225, 255, 0]], dtype=uint8) + """ + if image.dtype == 'bool': + return ~image + else: + return dtype_limits(image)[1] - image diff --git a/skimage/util/tests/test_invert.py b/skimage/util/tests/test_invert.py new file mode 100644 index 00000000..ea8c7ab9 --- /dev/null +++ b/skimage/util/tests/test_invert.py @@ -0,0 +1,45 @@ +import numpy as np +from numpy.testing import assert_array_equal +from skimage import dtype_limits +from skimage.util import invert + + +def test_invert_bool(): + dtype = 'bool' + image = np.zeros((3, 3), dtype=dtype) + image[1, :] = dtype_limits(image)[1] + expected = np.zeros((3, 3), dtype=dtype) + dtype_limits(image)[1] + expected[1, :] = 0 + result = invert(image) + assert_array_equal(expected, result) + +def test_invert_uint8(): + dtype = 'uint8' + image = np.zeros((3, 3), dtype=dtype) + image[1, :] = dtype_limits(image)[1] + expected = np.zeros((3, 3), dtype=dtype) + dtype_limits(image)[1] + expected[1, :] = 0 + result = invert(image) + assert_array_equal(expected, result) + +def test_invert_bool(): + dtype = 'int8' + image = np.zeros((3, 3), dtype=dtype) + image[1, :] = dtype_limits(image)[1] + expected = np.zeros((3, 3), dtype=dtype) + dtype_limits(image)[1] + expected[1, :] = 0 + result = invert(image) + assert_array_equal(expected, result) + +def test_invert_bool(): + dtype = 'float64' + image = np.zeros((3, 3), dtype=dtype) + image[1, :] = dtype_limits(image)[1] + expected = np.zeros((3, 3), dtype=dtype) + dtype_limits(image)[1] + expected[1, :] = 0 + result = invert(image) + assert_array_equal(expected, result) + + +if __name__ == '__main__': + np.testing.run_module_suite() From 10293f889180eb1d8a68f0787a3051d13c4635ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Mon, 1 Aug 2016 11:46:05 +0200 Subject: [PATCH 3/5] Call invert() in doc --- doc/source/user_guide/transforming_image_data.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.rst b/doc/source/user_guide/transforming_image_data.rst index ac19178f..741cb229 100644 --- a/doc/source/user_guide/transforming_image_data.rst +++ b/doc/source/user_guide/transforming_image_data.rst @@ -88,10 +88,11 @@ An inverted image is also called complementary image. For binary images, True va become False and conversely. For grayscale images, pixel values are replaced by the difference of the maximum value of the data type and the actual value. For RGB images, the same operation is done for each channel. This operation can be achieved -with the negation operator ~ on any numpy array:: +with :py:func:`skimage.util.invert`:: + >>> from skimage import util >>> img = data.camera() - >>> inverted_img = ~img + >>> inverted_img = util.invert(img) Painting images with labels ~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 200f3980945a5decbfecc3f898078a6f1d8e8221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Mon, 1 Aug 2016 12:49:38 +0200 Subject: [PATCH 4/5] Fix tests --- skimage/util/invert.py | 4 ++-- skimage/util/tests/test_invert.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/skimage/util/invert.py b/skimage/util/invert.py index be0ddef2..f59bef29 100644 --- a/skimage/util/invert.py +++ b/skimage/util/invert.py @@ -20,8 +20,8 @@ def invert(image): Examples -------- >>> img = np.array([[100, 0, 200], - ... [0, 50, 0], - ... [30, 0, 255]], np.uint8) + ... [0, 50, 0], + ... [30, 0, 255]], np.uint8) >>> invert(img) array([[155, 255, 55], [255, 205, 255], diff --git a/skimage/util/tests/test_invert.py b/skimage/util/tests/test_invert.py index ea8c7ab9..9de26aa3 100644 --- a/skimage/util/tests/test_invert.py +++ b/skimage/util/tests/test_invert.py @@ -1,7 +1,7 @@ import numpy as np from numpy.testing import assert_array_equal from skimage import dtype_limits -from skimage.util import invert +from skimage.util.invert import invert def test_invert_bool(): @@ -13,6 +13,7 @@ def test_invert_bool(): result = invert(image) assert_array_equal(expected, result) + def test_invert_uint8(): dtype = 'uint8' image = np.zeros((3, 3), dtype=dtype) @@ -22,7 +23,8 @@ def test_invert_uint8(): result = invert(image) assert_array_equal(expected, result) -def test_invert_bool(): + +def test_invert_int8(): dtype = 'int8' image = np.zeros((3, 3), dtype=dtype) image[1, :] = dtype_limits(image)[1] @@ -31,7 +33,8 @@ def test_invert_bool(): result = invert(image) assert_array_equal(expected, result) -def test_invert_bool(): + +def test_invert_float64(): dtype = 'float64' image = np.zeros((3, 3), dtype=dtype) image[1, :] = dtype_limits(image)[1] From f47a1768467c48aa84730dc878130e801316c010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Boulogne?= Date: Tue, 2 Aug 2016 11:56:11 +0200 Subject: [PATCH 5/5] Rename invert.py to _invert.py --- skimage/util/__init__.py | 2 +- skimage/util/{invert.py => _invert.py} | 0 skimage/util/tests/test_invert.py | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename skimage/util/{invert.py => _invert.py} (100%) diff --git a/skimage/util/__init__.py b/skimage/util/__init__.py index 5aee7337..b64836f1 100644 --- a/skimage/util/__init__.py +++ b/skimage/util/__init__.py @@ -7,7 +7,7 @@ from .apply_parallel import apply_parallel from .arraypad import pad, crop from ._regular_grid import regular_grid from .unique import unique_rows -from .invert import invert +from ._invert import invert __all__ = ['img_as_float', diff --git a/skimage/util/invert.py b/skimage/util/_invert.py similarity index 100% rename from skimage/util/invert.py rename to skimage/util/_invert.py diff --git a/skimage/util/tests/test_invert.py b/skimage/util/tests/test_invert.py index 9de26aa3..5890d685 100644 --- a/skimage/util/tests/test_invert.py +++ b/skimage/util/tests/test_invert.py @@ -1,7 +1,7 @@ import numpy as np from numpy.testing import assert_array_equal from skimage import dtype_limits -from skimage.util.invert import invert +from skimage.util import invert def test_invert_bool():