/**

\page tutorial-imgproc-contrast-sharpening Tutorial: Contrast and image sharpening techniques
\tableofcontents

\section imgproc_contrast_sharpening_intro Introduction

While the ViSP library is not intended to be an image processing library or replace a raster graphics editor, some easy image processing techniques can be used to improve the contrast and the sharpness of an image.

The different methods presented are:
- histogram stretching, see the corresponding <a href="https://docs.gimp.org/en/plug-in-c-astretch.html">Gimp documentation</a>.
- histogram stretching in the HSV color space, see the corresponding <a href="https://docs.gimp.org/en/plug-in-autostretch-hsv.html">Gimp documentation</a>.
- histogram equalization, see the corresponding <a href="https://en.wikipedia.org/wiki/Histogram_equalization">Wikipedia entry</a>.
- contrast limited adaptive histogram equalization (CLAHE), see the corresponding <a href="https://en.wikipedia.org/wiki/Adaptive_histogram_equalization#Contrast_Limited_AHE">Wikipedia entry</a>.
- unsharp masking, an image sharpening technique, see the corresponding <a href="https://en.wikipedia.org/wiki/Unsharp_masking">Wikipedia entry</a>.

The first two methods consist of stretching the histogram of an image to make it use the entire range of values. It is more or less similar to the histogram equalization technique (presented in \ref imgproc_brightness_histogram_equalization).
The stretching will act like a direct mapping between the old and new intensity values whereas the histogram equalization will linearize the cumulative histogram distribution to try to make each intensity values the same weighting in the image.
The CLAHE algorithm will limit the contrast enhancement using a maximum slope value to avoid to amplify too much the image noise. It will also compute the cumulative histogram locally by sliding a window around the current pixel location.

\section imgproc_contrast_sharpening_example Example code

The following example also available in tutorial-contrast-sharpening.cpp will show the result of each of these methods on a low contrast image.

\include tutorial-contrast-sharpening.cpp

These functions are provided in a \a vp:: namespace and accessible using this include:

\snippet tutorial-contrast-sharpening.cpp Include

The first step is to read the input image:

\snippet tutorial-contrast-sharpening.cpp Read

The low contrast color image used in this tutorial can be downloaded <a href="https://upload.wikimedia.org/wikipedia/commons/f/fd/Crayfish_low_contrast.JPG">here</a> (By Biem (Own work) [Public domain], via Wikimedia Commons):

\image html img-tutorial-contrast-sharpening-Crayfish-low-contrast.png "Input low contrast color image"

The figure below represents the histogram and the cumulative histogram of the low contrast image. Most of the histogram bins are approximately in the [80 - 140] range, resulting in an image with low dynamic.

\image html img-tutorial-contrast-sharpening-Crayfish-low-contrast-hist.png "Histogram and cumulative histogram of the input image"

The histogram stretching can be done with:

\snippet tutorial-contrast-sharpening.cpp Stretch contrast

The result is:

\image html img-tutorial-contrast-sharpening-histogram-stretching.png "Histogram stretching"

The corresponding histogram and cumulative histogram are the following:

\image html img-tutorial-contrast-sharpening-histogram-stretching-hist.png "Histogram and cumulative histogram of the stretched histogram image"

This method stretches the histogram with a direct mapping between the old and the new intensity values. The histogram bins are more spread out and the image gains some dynamic. It will not change the intensity distribution as the histogram equalization method could do.

The histogram stretching on HSV colorspace can be done with:

\snippet tutorial-contrast-sharpening.cpp Stretch contrast HSV

\image html img-tutorial-contrast-sharpening-histogram-stretching-HSV.png "Histogram stretching on HSV colorspace"

The main difference is that this method will stretch the Saturation and Value components and preserve the Hue channel.

From the Gimp documentation:
<blockquote>
it works in HSV color space, rather than RGB color space, and it preserves the Hue. Thus, it independently stretches the ranges of the Hue, Saturation and Value components of the colors. Occasionally the results are good, often they are a bit odd.
</blockquote>

\image html img-tutorial-contrast-sharpening-histogram-stretching-HSV-hist.png "Histogram and cumulative histogram of the stretched histogram image in HSV colorspace"

The histogram and cumulative histogram are similar to the previous method as expected.

To improve the image contrast using the histogram equalization method:

\snippet tutorial-contrast-sharpening.cpp Histogram equalization

The result is:

\image html img-tutorial-contrast-sharpening-histogram-equalization.png "Histogram equalization"

If we look at the histogram and the cumulative histogram:

\image html img-tutorial-contrast-sharpening-histogram-equalization-hist.png "Histogram and cumulative histogram of the histogram equalized image"

The cumulative histogram is more linear which can be related to a more equal distribution of the pixel intensities in the image.

To use the CLAHE algorithm:

\snippet tutorial-contrast-sharpening.cpp CLAHE

The CLAHE method avoid the over amplification of the noise compared to the histogram equalization method:

\image html img-tutorial-contrast-sharpening-CLAHE.png "Contrast limited adaptive histogram equalization (blockRadius=150, bins=256, slope=3)"

The parameters are:
- the block radius: the size (2*blockRadius+1) of the neighborhood to consider around the current pixel location
- the number of bins for the histogram computation
- the maximum slope to limit the contrast enhancement

The histogram of the corrected image is stretched and the local processing plus the limitation of the contrast enhancement avoid the over boosting of the contrast as in the histogram equalization case.

\image html img-tutorial-contrast-sharpening-CLAHE-hist.png "Histogram and cumulative histogram after using the CLAHE method"

The unsharp masking will sharpen the edges in an image:

\snippet tutorial-contrast-sharpening.cpp Unsharp mask

It is applied here on the image after using the CLAHE algorithm:

\image html img-tutorial-contrast-sharpening-unsharp-masking.png "Unsharp masking (weight=0.5, Gaussian blur size=11) on the processed image after CLAHE"

Two parameters can be modified:
- the size of the Gaussian kernel, see vpImageFilter::gaussianBlur(const vpImage<double> &, vpImage<double> &, unsigned int, double, bool)
- the unsharp masking weighting: \f$ I_{sharpen} = \frac{\left( I_{original} - weight \times I_{blurred} \right)}{\left( 1 - weight \right)} \f$

To summarize, the techniques presented to improve the contrast of an image can do a good job in some situations and not in another.
The CLAHE algorithm and the unsharp masking can be tuned (but the default values should be good enough in most of the situation).

\section imgproc_contrast_sharpening_next Next tutorial

You can now read the \ref tutorial-imgproc-autothreshold, to learn how to automatically threshold / binarise a grayscale image.

*/
