模板匹配是一项在一副图像中寻找另一幅模板图像最相似部分的技术
注意:
模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块,对实际的图像块和输入图像进行匹配的一种匹配方法
matchTemplate(
InputArray image, // 源图像,必须是8-bit或者32-bit浮点数图像
InputArray templ, // 模板图像,类型与输入图像一致,且尺寸不能大于源图像
OutputArray result, // 输出结果,必须是单通道32位浮点数,假设源图像W×H,模板图像w×h, 则此参数一定是(W-w+1)×( H-h+1)
int method, // 使用的匹配方法 )
如下6种图像匹配方法可以使用:
方法 | 标识符 |
---|---|
平方差匹配法 | TM_SQDIFF |
归一化平方差匹配法 | TM_SQDIFF_NORMED |
相关匹配法 | TM_CCORR |
归一化相关匹配法 | TM_CCORR_NORMED |
系数匹配法 | TM_CCOEFF |
相关系数匹配法 | TM_CCOEFF_NORMED |
通常,随着从简单的测量(平方差)到更复杂的测量(相关系数),我们可获得越来越准确的匹配。然而,这同时也会以越来越大的计算量为代价。比较科学的办法是对所有这些方法多次测试实验,以便为自己的应用选择同时兼顾速度和精度的最佳方案。
代码出处:https://www.cnblogs.com/skyfsm/p/6884253.html
#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/imgproc.hpp>
#include<iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img, templ, result;
img = imread("/home/zdg/图片/屏幕截图_1.png");
templ = imread("/home/zdg/图片/屏幕截图.png");
imshow("模板匹配图",templ);
int result_cols = img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;
result.create(result_cols, result_rows, CV_32FC1);
matchTemplate(img, templ, result, TM_SQDIFF_NORMED);//这里我们使用的匹配算法是标准平方差匹配 method=CV_TM_SQDIFF_NORMED,数值越小匹配度越好
normalize(result, result, 0, 1, NORM_MINMAX, -1, Mat());
double minVal = 0.0;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
cout << "匹配度:" << minVal << endl;
matchLoc = minLoc;
rectangle(img, matchLoc, Point(matchLoc.x + templ.cols, matchLoc.y + templ.rows), Scalar(0, 255, 0), 2, 8, 0);
imshow("img", img);
waitKey(0);
return 0;
}