Added tutorial for threshold in reST and fixed broken links from previous ImgProc...
[profile/ivi/opencv.git] / doc / tutorials / ImgProc / Threshold / Basic_Threshold.rst
1 .. _Basic_Threshold:
2
3 Basic Thresholding Operations
4 *******************************
5
6 Goal
7 =====
8
9 In this tutorial you will learn how to:
10
11 * Perform basic thresholding operations using OpenCV function :threshold:`threshold <>`
12
13
14 Cool Theory
15 ============
16
17 .. note::
18    The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
19
20 What is Thresholding?
21 -----------------------
22
23 * The simplest segmentation method
24
25 * Application example: Separate out regions of an image corresponding to objects which we want to analyze. This separation is based on the variation of intensity between the object pixels and the background pixels.
26
27 * To differentiate the pixels we are interested in from the rest (which will eventually be rejected), we perform a comparison of  each pixel intensity value with respect to a *threshold* (determined according to the problem to solve). 
28
29 * Once we have separated properly the important pixels, we can set them with a determined value to identify them (i.e. we can assign them a value of :math:`0` (black), :math:`255` (white) or any value  that suits your needs).
30
31   .. image:: images/Threshold_Tutorial_Theory_Example.png
32      :alt: Threshold simple example
33      :height: 150pt
34      :align: center 
35
36 Types of Thresholding
37 -----------------------
38
39 * OpenCV offers the function :threshold:`threshold <>` to perform thresholding operations. 
40
41 * We can effectuate :math:`5` types of Thresholding operations with this function. We will explain them in the following subsections.
42
43 * To illustrate how these thresholding processes work, let's consider that we have a source image with pixels with intensity values :math:`src(x,y)`. The plot below depicts this. The horizontal blue line represents the threshold :math:`thresh` (fixed).
44
45   .. image:: images/Threshold_Tutorial_Theory_Base_Figure.png
46      :alt: Threshold Binary
47      :height: 100pt
48      :align: center 
49
50 Threshold Binary
51 ^^^^^^^^^^^^^^^^^
52
53 * This thresholding operation can be expressed as:
54
55   .. math::
56          
57      \texttt{dst} (x,y) =  \fork{\texttt{maxVal}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}   
58  
59 * So, if the intensity of the pixel :math:`src(x,y)` is higher than :math:`thresh`, then the new pixel intensity is set to a :math:`MaxVal`. Otherwise, the pixels are set to :math:`0`.
60
61   .. image:: images/Threshold_Tutorial_Theory_Binary.png
62      :alt: Threshold Binary
63      :height: 100pt
64      :align: center 
65
66
67 Threshold Binary, Inverted
68 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
69
70 * This thresholding operation can be expressed as:
71                 
72   .. math::
73         
74      \texttt{dst} (x,y) =  \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{maxVal}}{otherwise}   
75
76 * If the intensity of the pixel :math:`src(x,y)` is higher than :math:`thresh`, then the new pixel intensity is set to a :math:`0`. Otherwise, it is set to :math:`MaxVal`.
77         
78   .. image:: images/Threshold_Tutorial_Theory_Binary_Inverted.png
79      :alt: Threshold Binary Inverted
80      :height: 100pt
81      :align: center 
82
83 Truncate
84 ^^^^^^^^^
85         
86 * This thresholding operation can be expressed as:
87                
88   .. math::
89         
90      \texttt{dst} (x,y) =  \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}   
91        
92 * The maximum intensity value for the pixels is :math:`thresh`, if :math:`src(x,y)` is greater, then its value is *truncated*. See figure below:
93  
94   .. image:: images/Threshold_Tutorial_Theory_Truncate.png
95      :alt: Threshold Truncate
96      :height: 100pt
97      :align: center 
98         
99
100
101 Threshold to Zero
102 ^^^^^^^^^^^^^^^^^^
103
104 * This operation can be expressed as:
105         
106    .. math::
107         
108       \texttt{dst} (x,y) =  \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}   
109
110 * If :math:`src(x,y)` is lower than :math:`thresh`, the new pixel value will be set to :math:`0`.
111
112   .. image:: images/Threshold_Tutorial_Theory_Zero.png
113      :alt: Threshold Zero
114      :height: 100pt
115      :align: center 
116
117
118 Threshold to Zero, Inverted
119 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120
121 * This operation can be expressed as:
122         
123    .. math::
124         
125       \texttt{dst} (x,y) =  \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}   
126
127 * If  :math:`src(x,y)` is greater than :math:`thresh`, the new pixel value will be set to :math:`0`.
128
129   .. image:: images/Threshold_Tutorial_Theory_Zero_Inverted.png
130      :alt: Threshold Zero Inverted
131      :height: 100pt
132      :align: center 
133
134
135 Code
136 ======
137
138 The tutorial code's is shown lines below. You can also download it from `here <https://code.ros.org/svn/opencv/trunk/opencv/samples/cpp/tutorial_code/ImgProc/Threshold.cpp>`_
139
140 .. code-block:: cpp 
141
142    #include "opencv2/imgproc/imgproc.hpp"
143    #include "opencv2/highgui/highgui.hpp"
144    #include <stdlib.h>
145    #include <stdio.h>
146
147    using namespace cv;
148
149    /// Global variables
150
151    int threshold_value = 0;
152    int threshold_type = 3;;
153    int const max_value = 255;
154    int const max_type = 4;
155    int const max_BINARY_value = 255;
156
157    Mat src, src_gray, dst;
158    char* window_name = "Threshold Demo";
159
160    char* trackbar_type = "Type: \n 0: Binary \n 1: Binary Inverted \n 2: Truncate \n 3: To Zero \n 4: To Zero Inverted";
161    char* trackbar_value = "Value";
162
163    /// Function headers
164    void Threshold_Demo( int, void* );
165
166    /**
167     * @function main
168     */
169    int main( int argc, char** argv )
170    {
171      /// Load an image
172      src = imread( argv[1], 1 );
173
174      /// Convert the image to Gray
175      cvtColor( src, src_gray, CV_RGB2GRAY );
176
177      /// Create a window to display results
178      namedWindow( window_name, CV_WINDOW_AUTOSIZE );
179
180      /// Create Trackbar to choose type of Threshold
181      createTrackbar( trackbar_type, 
182                      window_name, &threshold_type, 
183                      max_type, Threshold_Demo );
184
185      createTrackbar( trackbar_value,
186                      window_name, &threshold_value,
187                      max_value, Threshold_Demo );
188
189      /// Call the function to initialize
190      Threshold_Demo( 0, 0 );
191
192      /// Wait until user finishes program
193      while(true)
194      {
195        int c;
196        c = waitKey( 20 );
197        if( (char)c == 27 )
198          { break; }
199       }
200
201    }
202
203
204    /**
205     * @function Threshold_Demo
206     */
207    void Threshold_Demo( int, void* )
208    {
209      /* 0: Binary
210         1: Binary Inverted
211         2: Threshold Truncated
212         3: Threshold to Zero
213         4: Threshold to Zero Inverted
214       */
215
216      threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );
217
218      imshow( window_name, dst );
219    }
220
221
222
223 Explanation
224 =============
225
226
227 #. Let's check the general structure of the program:
228
229    * Load an image. If it is RGB we convert it to Grayscale. For this, remember that we can use the function :cvt_color:`cvtColor <>`:
230
231      .. code-block:: cpp
232
233         src = imread( argv[1], 1 );
234
235         /// Convert the image to Gray
236         cvtColor( src, src_gray, CV_RGB2GRAY );
237
238
239    * Create a window to display the result
240
241      .. code-block:: cpp
242
243         namedWindow( window_name, CV_WINDOW_AUTOSIZE );
244
245    * Create :math:`2` trackbars for the user to enter user input:
246
247      *  **Type of thresholding**: Binary, To Zero, etc...
248      *  **Threshold value**
249
250      .. code-block:: cpp
251
252         createTrackbar( trackbar_type, 
253                      window_name, &threshold_type, 
254                      max_type, Threshold_Demo );
255
256         createTrackbar( trackbar_value,
257                      window_name, &threshold_value,
258                      max_value, Threshold_Demo );
259
260    * Wait until the user enters the threshold value, the type of thresholding (or until the program exits)
261
262    * Whenever the user changes the value of any of the Trackbars, the function *Threshold_Demo* is called:
263
264      .. code-block:: cpp
265
266         /**
267          * @function Threshold_Demo
268          */
269         void Threshold_Demo( int, void* )
270         {
271           /* 0: Binary
272              1: Binary Inverted
273              2: Threshold Truncated
274              3: Threshold to Zero
275              4: Threshold to Zero Inverted
276            */
277
278           threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );
279
280           imshow( window_name, dst );
281         }
282
283      As you can see, the function :threshold:`threshold <>` is invoked. We give :math:`5` parameters:
284
285      * *src_gray*: Our input image
286      * *dst*: Destination (output) image
287      * *threshold_value*: The :math:`thresh` value with respect to which the thresholding operation is made
288      * *max_BINARY_value*: The value  used with the Binary thresholding operations (to set the chosen pixels)
289      * *threshold_type*: One of the :math:`5` thresholding operations. They are listed in the comment section of the function above.
290
291
292
293 Results
294 ========
295
296 #. After compiling this program, run it giving a path to an image as argument. For instance, for an input image as:
297
298
299    .. image:: images/Threshold_Tutorial_Original_Image.png
300       :alt: Threshold Original Image
301       :height: 200pt
302       :align: center 
303
304 #. First, we try to threshold our image with a *binary threhold inverted*. We expect that the pixels brighter than the :math:`thresh` will turn dark, which is what actually happens, as we can see in the snapshot below (notice from the original image, that the doggie's tongue and eyes are particularly bright in comparison with the image, this is reflected in the output image).
305
306
307    .. image:: images/Threshold_Tutorial_Result_Binary_Inverted.png
308       :alt: Threshold Result Binary Inverted
309       :height: 200pt
310       :align: center 
311
312
313 #. Now we try with the *threshold to zero*. With this, we expect that the darkest pixels (below the threshold) will become completely black, whereas the pixels with value greater than the threshold will keep its original value. This is verified by the following snapshot of the output image:
314
315    .. image:: images/Threshold_Tutorial_Result_Zero.png
316       :alt: Threshold Result Zero
317       :height: 200pt
318       :align: center 
319
320