From 18bc4db75cc4d70363b8d8a5d837e3bd63f768c0 Mon Sep 17 00:00:00 2001 From: tribta Date: Sun, 20 Aug 2017 22:54:38 +0100 Subject: [PATCH] Tutorial Hit-or-Miss --- doc/tutorials/imgproc/hitOrMiss/hitOrMiss.markdown | 33 +++++++++--- .../imgproc/table_of_content_imgproc.markdown | 4 +- .../ImgProc/{ => HitMiss}/HitMiss.cpp | 9 +++- .../tutorial_code/ImgProc/HitMiss/HitMiss.java | 58 ++++++++++++++++++++++ .../tutorial_code/imgProc/HitMiss/hit_miss.py | 38 ++++++++++++++ 5 files changed, 132 insertions(+), 10 deletions(-) rename samples/cpp/tutorial_code/ImgProc/{ => HitMiss}/HitMiss.cpp (88%) create mode 100644 samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java create mode 100644 samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py diff --git a/doc/tutorials/imgproc/hitOrMiss/hitOrMiss.markdown b/doc/tutorials/imgproc/hitOrMiss/hitOrMiss.markdown index 085e7c2..c55f0929 100644 --- a/doc/tutorials/imgproc/hitOrMiss/hitOrMiss.markdown +++ b/doc/tutorials/imgproc/hitOrMiss/hitOrMiss.markdown @@ -1,22 +1,23 @@ 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: @@ -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 -[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 -------------- diff --git a/doc/tutorials/imgproc/table_of_content_imgproc.markdown b/doc/tutorials/imgproc/table_of_content_imgproc.markdown index 335ba29..59f7725 100644 --- a/doc/tutorials/imgproc/table_of_content_imgproc.markdown +++ b/doc/tutorials/imgproc/table_of_content_imgproc.markdown @@ -29,7 +29,9 @@ In this section you will learn about the image processing (manipulation) functio Here we investigate different morphology operators -- @subpage tutorial_hitOrMiss +- @subpage tutorial_hitOrMiss + + *Languages:* C++, Java, Python *Compatibility:* \> OpenCV 2.4 diff --git a/samples/cpp/tutorial_code/ImgProc/HitMiss.cpp b/samples/cpp/tutorial_code/ImgProc/HitMiss/HitMiss.cpp similarity index 88% rename from samples/cpp/tutorial_code/ImgProc/HitMiss.cpp rename to samples/cpp/tutorial_code/ImgProc/HitMiss/HitMiss.cpp index c2c3e1d..0901191 100644 --- a/samples/cpp/tutorial_code/ImgProc/HitMiss.cpp +++ b/samples/cpp/tutorial_code/ImgProc/HitMiss/HitMiss.cpp @@ -23,15 +23,22 @@ int main(){ 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; } diff --git a/samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java b/samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java new file mode 100644 index 0000000..806537f --- /dev/null +++ b/samples/java/tutorial_code/ImgProc/HitMiss/HitMiss.java @@ -0,0 +1,58 @@ +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(); + } +} diff --git a/samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py b/samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py new file mode 100644 index 0000000..c25715c --- /dev/null +++ b/samples/python/tutorial_code/imgProc/HitMiss/hit_miss.py @@ -0,0 +1,38 @@ +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() -- 2.7.4