OpenCV Hit-or-Miss
目标
在本教程中,您将学习如何使用Hit-or-Miss变换(也称为Hit-and-Miss变换)来查找二进制图像中的给定配置或模式。这种变换也是更先进的形态学操作如稀释或修剪的基础。
我们将使用OpenCV函数cv :: morphologyEx。
Hit-or-Miss理论
形态运算符根据其形状来处理图像。这些操作者将一个或多个结构元素应用于输入图像以获得输出图像。两种基本形态作用是侵蚀和扩张。这两个操作的组合产生了先进的形态变换,如打开,关闭或顶帽变换。要了解更多关于这些和其他基本形态操作,请参阅此处和此处的以前的教程。
Hit-or-Miss转换对于查找二进制图像中的图案非常有用。特别地,它找到其邻域与第一结构元素的形状匹配的那些像素,同时不匹配第二结构元素B_2的形状。在数学上,应用于图像A的操作可以表示如下:B1B2A
因此,命中或错过操作包括三个步骤:
- 侵蚀图像与结构元素B_1。AB1
- 用构造元素B_2打印图像(A ^ c)的补码。AAcB2
- AND来自步骤1和步骤2。
结构元素和B_2可以组合成一个单一的元件乙。我们来看一个例子:B1B2B
结构元素(内核)。左:内核到'打'。中间:内核到'miss'。右:最终组合内核
在这种情况下,我们正在寻找中心像素属于背景的图案,而北,南,东,西像素属于前景。邻里的其他像素可以是任何形式,我们不关心它们。现在我们把这个内核应用到输入图像中:
输入二进制图像
输出二进制图像
您可以看到该图案仅在图像中的一个位置中找到。
Code
与前面的例子相对应的代码如下所示。您也可以从这里下载
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
using namespace cv;
int main(){
Mat input_image = (Mat_<uchar>(8, 8) <<
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 = (Mat_<int>(3, 3) <<
0, 1, 0,
1, -1, 1,
0, 1, 0);
Mat output_image;
morphologyEx(input_image, output_image, MORPH_HITMISS, kernel);
const int rate = 10;
kernel = (kernel + 1) * 127;
kernel.convertTo(kernel, CV_8U);
resize(kernel, kernel, Size(), rate, rate, INTER_NEAREST);
imshow("kernel", kernel);
resize(input_image, input_image, Size(), rate, rate, INTER_NEAREST);
imshow("Original", input_image);
resize(output_image, output_image, Size(), rate, rate, INTER_NEAREST);
imshow("Hit or Miss", output_image);
waitKey(0);
return 0;
}
可以看到,它与使用函数cv :: morphologyEx一样简单,操作类型为cv :: MORPH_HITMISS和所选内核。
其他例子
在这里,您可以找到将不同内核应用于之前使用的相同输入图像的输出结果:
查找右上角的内核和输出结果
找到左端点的内核和输出结果
现在尝试你自己的模式!