Opencv使用cv::matchTemplate进行模板匹配

本文介绍如何使用OpenCV中的matchTemplate函数实现图像模板匹配,并通过代码示例详细解释了匹配过程及结果展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 使用matchTemplate函数进行图像模板匹配

什么是模板匹配?

答:模板匹配是一项在一幅图像中寻找与另一幅模板图像最匹配(相似)部分的技术.

所需函数:matchTemplate

函数名:matchTemplate

函数功能:在目标图像中匹配模板图像!

函数原型:

void matchTemplate( InputArray image, InputArray templ,OutputArray result, int method );

参数介绍:

InputArray image: 目标图像
InputArray templ:模板图像,注意模板图像的颜色位深度与通道必须与目标图像一致
OutputArray result:匹配结果图像。必须是单通道32位浮点型,且大小是(W-w+1)*(H-h+1),其中W,H分别为输入图像的宽和高,w,h分别为模板图像的宽和高。
int method:相似度衡量的方法。具体如下

 

  1. 平方差匹配 method=CV_TM_SQDIFF

这类方法利用平方差来进行匹配,最好匹配为0.匹配越差,匹配值越大.

R(x,y)= \sum _{x',y'} (T(x',y')-I(x+x',y+y'))^2

  1. 标准平方差匹配 method=CV_TM_SQDIFF_NORMED

    R(x,y)= \frac{\sum_{x',y'} (T(x',y')-I(x+x',y+y'))^2}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}

  2. 相关匹配 method=CV_TM_CCORR

这类方法采用模板和图像间的乘法操作,所以较大的数表示匹配程度较高,0标识最坏的匹配效果.

R(x,y)= \sum _{x',y'} (T(x',y')  \cdot I(x+x',y+y'))

  1. 标准相关匹配 method=CV_TM_CCORR_NORMED

    R(x,y)= \frac{\sum_{x',y'} (T(x',y') \cdot I'(x+x',y+y'))}{\sqrt{\sum_{x',y'}T(x',y')^2 \cdot \sum_{x',y'} I(x+x',y+y')^2}}

  2. 相关匹配 method=CV_TM_CCOEFF

这类方法将模版对其均值的相对值与图像对其均值的相关值进行匹配,1表示完美匹配,-1表示糟糕的匹配,0表示没有任何相关性(随机序列).

R(x,y)= \sum _{x',y'} (T'(x',y')  \cdot I(x+x',y+y'))

在这里

\begin{array}{l} T'(x',y')=T(x',y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} T(x'',y'') \\ I'(x+x',y+y')=I(x+x',y+y') - 1/(w  \cdot h)  \cdot \sum _{x'',y''} I(x+x'',y+y'') \end{array}

  1. 标准相关匹配 method=CV_TM_CCOEFF_NORMED

    R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x',y+y')) }{ \sqrt{\sum_{x',y'}T'(x',y')^2 \cdot \sum_{x',y'} I'(x+x',y+y')^2} }

通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配(同时也意味着越来越大的计算代价). 最好的办法是对所有这些设置多做一些测试实验,以便为自己的应用选择同时兼顾速度和精度的最佳方案.

 

函数名:minMaxLoc

函数功能:寻找image矩阵里的最大值和最小值

函数原型:

 void minMaxLoc(InputArray src, CV_OUT double* minVal,CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0,CV_OUT Point* maxLoc=0, InputArray mask=noArray());

参数介绍:

参数1:InputArray类型的src,输入单通道数组(图像)。
参数2:double*类型的minVal,返回最小值的指针。若无须返回,此值置为NULL。
参数3:double*类型的maxVal,返回最大值的指针。若无须返回,此值置为NULL。
参数4:Point*类型的minLoc,返回最小位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数5:Point*类型的maxLoc,返回最大位置的指针(二维情况下)。若无须返回,此值置为NULL。
参数6:InputArray类型的mask,用于选择子阵列的可选掩膜。

返回值:无

二. 编写代码

开始前需要准备一张原图,和一张模板图

原图如下:

模板图如下:

如有需要可自行把保存本地JPG格式!

3.1 开始编写代码

注意该函数存在于cv空间中,采用c++的名字空间方式编写而成的,所以我们要去掉名字空间!在main函数前面加上:using namespace cv;来去掉名字空间!

当然如果你担心作用域冲突也可以不加!

using namespace cv;

3.2 加载原图和模板图

//加载源图像和模板图像  
Mat image = imread("d:\\a.jpg");
Mat image_demo = imread("d:\\b.jpg");

3.3 创建一个图像用于存储mat算法结果图

Mat image_matched;//用于存储结果图

3.4 模板匹配

使用的是TM_CCOEFF_NORMED算法!经过多次测试发现TM_CCOEFF_NORMED算法最为准确!

//模板匹配  
matchTemplate(image, image_demo, image_matched, TM_CCOEFF_NORMED);

3.5 寻找最佳的匹配位置

double minVal, maxVal;
Point minLoc, maxLoc;
//寻找最佳匹配位置  
minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc);

3.6 将对应区域规划出来

//绘制图像
	circle(image, Point(maxLoc.x + image_demo.cols / 2, maxLoc.y + image_demo.rows / 2), 50/*根据模板尺寸修改该值*/, Scalar(0, 0, 255), 2, 8, 0);

3.7 显示图像

//显示图像
	imshow("image", image);
	imshow("image_demo", image_demo);
	imshow("image_matched", image_matched);
	waitKey(0);	//message

运行结果:

完整代码:

//加载源图像和模板图像  
	Mat image = imread("d:\\a.jpg");
	Mat image_demo = imread("d:\\b.jpg");
	Mat image_matched;//用于存储结果图
	//模板匹配  
	matchTemplate(image, image_demo, image_matched, TM_CCOEFF_NORMED);
	double minVal, maxVal;
	Point minLoc, maxLoc;
	//寻找最佳匹配位置  
	minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc);
	//绘制图像
	Mat image_color;
	circle(image, Point(maxLoc.x + image_demo.cols / 2, maxLoc.y + image_demo.rows / 2), 50, Scalar(0, 0, 255), 2, 8, 0);
	//显示图像
	imshow("image", image);
	imshow("image_demo", image_demo);
	imshow("image_matched", image_matched);
	waitKey(0);	//message

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

17岁boy想当攻城狮

感谢打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值