Hit-or-Miss {#tutorial_hitOrMiss}
=================================
+@prev_tutorial{tutorial_opening_closing_hats}
+@next_tutorial{tutorial_morph_lines_detection}
+
Goal
----
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:
Code
----
-The code corresponding to the previous example is shown below. You can also download it from
-[here](https://github.com/opencv/opencv/tree/master/samples/cpp/tutorial_code/ImgProc/HitMiss.cpp)
-@include samples/cpp/tutorial_code/ImgProc/HitMiss.cpp
+The code corresponding to the previous example is shown below.
+
+@add_toggle_cpp
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/cpp/tutorial_code/ImgProc/HitMiss/HitMiss.cpp)
+@include samples/cpp/tutorial_code/ImgProc/HitMiss/HitMiss.cpp
+@end_toggle
+
+@add_toggle_java
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java)
+@include samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java
+@end_toggle
+
+@add_toggle_python
+You can also download it from
+[here](https://raw.githubusercontent.com/opencv/opencv/master/samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py)
+@include samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py
+@end_toggle
-As you can see, it is as simple as using the function @ref cv::morphologyEx with the operation type @ref cv::MORPH_HITMISS and the chosen kernel.
+As you can see, it is as simple as using the function **morphologyEx()** with the operation type **MORPH_HITMISS** and the chosen kernel.
Other examples
--------------
Here we investigate different morphology operators
-- @subpage tutorial_hitOrMiss
+- @subpage tutorial_hitOrMiss
+
+ *Languages:* C++, Java, Python
*Compatibility:* \> OpenCV 2.4
Mat output_image;
morphologyEx(input_image, output_image, MORPH_HITMISS, kernel);
- const int rate = 10;
+ const int rate = 50;
kernel = (kernel + 1) * 127;
kernel.convertTo(kernel, CV_8U);
+
resize(kernel, kernel, Size(), rate, rate, INTER_NEAREST);
imshow("kernel", kernel);
+ moveWindow("kernel", 0, 0);
+
resize(input_image, input_image, Size(), rate, rate, INTER_NEAREST);
imshow("Original", input_image);
+ moveWindow("Original", 0, 200);
+
resize(output_image, output_image, Size(), rate, rate, INTER_NEAREST);
imshow("Hit or Miss", output_image);
+ moveWindow("Hit or Miss", 500, 200);
+
waitKey(0);
return 0;
}
--- /dev/null
+import org.opencv.core.*;
+import org.opencv.highgui.HighGui;
+import org.opencv.imgproc.Imgproc;
+
+class HitMissRun{
+
+ public void run() {
+ Mat input_image = new Mat( 8, 8, CvType.CV_8UC1 );
+ int row = 0, col = 0;
+ input_image.put(row ,col,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 255, 255, 255, 0, 0, 0, 255,
+ 0, 255, 255, 255, 0, 0, 0, 0,
+ 0, 255, 255, 255, 0, 255, 0, 0,
+ 0, 0, 255, 0, 0, 0, 0, 0,
+ 0, 0, 255, 0, 0, 255, 255, 0,
+ 0, 255, 0, 255, 0, 0, 255, 0,
+ 0, 255, 255, 255, 0, 0, 0, 0);
+
+ Mat kernel = new Mat( 3, 3, CvType.CV_16S );
+ kernel.put(row ,col,
+ 0, 1, 0,
+ 1, -1, 1,
+ 0, 1, 0 );
+
+ Mat output_image = new Mat();
+ Imgproc.morphologyEx(input_image, output_image, Imgproc.MORPH_HITMISS, kernel);
+
+ int rate = 50;
+ Core.add(kernel, new Scalar(1), kernel);
+ Core.multiply(kernel, new Scalar(127), kernel);
+ kernel.convertTo(kernel, CvType.CV_8U);
+
+ Imgproc.resize(kernel, kernel, new Size(), rate, rate, Imgproc.INTER_NEAREST);
+ HighGui.imshow("kernel", kernel);
+ HighGui.moveWindow("kernel", 0, 0);
+
+ Imgproc.resize(input_image, input_image, new Size(), rate, rate, Imgproc.INTER_NEAREST);
+ HighGui.imshow("Original", input_image);
+ HighGui.moveWindow("Original", 0, 200);
+
+ Imgproc.resize(output_image, output_image, new Size(), rate, rate, Imgproc.INTER_NEAREST);
+ HighGui.imshow("Hit or Miss", output_image);
+ HighGui.moveWindow("Hit or Miss", 500, 200);
+
+ HighGui.waitKey(0);
+ System.exit(0);
+ }
+}
+
+public class HitMiss
+{
+ public static void main(String[] args) {
+ // load the native OpenCV library
+ System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
+ new HitMissRun().run();
+ }
+}
--- /dev/null
+import cv2
+import numpy as np
+
+input_image = np.array((
+ [0, 0, 0, 0, 0, 0, 0, 0],
+ [0, 255, 255, 255, 0, 0, 0, 255],
+ [0, 255, 255, 255, 0, 0, 0, 0],
+ [0, 255, 255, 255, 0, 255, 0, 0],
+ [0, 0, 255, 0, 0, 0, 0, 0],
+ [0, 0, 255, 0, 0, 255, 255, 0],
+ [0,255, 0, 255, 0, 0, 255, 0],
+ [0, 255, 255, 255, 0, 0, 0, 0]), dtype="uint8")
+
+kernel = np.array((
+ [0, 1, 0],
+ [1, -1, 1],
+ [0, 1, 0]), dtype="int")
+
+output_image = cv2.morphologyEx(input_image, cv2.MORPH_HITMISS, kernel)
+
+rate = 50
+kernel = (kernel + 1) * 127
+kernel = np.uint8(kernel)
+
+kernel = cv2.resize(kernel, None, fx = rate, fy = rate, interpolation = cv2.INTER_NEAREST)
+cv2.imshow("kernel", kernel)
+cv2.moveWindow("kernel", 0, 0)
+
+input_image = cv2.resize(input_image, None, fx = rate, fy = rate, interpolation = cv2.INTER_NEAREST)
+cv2.imshow("Original", input_image)
+cv2.moveWindow("Original", 0, 200)
+
+output_image = cv2.resize(output_image, None , fx = rate, fy = rate, interpolation = cv2.INTER_NEAREST)
+cv2.imshow("Hit or Miss", output_image)
+cv2.moveWindow("Hit or Miss", 500, 200)
+
+cv2.waitKey(0)
+cv2.destroyAllWindows()