1Eroding and Dilating {#tutorial_erosion_dilatation} 2==================== 3 4Goal 5---- 6 7In this tutorial you will learn how to: 8 9- Apply two very common morphology operators: Dilation and Erosion. For this purpose, you will use 10 the following OpenCV functions: 11 - @ref cv::erode 12 - @ref cv::dilate 13 14Cool Theory 15----------- 16 17@note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler. 18 19Morphological Operations 20------------------------ 21 22- In short: A set of operations that process images based on shapes. Morphological operations 23 apply a *structuring element* to an input image and generate an output image. 24- The most basic morphological operations are two: Erosion and Dilation. They have a wide array of 25 uses, i.e. : 26 - Removing noise 27 - Isolation of individual elements and joining disparate elements in an image. 28 - Finding of intensity bumps or holes in an image 29- We will explain dilation and erosion briefly, using the following image as an example: 30 31 ![](images/Morphology_1_Tutorial_Theory_Original_Image.png) 32 33### Dilation 34 35- This operations consists of convoluting an image \f$A\f$ with some kernel (\f$B\f$), which can have any 36 shape or size, usually a square or circle. 37- The kernel \f$B\f$ has a defined *anchor point*, usually being the center of the kernel. 38- As the kernel \f$B\f$ is scanned over the image, we compute the maximal pixel value overlapped by 39 \f$B\f$ and replace the image pixel in the anchor point position with that maximal value. As you can 40 deduce, this maximizing operation causes bright regions within an image to "grow" (therefore the 41 name *dilation*). Take as an example the image above. Applying dilation we can get: 42 43 ![](images/Morphology_1_Tutorial_Theory_Dilation.png) 44 45The background (bright) dilates around the black regions of the letter. 46 47### Erosion 48 49- This operation is the sister of dilation. What this does is to compute a local minimum over the 50 area of the kernel. 51- As the kernel \f$B\f$ is scanned over the image, we compute the minimal pixel value overlapped by 52 \f$B\f$ and replace the image pixel under the anchor point with that minimal value. 53- Analagously to the example for dilation, we can apply the erosion operator to the original image 54 (shown above). You can see in the result below that the bright areas of the image (the 55 background, apparently), get thinner, whereas the dark zones (the "writing") gets bigger. 56 57 ![](images/Morphology_1_Tutorial_Theory_Erosion.png) 58 59Code 60---- 61 62This tutorial code's is shown lines below. You can also download it from 63[here](https://github.com/Itseez/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp) 64@include samples/cpp/tutorial_code/ImgProc/Morphology_1.cpp 65 66Explanation 67----------- 68 69-# Most of the stuff shown is known by you (if you have any doubt, please refer to the tutorials in 70 previous sections). Let's check the general structure of the program: 71 72 - Load an image (can be BGR or grayscale) 73 - Create two windows (one for dilation output, the other for erosion) 74 - Create a set of 02 Trackbars for each operation: 75 - The first trackbar "Element" returns either **erosion_elem** or **dilation_elem** 76 - The second trackbar "Kernel size" return **erosion_size** or **dilation_size** for the 77 corresponding operation. 78 - Every time we move any slider, the user's function **Erosion** or **Dilation** will be 79 called and it will update the output image based on the current trackbar values. 80 81 Let's analyze these two functions: 82 83-# **erosion:** 84 @code{.cpp} 85 /* @function Erosion */ 86 void Erosion( int, void* ) 87 { 88 int erosion_type; 89 if( erosion_elem == 0 ){ erosion_type = MORPH_RECT; } 90 else if( erosion_elem == 1 ){ erosion_type = MORPH_CROSS; } 91 else if( erosion_elem == 2) { erosion_type = MORPH_ELLIPSE; } 92 93 Mat element = getStructuringElement( erosion_type, 94 Size( 2*erosion_size + 1, 2*erosion_size+1 ), 95 Point( erosion_size, erosion_size ) ); 96 /// Apply the erosion operation 97 erode( src, erosion_dst, element ); 98 imshow( "Erosion Demo", erosion_dst ); 99 } 100 @endcode 101 - The function that performs the *erosion* operation is @ref cv::erode . As we can see, it 102 receives three arguments: 103 - *src*: The source image 104 - *erosion_dst*: The output image 105 - *element*: This is the kernel we will use to perform the operation. If we do not 106 specify, the default is a simple `3x3` matrix. Otherwise, we can specify its 107 shape. For this, we need to use the function cv::getStructuringElement : 108 @code{.cpp} 109 Mat element = getStructuringElement( erosion_type, 110 Size( 2*erosion_size + 1, 2*erosion_size+1 ), 111 Point( erosion_size, erosion_size ) ); 112 @endcode 113 We can choose any of three shapes for our kernel: 114 115 - Rectangular box: MORPH_RECT 116 - Cross: MORPH_CROSS 117 - Ellipse: MORPH_ELLIPSE 118 119 Then, we just have to specify the size of our kernel and the *anchor point*. If not 120 specified, it is assumed to be in the center. 121 122 - That is all. We are ready to perform the erosion of our image. 123@note Additionally, there is another parameter that allows you to perform multiple erosions 124(iterations) at once. We are not using it in this simple tutorial, though. You can check out the 125Reference for more details. 126 127-# **dilation:** 128 129 The code is below. As you can see, it is completely similar to the snippet of code for **erosion**. 130 Here we also have the option of defining our kernel, its anchor point and the size of the operator 131 to be used. 132 @code{.cpp} 133 /* @function Dilation */ 134 void Dilation( int, void* ) 135 { 136 int dilation_type; 137 if( dilation_elem == 0 ){ dilation_type = MORPH_RECT; } 138 else if( dilation_elem == 1 ){ dilation_type = MORPH_CROSS; } 139 else if( dilation_elem == 2) { dilation_type = MORPH_ELLIPSE; } 140 141 Mat element = getStructuringElement( dilation_type, 142 Size( 2*dilation_size + 1, 2*dilation_size+1 ), 143 Point( dilation_size, dilation_size ) ); 144 /// Apply the dilation operation 145 dilate( src, dilation_dst, element ); 146 imshow( "Dilation Demo", dilation_dst ); 147 } 148 @endcode 149 150Results 151------- 152 153Compile the code above and execute it with an image as argument. For instance, using this image: 154 155![](images/Morphology_1_Tutorial_Original_Image.jpg) 156 157We get the results below. Varying the indices in the Trackbars give different output images, 158naturally. Try them out! You can even try to add a third Trackbar to control the number of 159iterations. 160 161![](images/Morphology_1_Result.jpg) 162