opencv-C++_模板匹配_matchTemplate

版权声明:本文为博主原创文章,转载请标明出处! https://blog.csdn.net/qq_27396861/article/details/87894153

模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块,对实际图像块和输入图像进行匹配的一种匹配方法。

实现模板匹配:matchTemplate()函数
用于匹配出和模板重叠的图像区域;
函数原型C++

void matchTemplate( InputArray image, InputArray temp1, OutputArray result, int method )

【1】InputArray类型的image,待搜索的图像,且需为8位或32位浮点型图像;
【2】InputArray类型的temp1,搜索模板,需和源图片有一样的数据类型,且尺寸不能大于源图像;
【3】OutputArray类型的result,比较结果的映射图像,其必须为单通道、32位浮点型图像,如果图像尺寸是W x H而temp1尺寸是wxh,则此参数result一定是(W-w + 1)x(H-h+1);
【4】int类型的method,指定的匹配方法,提供一下6种方法:

  1. 平方差匹配法 method = TM_SQDIFF,使用平方差来进行匹配,最好匹配为0。
    而若匹配越差,匹配值则越大。(说明最黑的地方是匹配最好的地方)
  2. 归一化平方差匹配法:method = TM_SQDIFF_NORMED,最好匹配为0。
  3. 相关匹配法:method = TM_CCORR,这类方法才用模板和图像间的乘法操作,所以较大
    的数表示匹配程序较高,0标识最坏的匹配效果。
  4. 归一化相关匹配法 method = TM_CCORR_NORMED;最坏匹配为0。
  5. 系数匹配法method = TM_CCOEFF;最好匹配为1;
  6. 化相关系数匹配法method = TM_CCOEFF_NORMED;最好匹配为1。

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

程序实例:

#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

using namespace cv;
using namespace std;

Mat g_srcImage, g_tempalteImage, g_resultImage;
int g_nMatchMethod;
int g_nMaxTrackbarNum = 5;


void on_matching(int, void*)
{
	Mat srcImage;
	g_srcImage.copyTo(srcImage);
	int resultImage_cols = g_srcImage.cols - g_tempalteImage.cols + 1;
	int resultImage_rows = g_srcImage.rows - g_tempalteImage.rows + 1;
	g_resultImage.create(resultImage_cols, resultImage_rows, CV_32FC1);

	matchTemplate(g_srcImage, g_tempalteImage, g_resultImage, g_nMatchMethod);
	normalize(g_resultImage, g_resultImage, 0, 1, NORM_MINMAX, -1, Mat());
	double minValue, maxValue;
	Point minLocation, maxLocation, matchLocation;
	minMaxLoc(g_resultImage, &minValue, &maxValue, &minLocation, &maxLocation);

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

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

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

}

int main()
{
	g_srcImage = imread("curry.jpg");
	if (!g_srcImage.data)
	{
		cout << "原始图读取失败" << endl;
		return -1;
	}
	g_tempalteImage = imread("curry2.jpg");
	if (!g_tempalteImage.data)
	{
		cout << "模板图读取失败" << endl;
		return -1;
	}

	imshow("g_srcImage", g_srcImage);
	imshow("g_tempalteImage", g_tempalteImage);

	namedWindow("原始图", CV_WINDOW_AUTOSIZE);
	namedWindow("效果图", CV_WINDOW_AUTOSIZE);
	createTrackbar("方法", "原始图", &g_nMatchMethod, g_nMaxTrackbarNum, on_matching);

	on_matching(0, NULL);


	waitKey(0);

	return 0;
}

可以看到有些方法也是匹配不上的;

原始图片:
在这里插入图片描述

模板图片:
在这里插入图片描述

运行结果

在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_27396861/article/details/87894153