From eae2196dd27479df1f435f6978b9227878003a77 Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Wed, 26 Nov 2014 22:59:49 +0100 Subject: [PATCH 1/5] First version of sections on color and exposure. --- doc/source/user_guide.txt | 1 + .../user_guide/transforming_image_data.txt | 179 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 doc/source/user_guide/transforming_image_data.txt diff --git a/doc/source/user_guide.txt b/doc/source/user_guide.txt index 338d9984..7be3e7a8 100644 --- a/doc/source/user_guide.txt +++ b/doc/source/user_guide.txt @@ -7,6 +7,7 @@ User Guide user_guide/getting_started user_guide/numpy_images user_guide/data_types + user_guide/transforming_image_data user_guide/plugins user_guide/tutorials user_guide/getting_help diff --git a/doc/source/user_guide/transforming_image_data.txt b/doc/source/user_guide/transforming_image_data.txt new file mode 100644 index 00000000..d247db3b --- /dev/null +++ b/doc/source/user_guide/transforming_image_data.txt @@ -0,0 +1,179 @@ +============================================ +Image adjustment: transforming image content +============================================ + +Color manipulation +------------------ + +.. currentmodule:: skimage.color + +Most functions for manipulating color channels are found in the submodule +:mod:`skimage.color`. + +Conversion between color models +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Color images can be represented using different `color spaces +`_. One of the most common +color spaces is the `RGB space +`_, where an image has +red, blue and green channels. However, other color models are widely +used, such as the `HSV color model +`_ (for hue, saturation and +value), where hue can be changed independently of saturation or value, or +the `CMYK model `_ used +for printing. + +:mod:`skimage.color` provide utility functions to convert images +to and from different color spaces. Note that such conversions may change +the numerical type of the image array:: + + >>> # bright saturated red + >>> red_pixel_rgb = np.array([[[255, 0, 0]]], dtype=np.uint8) + >>> color.rgb2hsv(red_pixel_rgb) + array([[[ 0., 1., 1.]]]) + >>> # darker saturated blue + >>> dark_blue_pixel_rgb = np.array([[[0, 0, 100]]], dtype=np.uint8) + >>> color.rgb2hsv(dark_blue_pixel_rgb) + array([[[ 0.66666667, 1. , 0.39215686]]]) + >>> # less saturated pink + >>> pink_pixel_rgb = np.array([[[255, 100, 255]]], dtype=np.uint8) + >>> color.rgb2hsv(pink_pixel_rgb) + array([[[ 0.83333333, 0.60784314, 1. ]]]) + + + +Conversion between color and gray values +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Converting an RGB image to a grayscale image is realized with +:func:`rgb2gray` :: + + >>> from skimage.color import rgb2gray + >>> from skimage import data + >>> img = data.astronaut() + >>> img_gray = rgb2gray(img) + +:func:`rgb2gray` uses a non-uniform weigthing of color channels, because of the +different sensivity of the human eye to different colors. :: + + >>> red_pixel = np.array([[[255, 0, 0]]], dtype=np.uint8) + >>> color.rgb2gray(red_pixel) + array([[ 0.2125]]) + >>> green_pixel = np.array([[[0, 255, 0]]], dtype=np.uint8) + >>> color.rgb2gray(green_pixel) + array([[ 0.7154]]) + + +Converting a grayscale image to RGB with :func:`gray2rgb``simply +duplicates the gray values over the three color channels. + +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. + + +.. image:: ../../_images/plot_join_segmentations_1.png + :target: ../auto_examples/plot_join_segmentations.html + :align: center + :width: 80% + + + +.. topic:: Examples: + + * :ref:`example_plot_tinting_grayscale_images.py` + * :ref:`example_plot_join_segmentations.py` + * :ref:`example_plot_rag_mean_color.py` + + +Contrast and exposure +--------------------- + +.. currentmodule:: skimage.exposure + +Image values can take values determined by the `dtype` of the image (see +:ref:`data_types`), such as 0 to 255 for `uint8` images or [-1, 1] for +floating point images. However, most images either have a narrower range +of values (because of poor contrast), or have most pixel values +concentrated in a subrange. :mod:`skimage.exposure` provides functions +that modify the distribution of pixels values of an image. + +A first class of methods compute a nonlinear function of the luminance, +which is always the same no matter the pixel values of a specific image. +Such methods are often used for correcting a known non-linearity of +sensors, or receptors such as the human eye. A known example is the +`Gamma correction `_, +implemented in :func:`adjust_gamma`. + +Other methods re-distribute pixel values according to the *histogram* of +the image. The histogram of pixel values is computed with +:func:`skimage.exposure.histogram`:: + + >>> image = np.array([[1, 3], [1, 1]]) + >>> exposure.histogram(image) + (array([3, 0, 1]), array([1, 2, 3])) + +that returns the number of pixels for each value bin, and the centers of +the bins. The behavior of :func:`histogram` is therefore slightly +different from the one of :func:`np.histogram`, that returns bins' +boundaries. + +The simplest contrast enhancement :func:`rescale_intensity` consists in +stretching pixels values to the whole allowed range, using a linear +transformation.:: + + >>> from skimage import exposure + >>> text = data.text() + >>> text.min(), text.max() + (10, 197) + >>> better_contrast = exposure.rescale_intensity(text) + >>> better_contrast.min(), better_contrast.max() + (0, 255) + +Even if an image uses the whole value range, sometimes there is very +little weight at the ends of the value range. In such a case, clipping +pixel values using percentiles of the image improves the contrast (at the +expense of some loss of information, because some pixels are saturated by +this operation).:: + + >>> moon = data.moon() + >>> v_min, v_max = np.percentile(moon, (0.2, 99.8)) + >>> v_min, v_max + (10.0, 186.0) + >>> better_contrast = exposure.rescale_intensity(moon, + ... in_range=(v_min, v_max)) + +The function :func:`equalize_hist` maps the cumulative distribution +function (cdf) of pixel values onto a linear cdf, ensuring that all parts +of the value range are equally represented in the image. As a result, +details are enhanced in large regions with poor contrast. As a further +refinement, histogram equalization can be performed in subregions of the +image with :func:`equalize_adapthist`, in order to correct for exposure +gradients across the image. See the example +:ref:`example_plot_equalize.py`. + +.. image:: ../../_images/plot_equalize_1.png + :target: ../auto_examples/plot_equalize.html + :align: center + :width: 90% + + +.. topic:: Examples: + + * :ref:`example_plot_equalize.py` + + +Image filtering +--------------- + +.. currentmodule:: skimage.filters + +Denoising and restoration +------------------------- + +Mathematical morphology +----------------------- From c0bedcf3ef32e17e73a8cde79a91ade30fb3aafa Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Sat, 6 Dec 2014 11:00:59 +0100 Subject: [PATCH 2/5] Minor corrections --- .../user_guide/transforming_image_data.txt | 31 +++++++------------ 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.txt b/doc/source/user_guide/transforming_image_data.txt index d247db3b..1e26b138 100644 --- a/doc/source/user_guide/transforming_image_data.txt +++ b/doc/source/user_guide/transforming_image_data.txt @@ -17,7 +17,7 @@ Color images can be represented using different `color spaces `_. One of the most common color spaces is the `RGB space `_, where an image has -red, blue and green channels. However, other color models are widely +red, green and blue channels. However, other color models are widely used, such as the `HSV color model `_ (for hue, saturation and value), where hue can be changed independently of saturation or value, or @@ -54,8 +54,8 @@ Converting an RGB image to a grayscale image is realized with >>> img = data.astronaut() >>> img_gray = rgb2gray(img) -:func:`rgb2gray` uses a non-uniform weigthing of color channels, because of the -different sensivity of the human eye to different colors. :: +:func:`rgb2gray` uses a non-uniform weighting of color channels, because of the +different sensitivity of the human eye to different colors. :: >>> red_pixel = np.array([[[255, 0, 0]]], dtype=np.uint8) >>> color.rgb2gray(red_pixel) @@ -95,14 +95,15 @@ Contrast and exposure .. currentmodule:: skimage.exposure -Image values can take values determined by the `dtype` of the image (see -:ref:`data_types`), such as 0 to 255 for `uint8` images or [-1, 1] for -floating point images. However, most images either have a narrower range -of values (because of poor contrast), or have most pixel values -concentrated in a subrange. :mod:`skimage.exposure` provides functions -that modify the distribution of pixels values of an image. +Image pixels can take values determined by the ``dtype`` of the image +(see :ref:`data_types`), such as 0 to 255 for ``uint8`` images or [-1, 1] +for floating-point images. However, most images either have a narrower +range of values (because of poor contrast), or have most pixel values +concentrated in a subrange of the accessible values. +:mod:`skimage.exposure` provides functions that modify the distribution +of pixels values of an image. -A first class of methods compute a nonlinear function of the luminance, +A first class of methods compute a nonlinear function of the intensity, which is always the same no matter the pixel values of a specific image. Such methods are often used for correcting a known non-linearity of sensors, or receptors such as the human eye. A known example is the @@ -167,13 +168,3 @@ gradients across the image. See the example * :ref:`example_plot_equalize.py` -Image filtering ---------------- - -.. currentmodule:: skimage.filters - -Denoising and restoration -------------------------- - -Mathematical morphology ------------------------ From d7023f1707a9a9481d96430f59634569c69a0c23 Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Sat, 13 Dec 2014 11:59:01 +0100 Subject: [PATCH 3/5] Enhancements to the text --- doc/source/user_guide/transforming_image_data.txt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.txt b/doc/source/user_guide/transforming_image_data.txt index 1e26b138..0a3f0957 100644 --- a/doc/source/user_guide/transforming_image_data.txt +++ b/doc/source/user_guide/transforming_image_data.txt @@ -24,7 +24,7 @@ value), where hue can be changed independently of saturation or value, or the `CMYK model `_ used for printing. -:mod:`skimage.color` provide utility functions to convert images +:mod:`skimage.color` provides utility functions to convert images to and from different color spaces. Note that such conversions may change the numerical type of the image array:: @@ -71,7 +71,7 @@ duplicates the gray values over the three color channels. Painting images with labels ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -:func:`label2rgb` can be used to superimpose colors on a grayscale image, +: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. @@ -104,9 +104,9 @@ concentrated in a subrange of the accessible values. of pixels values of an image. A first class of methods compute a nonlinear function of the intensity, -which is always the same no matter the pixel values of a specific image. +which is always the same, independent of the pixel values of a specific image. Such methods are often used for correcting a known non-linearity of -sensors, or receptors such as the human eye. A known example is the +sensors, or receptors such as the human eye. A well-known example is the `Gamma correction `_, implemented in :func:`adjust_gamma`. @@ -120,11 +120,11 @@ the image. The histogram of pixel values is computed with that returns the number of pixels for each value bin, and the centers of the bins. The behavior of :func:`histogram` is therefore slightly -different from the one of :func:`np.histogram`, that returns bins' -boundaries. +different from the one of :func:`np.histogram`, which returns the +boundaries of the bins. The simplest contrast enhancement :func:`rescale_intensity` consists in -stretching pixels values to the whole allowed range, using a linear +stretching pixel values to the whole allowed range, using a linear transformation.:: >>> from skimage import exposure From 7cb3071781d0579c8442bc2f1592e29e2d0dbdf7 Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Sun, 14 Dec 2014 23:27:57 +0100 Subject: [PATCH 4/5] Minor corrections --- .../user_guide/transforming_image_data.txt | 44 ++++++++++--------- 1 file changed, 23 insertions(+), 21 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.txt b/doc/source/user_guide/transforming_image_data.txt index 0a3f0957..a0ffc9d1 100644 --- a/doc/source/user_guide/transforming_image_data.txt +++ b/doc/source/user_guide/transforming_image_data.txt @@ -16,17 +16,16 @@ Conversion between color models Color images can be represented using different `color spaces `_. One of the most common color spaces is the `RGB space -`_, where an image has -red, green and blue channels. However, other color models are widely -used, such as the `HSV color model -`_ (for hue, saturation and -value), where hue can be changed independently of saturation or value, or -the `CMYK model `_ used -for printing. +`_, where an image has red, +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. :mod:`skimage.color` provides utility functions to convert images -to and from different color spaces. Note that such conversions may change -the numerical type of the image array:: +to and from different color spaces. Integer-type arrays can be +transformed to floating-point type by the conversion operation:: >>> # bright saturated red >>> red_pixel_rgb = np.array([[[255, 0, 0]]], dtype=np.uint8) @@ -55,7 +54,10 @@ Converting an RGB image to a grayscale image is realized with >>> img_gray = rgb2gray(img) :func:`rgb2gray` uses a non-uniform weighting of color channels, because of the -different sensitivity of the human eye to different colors. :: +different sensitivity of the human eye to different colors. Therefore, +such a weighting ensures `luminance preservation +`_ +from RGB to grayscale:: >>> red_pixel = np.array([[[255, 0, 0]]], dtype=np.uint8) >>> color.rgb2gray(red_pixel) @@ -96,19 +98,19 @@ Contrast and exposure .. currentmodule:: skimage.exposure Image pixels can take values determined by the ``dtype`` of the image -(see :ref:`data_types`), such as 0 to 255 for ``uint8`` images or [-1, 1] -for floating-point images. However, most images either have a narrower -range of values (because of poor contrast), or have most pixel values -concentrated in a subrange of the accessible values. -:mod:`skimage.exposure` provides functions that modify the distribution -of pixels values of an image. +(see :ref:`data_types`), such as 0 to 255 for ``uint8`` images or ``[0, +1]`` for floating-point images. However, most images either have a +narrower range of values (because of poor contrast), or have most pixel +values concentrated in a subrange of the accessible values. +:mod:`skimage.exposure` provides functions that spread the intensity +values over a larger range. A first class of methods compute a nonlinear function of the intensity, -which is always the same, independent of the pixel values of a specific image. -Such methods are often used for correcting a known non-linearity of -sensors, or receptors such as the human eye. A well-known example is the -`Gamma correction `_, -implemented in :func:`adjust_gamma`. +that is independent of the pixel values of a specific image. Such methods +are often used for correcting a known non-linearity of sensors, or +receptors such as the human eye. A well-known example is the `Gamma +correction `_, implemented +in :func:`adjust_gamma`. Other methods re-distribute pixel values according to the *histogram* of the image. The histogram of pixel values is computed with From 1a536905f1dd9f12f5b274d2578df729655f860d Mon Sep 17 00:00:00 2001 From: emmanuelle Date: Mon, 15 Dec 2014 21:45:02 +0100 Subject: [PATCH 5/5] Minor corrections --- .../user_guide/transforming_image_data.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/doc/source/user_guide/transforming_image_data.txt b/doc/source/user_guide/transforming_image_data.txt index a0ffc9d1..325017ff 100644 --- a/doc/source/user_guide/transforming_image_data.txt +++ b/doc/source/user_guide/transforming_image_data.txt @@ -108,7 +108,7 @@ values over a larger range. A first class of methods compute a nonlinear function of the intensity, that is independent of the pixel values of a specific image. Such methods are often used for correcting a known non-linearity of sensors, or -receptors such as the human eye. A well-known example is the `Gamma +receptors such as the human eye. A well-known example is `Gamma correction `_, implemented in :func:`adjust_gamma`. @@ -120,14 +120,14 @@ the image. The histogram of pixel values is computed with >>> exposure.histogram(image) (array([3, 0, 1]), array([1, 2, 3])) -that returns the number of pixels for each value bin, and the centers of -the bins. The behavior of :func:`histogram` is therefore slightly -different from the one of :func:`np.histogram`, which returns the -boundaries of the bins. +:func:`histogram` returns the number of pixels for each value bin, and +the centers of the bins. The behavior of :func:`histogram` is therefore +slightly different from the one of :func:`np.histogram`, which returns +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.:: +transformation:: >>> from skimage import exposure >>> text = data.text() @@ -141,14 +141,14 @@ Even if an image uses the whole value range, sometimes there is very little weight at the ends of the value range. In such a case, clipping pixel values using percentiles of the image improves the contrast (at the expense of some loss of information, because some pixels are saturated by -this operation).:: +this operation):: >>> moon = data.moon() >>> v_min, v_max = np.percentile(moon, (0.2, 99.8)) >>> v_min, v_max (10.0, 186.0) - >>> better_contrast = exposure.rescale_intensity(moon, - ... in_range=(v_min, v_max)) + >>> better_contrast = exposure.rescale_intensity( + ... moon, in_range=(v_min, v_max)) The function :func:`equalize_hist` maps the cumulative distribution function (cdf) of pixel values onto a linear cdf, ensuring that all parts