Home | History | Annotate | Download | only in erosion_dilatation
      1 Eroding and Dilating {#tutorial_erosion_dilatation}
      2 ====================
      3 
      4 Goal
      5 ----
      6 
      7 In 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 
     14 Cool Theory
     15 -----------
     16 
     17 @note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
     18 
     19 Morphological 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 
     45 The 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 
     59 Code
     60 ----
     61 
     62 This 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 
     66 Explanation
     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
    125 Reference 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 
    150 Results
    151 -------
    152 
    153 Compile 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 
    157 We get the results below. Varying the indices in the Trackbars give different output images,
    158 naturally. Try them out! You can even try to add a third Trackbar to control the number of
    159 iterations.
    160 
    161 ![](images/Morphology_1_Result.jpg)
    162