3 Basic Thresholding Operations
4 *******************************
9 In this tutorial you will learn how to:
11 * Perform basic thresholding operations using OpenCV function :threshold:`threshold <>`
18 The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
21 -----------------------
23 * The simplest segmentation method
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.
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).
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).
31 .. image:: images/Threshold_Tutorial_Theory_Example.png
32 :alt: Threshold simple example
37 -----------------------
39 * OpenCV offers the function :threshold:`threshold <>` to perform thresholding operations.
41 * We can effectuate :math:`5` types of Thresholding operations with this function. We will explain them in the following subsections.
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).
45 .. image:: images/Threshold_Tutorial_Theory_Base_Figure.png
46 :alt: Threshold Binary
53 * This thresholding operation can be expressed as:
57 \texttt{dst} (x,y) = \fork{\texttt{maxVal}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}
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`.
61 .. image:: images/Threshold_Tutorial_Theory_Binary.png
62 :alt: Threshold Binary
67 Threshold Binary, Inverted
68 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
70 * This thresholding operation can be expressed as:
74 \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{maxVal}}{otherwise}
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`.
78 .. image:: images/Threshold_Tutorial_Theory_Binary_Inverted.png
79 :alt: Threshold Binary Inverted
86 * This thresholding operation can be expressed as:
90 \texttt{dst} (x,y) = \fork{\texttt{threshold}}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}
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:
94 .. image:: images/Threshold_Tutorial_Theory_Truncate.png
95 :alt: Threshold Truncate
104 * This operation can be expressed as:
108 \texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if $\texttt{src}(x,y) > \texttt{thresh}$}{0}{otherwise}
110 * If :math:`src(x,y)` is lower than :math:`thresh`, the new pixel value will be set to :math:`0`.
112 .. image:: images/Threshold_Tutorial_Theory_Zero.png
118 Threshold to Zero, Inverted
119 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
121 * This operation can be expressed as:
125 \texttt{dst} (x,y) = \fork{0}{if $\texttt{src}(x,y) > \texttt{thresh}$}{\texttt{src}(x,y)}{otherwise}
127 * If :math:`src(x,y)` is greater than :math:`thresh`, the new pixel value will be set to :math:`0`.
129 .. image:: images/Threshold_Tutorial_Theory_Zero_Inverted.png
130 :alt: Threshold Zero Inverted
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>`_
142 #include "opencv2/imgproc/imgproc.hpp"
143 #include "opencv2/highgui/highgui.hpp"
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;
157 Mat src, src_gray, dst;
158 char* window_name = "Threshold Demo";
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";
164 void Threshold_Demo( int, void* );
169 int main( int argc, char** argv )
172 src = imread( argv[1], 1 );
174 /// Convert the image to Gray
175 cvtColor( src, src_gray, CV_RGB2GRAY );
177 /// Create a window to display results
178 namedWindow( window_name, CV_WINDOW_AUTOSIZE );
180 /// Create Trackbar to choose type of Threshold
181 createTrackbar( trackbar_type,
182 window_name, &threshold_type,
183 max_type, Threshold_Demo );
185 createTrackbar( trackbar_value,
186 window_name, &threshold_value,
187 max_value, Threshold_Demo );
189 /// Call the function to initialize
190 Threshold_Demo( 0, 0 );
192 /// Wait until user finishes program
205 * @function Threshold_Demo
207 void Threshold_Demo( int, void* )
211 2: Threshold Truncated
213 4: Threshold to Zero Inverted
216 threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );
218 imshow( window_name, dst );
227 #. Let's check the general structure of the program:
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 <>`:
233 src = imread( argv[1], 1 );
235 /// Convert the image to Gray
236 cvtColor( src, src_gray, CV_RGB2GRAY );
239 * Create a window to display the result
243 namedWindow( window_name, CV_WINDOW_AUTOSIZE );
245 * Create :math:`2` trackbars for the user to enter user input:
247 * **Type of thresholding**: Binary, To Zero, etc...
248 * **Threshold value**
252 createTrackbar( trackbar_type,
253 window_name, &threshold_type,
254 max_type, Threshold_Demo );
256 createTrackbar( trackbar_value,
257 window_name, &threshold_value,
258 max_value, Threshold_Demo );
260 * Wait until the user enters the threshold value, the type of thresholding (or until the program exits)
262 * Whenever the user changes the value of any of the Trackbars, the function *Threshold_Demo* is called:
267 * @function Threshold_Demo
269 void Threshold_Demo( int, void* )
273 2: Threshold Truncated
275 4: Threshold to Zero Inverted
278 threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type );
280 imshow( window_name, dst );
283 As you can see, the function :threshold:`threshold <>` is invoked. We give :math:`5` parameters:
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.
296 #. After compiling this program, run it giving a path to an image as argument. For instance, for an input image as:
299 .. image:: images/Threshold_Tutorial_Original_Image.png
300 :alt: Threshold Original Image
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).
307 .. image:: images/Threshold_Tutorial_Result_Binary_Inverted.png
308 :alt: Threshold Result Binary Inverted
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:
315 .. image:: images/Threshold_Tutorial_Result_Zero.png
316 :alt: Threshold Result Zero