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.
We will use the OpenCV function @ref cv::morphologyEx.
We will use the OpenCV function **morphologyEx()** .
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.
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$
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.
Code
----
The code corresponding to the previous example is shown below. You can also download it from
- Use the OpenCV function @ref cv::HoughCircles to detect circles in an image.
- Use the OpenCV function **HoughCircles()** to detect circles in an image.
Theory
------
...
...
@@ -31,31 +34,96 @@ Theory
the best radius for each candidate center. For more details, please check the book *Learning
OpenCV* or your favorite Computer Vision bibliography
#### What does this program do?
- Loads an image and blur it to reduce the noise
- Applies the *Hough Circle Transform* to the blurred image .
- Display the detected circle in a window.
Code
----
-# **What does this program do?**
- Loads an image and blur it to reduce the noise
- Applies the *Hough Circle Transform* to the blurred image .
- Display the detected circle in a window.
-# The sample code that we will explain can be downloaded from [here](https://github.com/opencv/opencv/tree/master/samples/cpp/houghcircles.cpp).
A slightly fancier version (which shows trackbars for
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_cpp
The sample code that we will explain can be downloaded from
- Use the OpenCV functions @ref cv::HoughLines and @ref cv::HoughLinesP to detect lines in an
- Use the OpenCV functions **HoughLines()** and **HoughLinesP()** to detect lines in an
image.
Theory
...
...
@@ -79,54 +82,93 @@ a. **The Standard Hough Transform**
- It consists in pretty much what we just explained in the previous section. It gives you as
result a vector of couples \f$(\theta, r_{\theta})\f$
- In OpenCV it is implemented with the function @ref cv::HoughLines
- In OpenCV it is implemented with the function **HoughLines()**
b. **The Probabilistic Hough Line Transform**
- A more efficient implementation of the Hough Line Transform. It gives as output the extremes
of the detected lines \f$(x_{0}, y_{0}, x_{1}, y_{1})\f$
- In OpenCV it is implemented with the function @ref cv::HoughLinesP
- In OpenCV it is implemented with the function **HoughLinesP()**
### What does this program do?
- Loads an image
- Applies a *Standard Hough Line Transform* and a *Probabilistic Line Transform*.
- Display the original image and the detected line in three windows.
Code
----
-# **What does this program do?**
- Loads an image
- Applies either a *Standard Hough Line Transform* or a *Probabilistic Line Transform*.
- Display the original image and the detected line in two windows.
-# 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
(which shows both Hough standard and probabilistic with trackbars for changing the threshold
values) can be found [here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgTrans/HoughLines_Demo.cpp).
@include samples/cpp/houghlines.cpp
@add_toggle_cpp
The sample code that we will explain can be downloaded from
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
----
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:
-@ref cv::erode
-@ref cv::dilate
-@ref cv::getStructuringElement
-**erode()**
-**dilate()**
-**getStructuringElement()**
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
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:
@snippet samples/cpp/tutorial_code/ImgProc/Morphology_3.cpp bin

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:
-# 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:

and in the source code this is represented by the following code snippet:
-# 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: