1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
More Morphology Transformations {#tutorial_opening_closing_hats}
===============================
@tableofcontents
@prev_tutorial{tutorial_erosion_dilatation}
@next_tutorial{tutorial_hitOrMiss}
| | |
| -: | :- |
| Original author | Ana Huamán |
| Compatibility | OpenCV >= 3.0 |
Goal
----
In this tutorial you will learn how to:
- Use the OpenCV function @ref cv::morphologyEx to apply Morphological Transformation such as:
- Opening
- Closing
- Morphological Gradient
- Top Hat
- Black Hat
Theory
------
@note The explanation below belongs to the book **Learning OpenCV** by Bradski and Kaehler.
In the previous tutorial we covered two basic Morphology operations:
- Erosion
- Dilation.
Based on these two we can effectuate more sophisticated transformations to our images. Here we
discuss briefly 5 operations offered by OpenCV:
### Opening
- It is obtained by the erosion of an image followed by a dilation.
\f[dst = open( src, element) = dilate( erode( src, element ) )\f]
- Useful for removing small objects (it is assumed that the objects are bright on a dark
foreground)
- 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 dots have disappeared.

### Closing
- It is obtained by the dilation of an image followed by an erosion.
\f[dst = close( src, element ) = erode( dilate( src, element ) )\f]
- Useful to remove small holes (dark regions).

### Morphological Gradient
- It is the difference between the dilation and the erosion of an image.
\f[dst = morph_{grad}( src, element ) = dilate( src, element ) - erode( src, element )\f]
- It is useful for finding the outline of an object as can be seen below:

### Top Hat
- It is the difference between an input image and its opening.
\f[dst = tophat( src, element ) = src - open( src, element )\f]

### Black Hat
- It is the difference between the closing and its input image
\f[dst = blackhat( src, element ) = close( src, element ) - src\f]

Code
----
@add_toggle_cpp
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/4.x/samples/cpp/tutorial_code/ImgProc/Morphology_2.cpp)
@include cpp/tutorial_code/ImgProc/Morphology_2.cpp
@end_toggle
@add_toggle_java
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/4.x/samples/java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java)
@include java/tutorial_code/ImgProc/opening_closing_hats/MorphologyDemo2.java
@end_toggle
@add_toggle_python
This tutorial's code is shown below. You can also download it
[here](https://github.com/opencv/opencv/tree/4.x/samples/python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py)
@include python/tutorial_code/imgProc/opening_closing_hats/morphology_2.py
@end_toggle
Explanation
-----------
-# Let's check the general structure of the C++ program:
- Load an image
- Create a window to display results of the Morphological operations
- Create three Trackbars for the user to enter parameters:
- The first trackbar **Operator** returns the kind of morphology operation to use
(**morph_operator**).
@snippet cpp/tutorial_code/ImgProc/Morphology_2.cpp create_trackbar1
- The second trackbar **Element** returns **morph_elem**, which indicates what kind of
structure our kernel is:
@snippet cpp/tutorial_code/ImgProc/Morphology_2.cpp create_trackbar2
- The final trackbar **Kernel Size** returns the size of the kernel to be used
(**morph_size**)
@snippet cpp/tutorial_code/ImgProc/Morphology_2.cpp create_trackbar3
- 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.
@snippet cpp/tutorial_code/ImgProc/Morphology_2.cpp morphology_operations
We can observe that the key function to perform the morphology transformations is @ref
cv::morphologyEx . In this example we use four arguments (leaving the rest as defaults):
- **src** : Source (input) image
- **dst**: Output image
- **operation**: The kind of morphology transformation to be performed. Note that we have
5 alternatives:
- *Opening*: MORPH_OPEN : 2
- *Closing*: MORPH_CLOSE: 3
- *Gradient*: MORPH_GRADIENT: 4
- *Top Hat*: MORPH_TOPHAT: 5
- *Black Hat*: MORPH_BLACKHAT: 6
As you can see the values range from \<2-6\>, that is why we add (+2) to the values
entered by the Trackbar:
@snippet cpp/tutorial_code/ImgProc/Morphology_2.cpp operation
- **element**: The kernel to be used. We use the function @ref cv::getStructuringElement
to define our own structure.
Results
-------
- After compiling the code above we can execute it giving an image path as an argument. Results using
the image: **baboon.png**:

- 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.

|