OpenCV4学习笔记(19)——模板匹配

本次要整理记录的内容是:模板匹配。
模板匹配可以说是一种最简单的模式识别方法,它的实现主要是通过模板图像在被匹配图像中的平移,在被匹配图像中逐个区域寻找和模板图像相似的区域,如果存在某区域的相似度大于一定的阈值,则表明该区域和模板图像是相匹配的。
但是模板匹配这种方式具有很大的自身局限性,首先它利用一个规定好的模板进行匹配,这就导致了想要匹配出来的结果必须在大小和角度上和模板图像一模一样,一旦原图像中的匹配目标发生旋转或大小变化,就会导致匹配准确率急剧下降。而且模板图像在原图像中进行移动的时候,只能够平行地上、下、左、右移动,对于有经过投影变换的图像,这种模板匹配寻找目标的方式可以说是完全无效的。同时,这种模板匹配方式对于图像的光照变换是十分敏感的,如果是对同一物体在不同光照环境下拍摄,并进行模板匹配,是很难得出令人满意的效果,模板匹配只适用于光照条件影响很小的匹配任务,工作条件限制比较严格,这也很大的限制了它的应用性。但是对于一些光照不变的图像,在经过预处理之后,还是可以使用模板匹配的方式来寻找匹配目标的。
OpenCV中提供了matchTemplate(image, templ, result, method,mask)这个API来实现模板匹配功能。
第一个参数image:输入的包含匹配目标的图像;
第二个参数templ:进行匹配所用的模板图像;
第三个参数result:输出的匹配结果,为浮点型的Mat对象,其高度是find_image.rows - tem_image.rows + 1 ,宽度是find_image.cols - tem_image.cols + 1
第四个参数method:使用的计算像素相似度的方式,主要有三种可选方式
(1)TM_SQDIFF_NORMED:平方不同(归一化)值在0~1之间,1表示完全不匹配,0表示高度匹配
(2)TM_CCORR_NORMED:相关性(归一化),值在0~1之间,1表示高度匹配,0表示完全不匹配
(3)TM_CCOEFF_NORMED:相关因子(归一化),值在0~1之间,1表示高度匹配,0表示完全不匹配
第五个参数mask:使用的掩膜,没有掩膜的话不用输入直接使用默认值就可以。
下面给出一个模板匹配的代码实现:

	Mat find_image;
	find_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\tyt.png");
	Mat tem_image;
	tem_image = imread("D:\\opencv_c++\\opencv_tutorial\\data\\images\\tyt_template.png");

	Mat result;
	matchTemplate(find_image, tem_image, result, TM_CCOEFF_NORMED);
	
	int result_h = result.rows;			//find_image.rows - tem_image.rows +1
	int result_w = result.cols;			//find_image.cols - tem_image.cols +1
	float threshold = 0.85;				//判断是否与模板相匹配的阈值
	for (int row = 0; row < result_h; row++)
	{
		for (int col = 0; col < result_w; col++)
		{
			float value = result.at<float>(row, col);
			if (value > threshold)			
			{
				Rect rect(col, row, tem_image.cols, tem_image.rows);
				rectangle(find_image, rect, Scalar(0, 0, 255), 2, LINE_AA, 0);
			}
		}
	}
	imshow("find_image", find_image);

首先读入一张待匹配图像和一张模板图像,然后通过matchTemplate()来得到一个表示相似度的浮点型矩阵,这个矩阵中每一个点都是通过与模板进行对比后得到的相似度。再后面使用两个for循环对这个矩阵的所有坐标点进行遍历,获取每个坐标点的值并与设定的阈值进行比较,如果该坐标点值(相似度)大于阈值,说明这里存在一个与模板相匹配的目标,就将相似性大于阈值的点作为绘制目标矩形的锚点坐标,也就是矩形左上角的点,将模板的尺寸作为绘制目标矩形的尺寸,绘制出矩形将目标标记出来。这就实现是对目标的模板匹配操作。具体效果如下:
这是模板图像,是从原图像中裁剪出来的一小块
在这里插入图片描述
然后是待匹配图像
在这里插入图片描述
这是匹配得到的结果:
在这里插入图片描述
可见输出结果中很好的将待寻找目标给标记了出来,但这是在原图像进行操作,下面将原图像通过像素值的添加进行亮度调节后再进行匹配,看看效果。
在这里插入图片描述
这里对原图的像素值都提升了150,虽然图像内容没有发生改变,但是像素值一变化,导致模板匹配操作无法达到之前那么好的效果了,可见模板匹配的鲁棒性是很差的。
总结:对于光照固定的图像进行目标检测,可以通过模板匹配来实现,但如果光照等外界因素变化对图像影响比较大,则模板匹配的效果会大幅下降。模板匹配只能作为一种基本的、入门的目标检测方式。
本次整理到此结束,谢谢阅读。

PS:本人的注释比较杂,既有自己的心得体会也有网上查阅资料时摘抄下的知识内容,所以如有雷同,纯属我向前辈学习的致敬,如果有前辈觉得我的笔记内容侵犯了您的知识产权,请和我联系,我会将涉及到的博文内容删除,谢谢!

发布了36 篇原创文章 · 获赞 43 · 访问量 1807

猜你喜欢

转载自blog.csdn.net/weixin_45224869/article/details/104668915