============================================ 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, 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. :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 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) 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 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 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 `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`