File: histogram_equalization.rst

package info (click to toggle)
opencv 2.4.9.1%2Bdfsg-1%2Bdeb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 126,800 kB
  • ctags: 62,729
  • sloc: xml: 509,055; cpp: 490,794; lisp: 23,208; python: 21,174; java: 19,317; ansic: 1,038; sh: 128; makefile: 72
file content (217 lines) | stat: -rw-r--r-- 6,198 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
.. _histogram_equalization:

Histogram Equalization
**********************

Goal
====

In this tutorial you will learn:

.. container:: enumeratevisibleitemswithsquare

   * What an image histogram is and why it is useful

   * To equalize histograms of images by using the OpenCV function:equalize_hist:`equalizeHist <>`



Theory
======

What is an Image Histogram?
---------------------------

.. container:: enumeratevisibleitemswithsquare

   * It is a graphical representation of the intensity distribution of an image.

   * It quantifies the number of pixels for each intensity value considered.

.. image:: images/Histogram_Equalization_Theory_0.jpg
        :align: center


What is Histogram Equalization?
-------------------------------

.. container:: enumeratevisibleitemswithsquare

   * It is a method that improves the contrast in an image, in order to stretch out the intensity range.

   * To make it clearer, from the image above, you can see that the pixels seem clustered around the middle of the available range of intensities. What Histogram Equalization does is to *stretch out* this range. Take a look at the figure below: The green circles indicate the *underpopulated* intensities. After applying the equalization, we get an histogram like the figure in the center. The resulting image is shown in the picture at right.

.. image:: images/Histogram_Equalization_Theory_1.jpg
          :align: center

How does it work?
-----------------

.. container:: enumeratevisibleitemswithsquare

   * Equalization implies *mapping* one distribution (the given histogram) to another distribution (a wider and more uniform distribution of intensity values) so the intensity values are spreaded over the whole range.

   * To accomplish the equalization effect, the remapping should be the *cumulative distribution function (cdf)* (more details, refer to *Learning OpenCV*). For the histogram :math:`H(i)`, its *cumulative distribution* :math:`H^{'}(i)` is:

     .. math::

        H^{'}(i) = \sum_{0 \le j < i} H(j)

     To use this as a remapping function, we have to normalize :math:`H^{'}(i)` such that the maximum value is 255 ( or the maximum value for the intensity of the image ). From the example above, the cumulative function is:

     .. image:: images/Histogram_Equalization_Theory_2.jpg
              :align: center

   * Finally, we use a simple remapping procedure to obtain the intensity values of the equalized image:

     .. math::

        equalized( x, y ) = H^{'}( src(x,y) )

Code
====

.. container:: enumeratevisibleitemswithsquare

   * **What does this program do?**

     .. container:: enumeratevisibleitemswithsquare

        * Loads an image
        * Convert the original image to grayscale
        * Equalize the Histogram by using the OpenCV function :equalize_hist:`EqualizeHist <>`
        * Display the source and equalized images in a window.

   * **Downloadable code**:
     Click `here <https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/Histograms_Matching/EqualizeHist_Demo.cpp>`_

   * **Code at glance:**

.. code-block:: cpp

   #include "opencv2/highgui/highgui.hpp"
   #include "opencv2/imgproc/imgproc.hpp"
   #include <iostream>
   #include <stdio.h>

   using namespace cv;
   using namespace std;

   /**  @function main */
   int main( int argc, char** argv )
   {
     Mat src, dst;

     char* source_window = "Source image";
     char* equalized_window = "Equalized Image";

     /// Load image
     src = imread( argv[1], 1 );

     if( !src.data )
       { cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;
         return -1;}

     /// Convert to grayscale
     cvtColor( src, src, CV_BGR2GRAY );

     /// Apply Histogram Equalization
     equalizeHist( src, dst );

     /// Display results
     namedWindow( source_window, CV_WINDOW_AUTOSIZE );
     namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

     imshow( source_window, src );
     imshow( equalized_window, dst );

     /// Wait until user exits the program
     waitKey(0);

     return 0;
   }

Explanation
===========

#. Declare the source and destination images as well as the windows names:

   .. code-block:: cpp

      Mat src, dst;

      char* source_window = "Source image";
      char* equalized_window = "Equalized Image";

#. Load the source image:

   .. code-block:: cpp

      src = imread( argv[1], 1 );

      if( !src.data )
        { cout<<"Usage: ./Histogram_Demo <path_to_image>"<<endl;
          return -1;}

#. Convert it to grayscale:

   ..  code-block:: cpp

       cvtColor( src, src, CV_BGR2GRAY );

#. Apply histogram equalization with the function :equalize_hist:`equalizeHist <>` :

   .. code-block:: cpp

      equalizeHist( src, dst );

   As it can  be easily seen, the only arguments are the original image and the output (equalized) image.

#. Display both images (original and equalized) :

   .. code-block::  cpp

      namedWindow( source_window, CV_WINDOW_AUTOSIZE );
      namedWindow( equalized_window, CV_WINDOW_AUTOSIZE );

      imshow( source_window, src );
      imshow( equalized_window, dst );

#. Wait until user exists the program

   .. code-block:: cpp

      waitKey(0);
      return 0;


Results
=======

#. To appreciate better the results of equalization, let's introduce an image with not much contrast, such as:

   .. image:: images/Histogram_Equalization_Original_Image.jpg
            :align: center

   which, by the way, has this histogram:

   .. image:: images/Histogram_Equalization_Original_Histogram.jpg
            :align: center

   notice that the pixels are clustered around the center of the histogram.

#. After applying the equalization with our program, we get this result:

   .. image:: images/Histogram_Equalization_Equalized_Image.jpg
            :align: center

   this image has certainly more contrast. Check out its new histogram like this:

   .. image:: images/Histogram_Equalization_Equalized_Histogram.jpg
            :align: center

   Notice how the number of pixels is more distributed through the intensity range.


.. note::
   Are you wondering how did we draw the Histogram figures shown above? Check out the following tutorial!