============================================
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
<http://en.wikipedia.org/wiki/Color_space>`_. One of the most common
color spaces is the `RGB space
<http://en.wikipedia.org/wiki/RGB_color_model>`_, where an image has red,
green and blue channels. However, other color models are widely used,
such as the `HSV color model
<http://en.wikipedia.org/wiki/HSL_and_HSV>`_, where hue, saturation and
value are independent channels, or the `CMYK model
<http://en.wikipedia.org/wiki/CMYK_color_model>`_ used for printing. 

:mod:`skimage.color` provides utility functions to convert images
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)
    >>> 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 weighting of color channels, because of the
different sensitivity of the human eye to different colors. Therefore,
such a weighting ensures `luminance preservation
<http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale>`_
from RGB to grayscale::

    >>> 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: ../auto_examples/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 pixels can take values determined by the ``dtype`` of the 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,
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 `Gamma
correction <http://en.wikipedia.org/wiki/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]))

: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::
    
    >>> 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:: ../auto_examples/images/plot_equalize_1.png
   :target: ../auto_examples/plot_equalize.html
   :align: center
   :width: 90%


.. topic:: Examples:

  * :ref:`example_plot_equalize.py`


