我先介绍一下模板匹配的原理
原图像:我们期望找到与模板图像匹配的图像
模板图像:将于模板图像进行比较的图像

一次移动一个像素(从左到右,从上到下)。在每个位置,计算相似度度量,以便它表示在该位置处的匹配的“好”还是“坏”。
下面直接用opencv进行实现
头文件
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
定义一些后面要用到的图像
Mat srcImage; //原图像Mat templateImage;//模板图像Mat resultImage; //输出结果
载入原图像和模板图像
srcImage = imread("map.png", 1);
templateImage = imread("img1.png", 1);
/*Mat imread(const string& filename, int flags)filename为文件路径flags为读入类型,-1为解码得到的图像,0为单通道读入图像,即灰白图像,1为三通道读入图像,即彩色 图像
*/
初始化用于结果输出的矩阵
int resultImage_rows = srcImage.rows - templateImage.rows + 1;
int resultImage_cols = srcImage.cols - templateImage.cols + 1;
resultImage.create(resultImage_rows, resultImage_cols, CV_32FC1);
/*create(rows,cols,type)CV_32FC1为单通道图像,CV_32FC3为三通道图像*/
进行匹配和标准化
matchTemplate(srcImage, templateImage, resultImage, MatchMethod);
/*void matchTemplate(InputArray image, InputArray temp, OutputArray result, int method)image: 输入原图像temp: 输入模板图像result: 输出的相关系数矩阵method: 匹配方法平方差匹配法CV_TM_SQDIFF归一化平方差匹配法CV_TM_SQDIFF_NORMED相关匹配法CV_TM_CCORR归一化相关匹配法CV_TM_CCORR_NORMED相关系数匹配法CV_TM_CCOEFF归一化相关系数匹配法CV_TM_CCOEFF_NORMED
*/
这五种匹配方法的公式分别是

normalize(resultImage, resultImage, 0, 1, NORM_MINMAX, -1, Mat());
/*void normalize(const InputArray src, OutputArray dst, double alpha, double beta, int normType, int rtype, InputArray mask)src为输入数组dst为输出数组alpha为规范下限beta为规范上限normtype为公式类型rtype为负数时,输出数组的type与输入数组的type相同;否则,输出数组与输入数组只是通道数相同mask为掩膜,选择感兴趣区域,选定后只能对该区域进行操作。Mat()代表整幅图像
*/
通过函数 minMaxLoc 定位最匹配的位置
double minValue; double maxValue; Point minLocation; Point maxLocation;
/*定义最大值、最小值和最大值位置、最小值位置*/Point matchLocation;minMaxLoc(resultImage, &minValue, &maxValue, &minLocation, &maxLocation, Mat());
/*寻找图像中最小值最大值及它们的位置void minMaxLoc(InputArray src, double* minVal, double* maxVal=0, Point* minLoc=0, Point* maxLoc=0, InputArray mask=noArray())src:输入图像。minVal:最小值,可輸入NULL表示不需要。maxVal :最大值,可輸入NULL表示不需要。minLoc:最小值的位置,可输入NULL表示不需要,Point类型。maxLoc:最大值的位置,可输入NULL表示不需要,Point类型。mask:可有可无的掩模。
*/
对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值有着更高的匹配结果. 而其余的方法, 数值越大匹配效果越好
if (MatchMethod == TM_SQDIFF || MatchMethod == TM_SQDIFF_NORMED){matchLocation = minLocation;}else{matchLocation = maxLocation;}
绘制出矩形,并显示最终结果
rectangle(tempImage, matchLocation, Point(matchLocation.x + templateImage.cols, matchLocation.y + templateImage.rows), Scalar(0, 0, 255), 2, 8, 0);
/*void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,int thickness=1, int line_type=8, int shift=0 );img: 图像.pt1: 矩形的一个顶点。pt2: 矩形对角线上的另一个顶点color: 线条颜色 (RGB) 或亮度(灰度图像 )(grayscale image)。thickness: 组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。line_type: 线条的类型。见cvLine的描述shift: 坐标点的小数点位数。
*/
源代码的下载链接:
https://download.csdn.net/download/weixin_42521239/11147622
如果没有积分的小伙伴也可以在评论里留下你的邮箱,我发给你。















