1 Basic Thresholding Operations {#tutorial_threshold} 2 ============================= 3 4 Goal 5 ---- 6 7 In this tutorial you will learn how to: 8 9 - Perform basic thresholding operations using OpenCV function @ref cv::threshold 10 11 Cool Theory 12 ----------- 13 14 @note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler. What is 15 16 Thresholding? 17 ------------- 18 19 - The simplest segmentation method 20 - Application example: Separate out regions of an image corresponding to objects which we want to 21 analyze. This separation is based on the variation of intensity between the object pixels and 22 the background pixels. 23 - To differentiate the pixels we are interested in from the rest (which will eventually be 24 rejected), we perform a comparison of each pixel intensity value with respect to a *threshold* 25 (determined according to the problem to solve). 26 - Once we have separated properly the important pixels, we can set them with a determined value to 27 identify them (i.e. we can assign them a value of \f$0\f$ (black), \f$255\f$ (white) or any value that 28 suits your needs). 29 30 ![](images/Threshold_Tutorial_Theory_Example.jpg) 31 32 ### Types of Thresholding 33 34 - OpenCV offers the function @ref cv::threshold to perform thresholding operations. 35 - We can effectuate \f$5\f$ types of Thresholding operations with this function. We will explain them 36 in the following subsections. 37 - To illustrate how these thresholding processes work, let's consider that we have a source image 38 with pixels with intensity values \f$src(x,y)\f$. The plot below depicts this. The horizontal blue 39 line represents the threshold \f$thresh\f$ (fixed). 40 41 ![](images/Threshold_Tutorial_Theory_Base_Figure.png) 42 43 #### Threshold Binary 44 45 - This thresholding operation can be expressed as: 46 47 \f[\texttt{dst} (x,y) = \fork{\texttt{maxVal}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] 48 49 - So, if the intensity of the pixel \f$src(x,y)\f$ is higher than \f$thresh\f$, then the new pixel 50 intensity is set to a \f$MaxVal\f$. Otherwise, the pixels are set to \f$0\f$. 51 52 ![](images/Threshold_Tutorial_Theory_Binary.png) 53 54 #### Threshold Binary, Inverted 55 56 - This thresholding operation can be expressed as: 57 58 \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{maxVal}}{otherwise}\f] 59 60 - If the intensity of the pixel \f$src(x,y)\f$ is higher than \f$thresh\f$, then the new pixel intensity 61 is set to a \f$0\f$. Otherwise, it is set to \f$MaxVal\f$. 62 63 ![](images/Threshold_Tutorial_Theory_Binary_Inverted.png) 64 65 #### Truncate 66 67 - This thresholding operation can be expressed as: 68 69 \f[\texttt{dst} (x,y) = \fork{\texttt{threshold}}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] 70 71 - The maximum intensity value for the pixels is \f$thresh\f$, if \f$src(x,y)\f$ is greater, then its value 72 is *truncated*. See figure below: 73 74 ![](images/Threshold_Tutorial_Theory_Truncate.png) 75 76 #### Threshold to Zero 77 78 - This operation can be expressed as: 79 80 \f[\texttt{dst} (x,y) = \fork{\texttt{src}(x,y)}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{0}{otherwise}\f] 81 82 - If \f$src(x,y)\f$ is lower than \f$thresh\f$, the new pixel value will be set to \f$0\f$. 83 84 ![](images/Threshold_Tutorial_Theory_Zero.png) 85 86 #### Threshold to Zero, Inverted 87 88 - This operation can be expressed as: 89 90 \f[\texttt{dst} (x,y) = \fork{0}{if \(\texttt{src}(x,y) > \texttt{thresh}\)}{\texttt{src}(x,y)}{otherwise}\f] 91 92 - If \f$src(x,y)\f$ is greater than \f$thresh\f$, the new pixel value will be set to \f$0\f$. 93 94 ![](images/Threshold_Tutorial_Theory_Zero_Inverted.png) 95 96 Code 97 ---- 98 99 The tutorial code's is shown lines below. You can also download it from 100 [here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Threshold.cpp) 101 @include samples/cpp/tutorial_code/ImgProc/Threshold.cpp 102 103 Explanation 104 ----------- 105 106 -# Let's check the general structure of the program: 107 - Load an image. If it is BGR we convert it to Grayscale. For this, remember that we can use 108 the function @ref cv::cvtColor : 109 @code{.cpp} 110 src = imread( argv[1], 1 ); 111 112 /// Convert the image to Gray 113 cvtColor( src, src_gray, COLOR_BGR2GRAY ); 114 @endcode 115 - Create a window to display the result 116 @code{.cpp} 117 namedWindow( window_name, WINDOW_AUTOSIZE ); 118 @endcode 119 - Create \f$2\f$ trackbars for the user to enter user input: 120 121 - **Type of thresholding**: Binary, To Zero, etc... 122 - **Threshold value** 123 @code{.cpp} 124 createTrackbar( trackbar_type, 125 window_name, &threshold_type, 126 max_type, Threshold_Demo ); 127 128 createTrackbar( trackbar_value, 129 window_name, &threshold_value, 130 max_value, Threshold_Demo ); 131 @endcode 132 - Wait until the user enters the threshold value, the type of thresholding (or until the 133 program exits) 134 - Whenever the user changes the value of any of the Trackbars, the function *Threshold_Demo* 135 is called: 136 @code{.cpp} 137 /* 138 * @function Threshold_Demo 139 */ 140 void Threshold_Demo( int, void* ) 141 { 142 /* 0: Binary 143 1: Binary Inverted 144 2: Threshold Truncated 145 3: Threshold to Zero 146 4: Threshold to Zero Inverted 147 */ 148 149 threshold( src_gray, dst, threshold_value, max_BINARY_value,threshold_type ); 150 151 imshow( window_name, dst ); 152 } 153 @endcode 154 As you can see, the function @ref cv::threshold is invoked. We give \f$5\f$ parameters: 155 156 - *src_gray*: Our input image 157 - *dst*: Destination (output) image 158 - *threshold_value*: The \f$thresh\f$ value with respect to which the thresholding operation 159 is made 160 - *max_BINARY_value*: The value used with the Binary thresholding operations (to set the 161 chosen pixels) 162 - *threshold_type*: One of the \f$5\f$ thresholding operations. They are listed in the 163 comment section of the function above. 164 165 Results 166 ------- 167 168 -# After compiling this program, run it giving a path to an image as argument. For instance, for an 169 input image as: 170 171 ![](images/Threshold_Tutorial_Original_Image.jpg) 172 173 -# First, we try to threshold our image with a *binary threhold inverted*. We expect that the 174 pixels brighter than the \f$thresh\f$ will turn dark, which is what actually happens, as we can see 175 in the snapshot below (notice from the original image, that the doggie's tongue and eyes are 176 particularly bright in comparison with the image, this is reflected in the output image). 177 178 ![](images/Threshold_Tutorial_Result_Binary_Inverted.jpg) 179 180 -# Now we try with the *threshold to zero*. With this, we expect that the darkest pixels (below the 181 threshold) will become completely black, whereas the pixels with value greater than the 182 threshold will keep its original value. This is verified by the following snapshot of the output 183 image: 184 185 ![](images/Threshold_Tutorial_Result_Zero.jpg) 186