Added tutorial for threshold in reST and fixed broken links from previous ImgProc...
[profile/ivi/opencv.git] / doc / tutorials / ImgProc / Morphology_2 / Morphology_2.rst
1 .. _Morphology_2:
2
3 More Morphology Transformations
4 *********************************
5
6 Goal
7 =====
8
9 In this tutorial you will learn how to:
10
11 * Use the OpenCV function :morphology_ex:`morphologyEx <>` to apply Morphological Transformation such as:
12   
13   * Opening 
14   * Closing
15   * Morphological Gradient
16   * Top Hat
17   * Black Hat
18
19 Cool Theory
20 ============
21
22 .. note::
23    The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
24
25 In the previous tutorial we covered two basic Morphology operations: 
26
27 * Erosion
28
29 * Dilation. 
30
31 Based on these two we can effectuate more sophisticated transformations to our images. Here we discuss briefly 05 operations offered by OpenCV:
32
33 Opening
34 ---------
35
36 * It is obtained by the erosion of an image followed by a dilation.
37
38   .. math::
39      
40      dst = open( src, element) = dilate( erode( src, element ) )
41
42 * Useful for removing small objects (it is assumed that the objects are bright on a dark foreground)
43
44 * For instance, check out the example below. The image at the left is the original and the image at the right is the result after applying the opening transformation. We can observe that the small spaces in the corners of the letter tend to dissapear.
45
46   .. image:: images/Morphology_2_Tutorial_Theory_Opening.png
47      :height: 150pt
48      :alt: Opening
49      :align: center  
50
51 Closing
52 ---------
53
54 * It is obtained by the dilation of an image followed by an erosion.
55
56   .. math::
57     
58      dst = close( src, element ) = erode( dilate( src, element ) )
59
60 * Useful to remove small holes (dark regions). 
61
62   .. image:: images/Morphology_2_Tutorial_Theory_Closing.png
63      :height: 150pt
64      :alt: Closing example
65      :align: center  
66
67
68 Morphological Gradient
69 ------------------------
70
71 * It is the difference between the dilation and the erosion of an image.
72
73   .. math::
74
75      dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element )
76
77 * It is useful for finding the outline of an object as can be seen below:
78
79   .. image:: images/Morphology_2_Tutorial_Theory_Gradient.png
80      :height: 150pt
81      :alt: Gradient
82      :align: center  
83
84
85 Top Hat
86 ---------
87
88 * It is the difference between an input image and its opening.
89
90   .. math::
91    
92      dst = tophat( src, element ) = src - open( src, element )
93
94   .. image:: images/Morphology_2_Tutorial_Theory_TopHat.png
95      :height: 150pt
96      :alt: Top Hat
97      :align: center  
98
99 Black Hat
100 ----------
101
102 * It is the difference between the closing and its input image
103
104   .. math::
105  
106      dst = blackhat( src, element ) = close( src, element ) - src
107
108   .. image:: images/Morphology_2_Tutorial_Theory_BlackHat.png
109      :height: 150pt
110      :alt: Black Hat
111      :align: center    
112
113 Code
114 ======
115
116 This 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/Morphology_2.cpp>`_
117
118 .. code-block:: cpp 
119
120    #include "opencv2/imgproc/imgproc.hpp"
121    #include "opencv2/highgui/highgui.hpp"
122    #include <stdlib.h>
123    #include <stdio.h>
124
125    using namespace cv;
126
127    /// Global variables
128    Mat src, dst;
129
130    int morph_elem = 0;
131    int morph_size = 0;
132    int morph_operator = 0;
133    int const max_operator = 4;
134    int const max_elem = 2;
135    int const max_kernel_size = 21;
136
137    char* window_name = "Morphology Transformations Demo";
138
139    /** Function Headers */
140    void Morphology_Operations( int, void* );
141
142    /** @function main */
143    int main( int argc, char** argv )
144    {
145      /// Load an image
146      src = imread( argv[1] );
147
148      if( !src.data )
149      { return -1; }
150     
151     /// Create window
152     namedWindow( window_name, CV_WINDOW_AUTOSIZE );
153
154     /// Create Trackbar to select Morphology operation
155     createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", window_name, &morph_operator, max_operator, Morphology_Operations );
156
157     /// Create Trackbar to select kernel type
158     createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name, 
159                     &morph_elem, max_elem, 
160                     Morphology_Operations );
161
162     /// Create Trackbar to choose kernel size
163     createTrackbar( "Kernel size:\n 2n +1", window_name, 
164                     &morph_size, max_kernel_size,
165                     Morphology_Operations );
166
167     /// Default start
168     Morphology_Operations( 0, 0 );
169
170     waitKey(0);
171     return 0;
172     }
173
174     /** 
175      * @function Morphology_Operations
176      */
177    void Morphology_Operations( int, void* )
178    {
179      // Since MORPH_X : 2,3,4,5 and 6
180      int operation = morph_operator + 2;
181
182      Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) ); 
183
184      /// Apply the specified morphology operation
185      morphologyEx( src, dst, operation, element );
186      imshow( window_name, dst );  
187      }
188
189
190 Explanation
191 =============
192
193 #. Let's check the general structure of the program:
194
195    * Load an image
196
197    * Create a window to display results of the Morphological operations
198
199    * Create 03 Trackbars for the user to enter parameters:
200
201      * The first trackbar **"Operator"** returns the kind of morphology operation to use (**morph_operator**).
202
203        .. code-block:: cpp
204
205           createTrackbar("Operator:\n 0: Opening - 1: Closing \n 2: Gradient - 3: Top Hat \n 4: Black Hat", 
206                          window_name, &morph_operator, max_operator, 
207                          Morphology_Operations );
208
209
210
211      * The second trackbar **"Element"** returns **morph_elem**, which indicates what kind of structure our kernel is: 
212
213        .. code-block:: cpp
214
215           createTrackbar( "Element:\n 0: Rect - 1: Cross - 2: Ellipse", window_name, 
216                           &morph_elem, max_elem, 
217                           Morphology_Operations );
218
219      * The final trackbar **"Kernel Size"** returns the size of the kernel to be used (**morph_size**)
220
221        .. code-block:: cpp
222
223           createTrackbar( "Kernel size:\n 2n +1", window_name, 
224                           &morph_size, max_kernel_size,
225                           Morphology_Operations );
226
227
228    * Every time we move any slider, the user's function **Morphology_Operations** will be called to effectuate a new morphology operation and it will update the output image based on the current trackbar values.
229   
230      .. code-block:: cpp
231
232         /** 
233          * @function Morphology_Operations
234          */
235        void Morphology_Operations( int, void* )
236        {
237          // Since MORPH_X : 2,3,4,5 and 6
238          int operation = morph_operator + 2;
239
240          Mat element = getStructuringElement( morph_elem, Size( 2*morph_size + 1, 2*morph_size+1 ), Point( morph_size, morph_size ) ); 
241
242          /// Apply the specified morphology operation
243          morphologyEx( src, dst, operation, element );
244          imshow( window_name, dst );  
245         }
246
247
248      We can observe that the key function to perform the morphology transformations is :morphology_ex:`morphologyEx <>`. In this example we use four arguments (leaving the rest as defaults):
249
250      * **src** : Source (input) image
251      * **dst**: Output image
252      * **operation**: The kind of morphology transformation to be performed. Note that we have 5 alternatives:
253
254        * *Opening*: MORPH_OPEN : 2
255        * *Closing*: MORPH_CLOSE: 3
256        * *Gradient*: MORPH_GRADIENT: 4
257        * *Top Hat*: MORPH_TOPHAT: 5
258        * *Black Hat*: MORPH_BLACKHAT: 6
259
260        As you can see the values range from <2-6>, that is why we add (+2) to the values entered by the Trackbar:
261
262        ..  code-block:: cpp
263
264            int operation = morph_operator + 2;    
265
266      * **element**: The kernel to be used. We use the function :get_structuring_element:`getStructuringElement <>` to define our own structure.
267
268    
269
270 Results
271 ========
272
273 * After compiling the code above we can execute it giving an image path as an argument. For this tutorial we use as input the image: **baboon.jpg**:
274
275   .. image:: images/Morphology_2_Tutorial_Original_Image.jpg
276      :height: 200pt
277      :alt: Morphology 2: Original image
278      :align: center 
279
280 * And here are two snapshots of the display window. The first picture shows the output after using the operator **Opening** with a cross kernel. The second picture (right side, shows the result of using a **Blackhat** operator with an ellipse kernel.
281  
282   .. image:: images/Morphology_2_Tutorial_Cover.png
283      :height: 300pt
284      :alt: Morphology 2: Result sample
285      :align: center 
286