In this tutorial you will learn how to find a given configuration or pattern in a binary image by using the Hit-or-Miss transform (also known as Hit-and-Miss transform).
In this tutorial you will learn how to find a given configuration or pattern in a binary image by using the Hit-or-Miss transform (also known as Hit-and-Miss transform).
This transform is also the basis of more advanced morphological operations such as thinning or pruning.
This transform is also the basis of more advanced morphological operations such as thinning or pruning.
We will use the OpenCV function @ref cv::morphologyEx.
We will use the OpenCV function **morphologyEx()** .
Hit-or-Miss theory
Hit-or-Miss theory
-------------------
-------------------
Morphological operators process images based on their shape. These operators apply one or more *structuring elements* to an input image to obtain the output image.
Morphological operators process images based on their shape. These operators apply one or more *structuring elements* to an input image to obtain the output image.
The two basic morphological operations are the *erosion* and the *dilation*. The combination of these two operations generate advanced morphological transformations such as *opening*, *closing*, or *top-hat* transform.
The two basic morphological operations are the *erosion* and the *dilation*. The combination of these two operations generate advanced morphological transformations such as *opening*, *closing*, or *top-hat* transform.
To know more about these and other basic morphological operations refer to previous tutorials @ref tutorial_erosion_dilatation "here" and @ref tutorial_opening_closing_hats "here".
To know more about these and other basic morphological operations refer to previous tutorials (@ref tutorial_erosion_dilatation "Eroding and Dilating") and (@ref tutorial_opening_closing_hats "More Morphology Transformations").
The Hit-or-Miss transformation is useful to find patterns in binary images. In particular, it finds those pixels whose neighbourhood matches the shape of a first structuring element \f$B_1\f$
The Hit-or-Miss transformation is useful to find patterns in binary images. In particular, it finds those pixels whose neighbourhood matches the shape of a first structuring element \f$B_1\f$
while not matching the shape of a second structuring element \f$B_2\f$ at the same time. Mathematically, the operation applied to an image \f$A\f$ can be expressed as follows:
while not matching the shape of a second structuring element \f$B_2\f$ at the same time. Mathematically, the operation applied to an image \f$A\f$ can be expressed as follows:
...
@@ -43,11 +44,27 @@ You can see that the pattern is found in just one location within the image.
...
@@ -43,11 +44,27 @@ You can see that the pattern is found in just one location within the image.
Code
Code
----
----
The code corresponding to the previous example is shown below. You can also download it from
The code corresponding to the previous example is shown below.
A slightly fancier version (which shows trackbars for
@end_toggle
changing the threshold values) can be found [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/HoughCircle_Demo.cpp).
@include samples/cpp/houghcircles.cpp
@add_toggle_java
The sample code that we will explain can be downloaded from
- Display the original image and the detected line in two windows.
A slightly fancier version (which shows both Hough standard and probabilistic
with trackbars for changing the threshold values) can be found
-# The sample code that we will explain can be downloaded from [here](https://github.com/opencv/opencv/tree/master/samples/cpp/houghlines.cpp). A slightly fancier version
Extract horizontal and vertical lines by using morphological operations {#tutorial_moprh_lines_detection}
Extract horizontal and vertical lines by using morphological operations {#tutorial_morph_lines_detection}
=============
=============
@prev_tutorial{tutorial_hitOrMiss}
@next_tutorial{tutorial_pyramids}
Goal
Goal
----
----
In this tutorial you will learn how to:
In this tutorial you will learn how to:
- Apply two very common morphology operators (i.e. Dilation and Erosion), with the creation of custom kernels, in order to extract straight lines on the horizontal and vertical axes. For this purpose, you will use the following OpenCV functions:
- Apply two very common morphology operators (i.e. Dilation and Erosion), with the creation of custom kernels, in order to extract straight lines on the horizontal and vertical axes. For this purpose, you will use the following OpenCV functions:
-@ref cv::erode
-**erode()**
-@ref cv::dilate
-**dilate()**
-@ref cv::getStructuringElement
-**getStructuringElement()**
in an example where your goal will be to extract the music notes from a music sheet.
in an example where your goal will be to extract the music notes from a music sheet.
...
@@ -48,39 +51,144 @@ A structuring element can have many common shapes, such as lines, diamonds, disk
...
@@ -48,39 +51,144 @@ A structuring element can have many common shapes, such as lines, diamonds, disk
Code
Code
----
----
This tutorial code's is shown lines below. You can also download it from [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/Morphology_3.cpp).
You can also download it from [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp).
You can also download it from [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.java).
You can also download it from [here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/imgProc/morph_lines_detection/morph_lines_detection.py).
@snippet samples/cpp/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.cpp bin
@end_toggle
@add_toggle_java
@snippet samples/java/tutorial_code/ImgProc/morph_lines_detection/Morphology_3.java bin
@end_toggle
@add_toggle_python
@snippet samples/python/tutorial_code/imgProc/morph_lines_detection/morph_lines_detection.py bin
@end_toggle

#### Output images
Now we are ready to apply morphological operations in order to extract the horizontal and vertical lines and as a consequence to separate the the music notes from the music sheet, but first let's initialize the output images that we will use for that reason:
As we specified in the theory in order to extract the object that we desire, we need to create the corresponding structure element. Since we want to extract the horizontal lines, a corresponding structure element for that purpose will have the following shape:

and in the source code this is represented by the following code snippet:
-# Afterwards transform grayscale image to binary. Notice the ~ symbol which indicates that we use the inverse (i.e. bitwise_not) version of it:
As you can see we are almost there. However, at that point you will notice that the edges of the notes are a bit rough. For that reason we need to refine the edges in order to obtain a smoother result:
@snippet samples/cpp/tutorial_code/ImgProc/Morphology_3.cpp bin

-# Now we are ready to apply morphological operations in order to extract the horizontal and vertical lines and as a consequence to separate the the music notes from the music sheet, but first let's initialize the output images that we will use for that reason:
-# As we specified in the theory in order to extract the object that we desire, we need to create the corresponding structure element. Since here we want to extract the horizontal lines, a corresponding structure element for that purpose will have the following shape:
@snippet samples/cpp/tutorial_code/ImgProc/Morphology_3.cpp vert

-# As you can see we are almost there. However, at that point you will notice that the edges of the notes are a bit rough. For that reason we need to refine the edges in order to obtain a smoother result: