一、模板匹配

模板匹配(TemplateMatching)就是在一幅图像中寻找和模板图像(template)最相似的区域,该方法原理简单计算速度快,能够应用于目标识别,目标跟踪等多个领域。

二、原理

1、cv::TM_SQDIFF:该方法使用平方差进行匹配,因此最佳的匹配结果在结果为0处,值越大匹配结果越差。

2、cv::TM_SQDIFF_NORMED:该方法使用归一化的平方差进行匹配,最佳匹配也在结果为0处。

3、cv::TM_CCORR:相关性匹配方法,该方法使用源图像与模板图像的卷积结果进行匹配,因此,最佳匹配位置在值最大处,值越小匹配结果越差。

4、cv::TM_CCORR_NORMED:归一化的相关性匹配方法,与相关性匹配方法类似,最佳匹配位置也是在值最大处。

5、cv::TM_CCOEFF:相关性系数匹配方法,该方法使用源图像与其均值的差、模板与其均值的差二者之间的相关性进行匹配,最佳匹配结果在值等于1处,最差匹配结果在值等于-1处,值等于0直接表示二者不相关。

6、cv::TM_CCOEFF_NORMED:归一化的相关性系数匹配方法,正值表示匹配的结果较好,负值则表示匹配的效果较差,也是值越大,匹配效果也好。

三、API

MatchTemplate(
 InputArrray image,  //源图像
InputArray templ,   //模板图像
OutputArray result,//输出结果  必须是单通道32位浮点数,假设源图像WxH,模版图像  w*h,到结果必须为W-w+1,H-h+1的大小
int method   // 匹配方法,使用不同的方法产生的结果的意义可能不太一样,有些返回的值越大表示匹配程度越好,而有些方法返回的值越小表示匹配程度越好

关于参数 method:

CV_TM_SQDIFF平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
CV_TM_CCORR相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
CV_TM_CCOEFF相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。
CV_TM_SQDIFF_NORMED归一化平方差匹配法
CV_TM_CCORR_NORMED归一化相关匹配法
CV_TM_CCOEFF_NORMED归一化相关系数匹配法
);

四、代码显示

模板匹配角度问题 python 模板匹配算法的原理_计算机视觉

 

#if  1 // 模板匹配  有六种方法
Mat src, tempalte, result;
int matchMethod;
int maxTrackbarType = 5;


void on_matching(int, void*)
{
	Mat srcImage;
	src.copyTo(srcImage);
	int result_cols = src.cols - tempalte.cols + 1;
	int result_rows = src.rows - tempalte.rows + 1;


	cout << "---- result_rows----: " << result_rows << endl;
	cout << "---- result_cols----: " << result_cols << endl;



	result.create(result_cols, result_rows, CV_32FC1);

	// 开始匹配
	matchTemplate(src, tempalte, result, matchMethod);


	normalize(result, result, 0, 2, NORM_MINMAX, -1, Mat());

	double minValue, maxValue;

	Point minLocation, maxLocation, matchLocation;
	minMaxLoc(result, &minValue, &maxValue, &minLocation, &maxLocation);

	if (matchMethod == TM_SQDIFF || matchMethod == CV_TM_SQDIFF_NORMED)
	{
		matchLocation = minLocation;
	}
	else
	{
		matchLocation = maxLocation;
	}

	rectangle(srcImage, matchLocation, Point(matchLocation.x + tempalte.cols, matchLocation.y + tempalte.rows), Scalar(0, 0, 255), 2, 8, 0);
	rectangle(result, matchLocation, Point(matchLocation.x + tempalte.cols, matchLocation.y + tempalte.rows), Scalar(0, 0, 255), 2, 8, 0);

	imshow("原始图", srcImage);
	imshow("效果图", result);

}

int main()
{

	src = imread("C:\\Users\\19473\\Desktop\\opencv_images\\609.png");
	if (!src.data)
	{
		cout << "原始图读取失败" << endl;
		return -1;
	}
	cout << "原目标图像  " << src.rows << "    ,    " << src.cols << endl;
	tempalte = imread("C:\\Users\\19473\\Desktop\\opencv_images\\610.png");
	if (!tempalte.data)
	{
		cout << "模板图读取失败" << endl;
		return -1;
	}
	cout << "目标目标图像  " << tempalte.rows << "    ,    " << tempalte.cols << endl;


	imshow("模板", tempalte);
	namedWindow("原始图", CV_WINDOW_AUTOSIZE);
	namedWindow("效果图", CV_WINDOW_AUTOSIZE);
	createTrackbar("方法", "原始图", &matchMethod, maxTrackbarType, on_matching);

	on_matching(0, NULL);


	waitKey(0);

	return 0;
}
#endif