Skip to content
Snippets Groups Projects
Commit 9968b385 authored by Antoine Regimbeau's avatar Antoine Regimbeau
Browse files

MRG: Merge branch 'contrast_enhancement' into release-6.4

parents 95913362 f0941c87
No related branches found
No related tags found
No related merge requests found
Documentation/Cookbook/Art/contrast1.png

56.1 KiB

Documentation/Cookbook/Art/contrast2.png

89.2 KiB

Documentation/Cookbook/Art/contrast4.png

15.3 KiB

Documentation/Cookbook/Art/contrast_orig.jpg

560 KiB

Documentation/Cookbook/Art/contrast_result.jpg

867 KiB

......@@ -13,7 +13,9 @@ and demonstrate how the can be applied.
recipes/sarprocessing.rst
recipes/residual_registration.rst
recipes/improc.rst
recipes/bandmathx.rst
recipes/contrast_enhancement.rst
recipes/pbclassif.rst
recipes/featextract.rst
recipes/stereo.rst
recipes/bandmathx.rst
Enhance local contrast
======================
Principles
~~~~~~~~~~
Sensor images have often a wide dynamic range. Whereas it is helpful to have
high precision to do complex processing, it is pretty hard to display high
dynamic images, even on modern screen as the dynamic range for basic screen is
of 8 bits while images can be encoded on 12 or 16 bits (or even more!).
.. _Figure1:
|image5| |image6|
The *ContrastEnhancement* application aims to reduce the image dynamic by
reorganizing it in a smarter way than just linear compression and improve the
local contrast and enhance the definitions of edges.
.. _Figure2:
|image1| |image2|
The equalization of histogram creates a look up table in order to maximize the
dynamic. The target histogram is perfectly flat. The gain applied on each pixel
comes from the computation of the transfer function :math:`T` such that :
.. math:: \forall i \quad \int_{min}^{i*T(i)}h_{istogram}(j)dj =
\int_{min}^{i}h_{target}(j)dj
where :math:`h_{target}` is the corresponding flat histogram with the constraint
that white and black are still white and black after equalization :
.. math:: T(min) = T(max) = 1
You can apply this transformation with the *ContrastEnhancement* application:
::
otbcli_ContrastEnhancement -in input_image.tif
-out output_image.tif
-spatial global
It allows to compress the dynamic without loosing details and contrast.
Advanced parameters
~~~~~~~~~~~~~~~~~~~
The *ContrastEnhancement* provides different options to configure the contrast
enhancement method. Let us see what there are for.
First what you want to equalize. Two modes are available:
* **luminance:** on 3 bands image, the equalization will be done on a single
band which will be a composition of the original bands. The computed gain will
then be applied on the different bands. The classical use of this method is to
conserve ratio between the different color, conserve the hue.
* **channel:** each bands are equalized independently.
The other option is the local equalization. You can choose a window size that
will be use to split the image in tiles and histograms will be computed over
those tiles. Gain will be interpolated between the adjacent tiles in order to
give a smooth result.
::
otbcli_ContrastEnhancement -in input_image.tif
-out output_image.tif spatial.local.h 500
-spatial.local.w 500
-mode lum
The *ContrastEnhancement* application also offers a way to limit contrast by
adjusting original histogram with the **hfact** parameter. The limitation factor
represents the limit height that can have any bucket of the histogram; the
application computes the height of the flat histogram and the maximal height is
the limitation factor time this "flat height".
.. _Figure3:
|image4|
Finally, you can ignore a particular value with the **nodata** parameter, and
also set manually your minimum and maximum value. Any value out of bound will be
ignored.
.. |image1| image:: ../Art/contrast1.png
:scale: 30%
.. |image2| image:: ../Art/contrast2.png
:scale: 30%
.. |image4| image:: ../Art/contrast4.png
.. |image5| image:: ../Art/contrast_orig.jpg
:scale: 30%
:alt: original
.. |image6| image:: ../Art/contrast_result.jpg
:scale: 30%
:alt: result
......@@ -68,7 +68,7 @@ public:
} // end operator ()
void SetRgb( std::vector<int> rgb)
void SetRgb( std::vector<unsigned int> rgb)
{
m_Rgb = rgb;
}
......@@ -82,7 +82,7 @@ public:
return m_LumCoef;
}
private:
std::vector<int> m_Rgb;
std::vector<unsigned int> m_Rgb;
std::vector<float> m_LumCoef;
}; // end of functor class MultiplyOperator
......@@ -383,10 +383,17 @@ private:
}
else if ( m_EqMode == "lum")
{
std::vector<int> rgb( 3 , 0 );
std::vector< unsigned int > rgb( 3 , 0 );
rgb[0] = GetParameterInt("mode.lum.red.ch");
rgb[1] = GetParameterInt("mode.lum.green.ch");
rgb[2] = GetParameterInt("mode.lum.blue.ch");
if ( !( nbChannel > std::max( rgb[0] , std::max( rgb[1] , rgb[2] ) ) ) )
{
std::ostringstream oss;
oss<<"One of the selected channel needed for luminance computation "
"exceed the number of component of the image.";
otbAppLogFATAL( << oss.str() )
}
ComputeLuminance( inImage , rgb );
LuminanceEqualization( inputImageList , rgb , outputImageList );
}
......@@ -695,7 +702,7 @@ private:
// Compute the luminance with user parameters
void ComputeLuminance( const FloatVectorImageType::Pointer inImage ,
std::vector < int > rgb )
std::vector < unsigned int > rgb )
{
// Retreive coeffs for each channel
std::vector < float > lumCoef( 3 , 0.0 );
......@@ -719,7 +726,7 @@ private:
// Equalize the luminance and apply the corresponding gain on each channel
// used to compute this luminance
void LuminanceEqualization( const ImageListType::Pointer inputImageList ,
const std::vector < int > rgb ,
const std::vector < unsigned int > rgb ,
ImageListType::Pointer outputImageList )
{
m_GainLutFilter.resize( 1 , GainLutFilterType::New() );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment