图像形态学——击中击不中

在这里插入图片描述
说明:关于击中击不中问题还有很多疑点,代码实现存在问题,日后遇到在详细解决。


击中击不中变换

击中击不中变换是形状检测的一个基本工具。

设X为目标图像,B为结构元素,且B由两个不相交的部分 B 1 B_1 B1 B 2 B_2 B2组成,即 B = B 1 ∪ B 2 B=B_1∪B_2 B=B1B2,且 B 1 ∩ B 2 = ϕ B_1∩B_2=\phi B1B2=ϕ。则目标图像X被结构元素B击中的数学表达式:
X ⊗ B = { x ∣ ( B 1 ) x ⊆ X , ( B 2 ) x ⊆ X c } X \otimes B= \{x|(B_1)_x \subseteq X , (B_2)_x \subseteq X^c \} XB={x(B1)xX,(B2)xXc}其中, ⊗ \otimes 表示击中击不中变换的运算符。

HMT变换的含义是在目标图像 X被结构元素B击中的输出结果中,每点x必须同时满足两个条件: B 1 B_1 B1被x平移后包含在X内; B 2 B_2 B2被x平移后不包含在X内。



连通子图的匹配和定位

假设A的前景由若干个互不连通子图构成,而且相隔不是太近。另有图像G,需要检测G的前景是否匹配A的某个子图,也就是G的前景集与A的某个子图是否完全一样。若匹配则称为“击中”,否则称为“击不中”。当击中时,还要得到匹配子图在A中的位置,位置的含义是:在A中用两条水平线,两条垂直线恰好框住匹配子图,该矩形的左上角、右下角在A中的坐标。

以下图为例说明击中不击中的原理。图A背景为灰色,前景为白色,前景是三个不连续的子图:圆盘、三角形和正方形。其中正方形的高宽是30*30, A c A^{c} Ac是A的反转。现在设图G的前景色也是30×30的白正方形,那么问题是如何确认G的前景与A的正方形匹配,并得到正方块的位置。
在这里插入图片描述
在这里插入图片描述

下图示意了目标图像X被结构元素B击中的过程与结果。
在这里插入图片描述
在这里插入图片描述

Hit-miss原理

基于腐蚀运算的一个特性:腐蚀的过程相当于对可以填入结构元素的位置作标记的过程。

腐蚀中,虽然标记点取决于原点在结构元素中的相对位置,但输出图像的形状与此无关,改变原点的位置,只会导致输出结果发生平移。腐蚀的过程相当于对可以填入结构元素的位置作标记的过程,可以利用腐蚀确定目标的位置。

进行目标检测,既要检测到目标的内部,也要检测到目标的外部,即在一次运算中可以同时捕获内外标记。

由于以上两点。采用两个结构基元H、M,作为一个结构元素对 B = ( H , M ) B=(H,M) B=(H,M),一个探测目标内部,一个探测目标外部。当且仅当H平移到某一点可填入X的内部,M平移到该点可填入X的外部是,该点才在击中不击中变换中输出。

在这里插入图片描述

Hit-miss算法步骤

击中击不中变换基本原理是使用腐蚀;如果要在一幅图像A上找到B形状的目标,我们需要做的是:

  1. 建立一个比B大的模板W,使用此模板对图像A进行腐蚀,得到图像假设为Process1;
  2. 用B减去W,从而得到V模板(W-B);使用V模板对图像A的补集进行腐蚀,得到图像假设为Process2;
  3. Process1和Process2进行取交集;得到结果就是B的位置。这里的位置可能不是B的中心位置,要视W-B时对其的位置而异。
void hitmiss(Mat &src,Mat &kernel) {
	//原图像src,待检测目标kernel

	//1. 灰度化处理
	Mat gray;
	cvtColor(kernel, kernel, COLOR_BGR2GRAY);
	cvtColor(src, gray, COLOR_BGR2GRAY);
	

	//2. 二值化处理
	Mat binary_src,binary_kernel;
    int thresholdValue = 180;
	threshold(gray, binary_src, thresholdValue, 255, THRESH_BINARY);
	threshold(kernel, binary_kernel, thresholdValue, 255, THRESH_BINARY);

	//3. 击中不击中检测
	Mat  hit_result, hit_result1, hit_result2;
	//3.1    Process1: 使用待检测图像腐蚀原图
	erode(binary_src, hit_result1, binary_kernel);
	imshow("hit_result1", hit_result1);

	//3.2    Process2: 图像A的补集,即src的补集
	  //原图像的补集
	Mat bigBlackImg = Mat::ones(src.rows, src.cols, CV_8UC1);
	Mat src1 = bigBlackImg * 255 - binary_src;
	imshow("反置", src1);
	  //W-B --> 得到模板V,即kernel2
	Mat blackImg = Mat::ones(binary_kernel.rows, binary_kernel.cols, CV_8UC1);
	Mat kernel2 = blackImg * 255 - binary_kernel;
	
	//3.3  腐蚀:使用V模板对图像A的补集进行腐蚀:
	erode(src1, hit_result2, kernel2);
	imshow("hit_result2", hit_result2);

	//3.4  Process1与Process2取交集;得到的结果就是B的位置。
	hit_result = hit_result1 & hit_result2;
	imshow("击中击不中", hit_result);
}

int main() {
	src= imread("D:/test/src.png");
	Mat kernel = imread("D:/test/kernel.png");
	if (src.empty()||kernel.empty()) {
		cout << " input the image error!" << endl;
	}
	imshow("src", src);
	imshow("kernel", kernel);
	hitmiss(src, kernel);

	waitKey(0);
	return 0;
}

在这里插入图片描述

MorphologyEx中的击中参数:

在这里插入图片描述

void hitmiss2(Mat &src) {
	//1. 灰度化处理
	Mat gray;
	cvtColor(src, gray, COLOR_BGR2GRAY);


	//2. 二值化处理
	Mat binary;
	int thresholdValue = 180;
	threshold(gray, binary, thresholdValue, 255, THRESH_BINARY);

	Mat kernel1 = (Mat_<int>(3, 3) <<
		0,  1, 0,
		1, -1, 1,
		0,  1, 0);
	Mat kernel2 = (Mat_<int>(3, 3) <<
		0, 1, 0,
		1, 0, 1,
		0, 1, 0);
	Mat kernel3 = (Mat_<int>(3, 3) <<
		0, 0, 0,
		0, 1, 0,
		0, 0, 0);
	Mat outImg, output_image1, output_image2, output_image3, output_image4;
	Mat element = getStructuringElement(0, Size(3, 3), Point(-1, -1));
	erode(binary, outImg, element);
	imshow("腐蚀图", outImg);
	morphologyEx(binary, output_image1, MORPH_HITMISS, kernel1);
	morphologyEx(binary, output_image2, MORPH_HITMISS, kernel2);
	morphologyEx(binary, output_image3, MORPH_HITMISS, kernel3);
	imshow("Hit or Miss1", output_image1);
	imshow("Hit or Miss2", output_image2);
	imshow("Hit or Miss3", output_image3);
	absdiff(output_image1, output_image2, output_image4);
	imshow("Hit or Miss", output_image4);
}

参考:
数字图像处理(七)形态学处理之击中击不中变换、骨架提取

Opencv图像识别从零到精通(18)——击中击不中

28.击中击不中变换(二值图像/结构元素/集合/convertTo/saturate_cast/moveWindow)

击中击不中变换的作用理解

击中击不中的变换

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值