15.1 引言

       模板匹配就是在给定的图像中,通过计算模板与图片对应区域的匹配度,查找与模板最相似的区域。模板匹配的核心其实就是将模板与源图像的每个区域进行比较,逐像素滑动。从本质上讲,是将模板在源图像上进行卷积,创建新的图像或矩阵,其中每个像素值表示模板与源图像中相应区域之间的相似性。分析结果图像,可以通过峰值找到与模板匹配的紧缺位置。

15.2 匹配度量方式

15.2.1 平方差TM_SQDIFF

模板与源图像对应像素值的平方差的和。值越小匹配度越高(0)

opencv 旋转目标检测_opencv 旋转目标检测

15.2.2  归一化平方差TM_SQDIFF_NORMED

值越小匹配度越高(0)

opencv 旋转目标检测_模板匹配_02

15.2.3 相关性TM_CCORR

模板与源图像对应像素值的乘积和。值越大匹配度越高

opencv 旋转目标检测_opencv_03

15.2.4 归一化相关性TM_CCORR_NORMED

值越大匹配度越高,越接近1,效果越好。

opencv 旋转目标检测_opencv 旋转目标检测_04

15.2.5 相关性系数TM_CCOEFF

模板与源图像对应像素将去其各自区域的均值后的像素值的乘积和。最佳匹配结果在值等于1处,最差匹配结果在值等于-1处,值等于0直接表示二者不相关。

opencv 旋转目标检测_计算机视觉_05

opencv 旋转目标检测_opencv_06

opencv 旋转目标检测_opencv_07

15.2.6 归一化相关性系数TM_CCOEFF_NORMED

正值表示匹配的结果较好,负值则表示匹配的效果较差。 越接近1,效果越好

opencv 旋转目标检测_opencv 旋转目标检测_08

15.3 相关API

·void matchTemplate( InputArray image, OutputArray templ, OutputArray result, int method, InputArray mask=noArray())

参数

含义

作用

根据模板在一幅图像中找到匹配的区域

输入

image

源图像,必须是8bit或32bit浮点数图像

templ

模板图像,类型与源图像一致

result

输出保存结果的矩阵,32F类型。假设源图像W*H,模板w*h,则结果矩阵大小为W-w+1*H-h+1,

method

使用的匹配方式,见15.2

mask

返回值

void


15.4 代码示例

Mat src, temp, dst;
int matchMethod = TM_SQDIFF;
int maxTrack = 5;
const char* INPUTWIN = "srcimg";
const char* OUTPUTWIN = "dstimg";
const char* MATCH = "tempimg";
void matchCallback(int,void*)
{
	int width = src.cols - temp.cols + 1;
	int height = src.rows - temp.rows + 1;
	Mat result(width, height,CV_32FC3);

	matchTemplate(src,temp,result,matchMethod);

	//遭到匹配上的位置
	Point minPos;
	Point maxPos;
	double min, max;
	src.copyTo(dst);
	Point tempPos;
	minMaxLoc(result,&min,&max,&minPos,&maxPos,Mat());
	if (matchMethod == TM_SQDIFF || matchMethod == TM_SQDIFF_NORMED)
	{
		tempPos = minPos;
	}
	else
	{
		tempPos = maxPos;
	}

	//矩形绘制
	rectangle(dst,Rect(tempPos.x, tempPos.y,temp.cols,temp.rows),Scalar(0,0,255),2);
	rectangle(result, Rect(tempPos.x, tempPos.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2);

	imshow(OUTPUTWIN, dst);
	imshow(MATCH, result);
}

int main(int argc, char** argv)
{
	//源图像
	src = imread("D:\\testimg\\CSet12\\lena.png");
	//模板图像
	temp = imread("D:\\testimg\\CSet12\\lenaTemp.png");
	if (src.empty()|| temp.empty())
	{
		printf("Could not load the image...\n");
		return -1;
	}
	else;

	namedWindow(INPUTWIN, WINDOW_AUTOSIZE);
	imshow(INPUTWIN, src);
	namedWindow(OUTPUTWIN, WINDOW_AUTOSIZE);
	namedWindow(MATCH, WINDOW_AUTOSIZE);
	imshow("temp",temp);

	const char* trackbarTitle = "Method";
	createTrackbar(trackbarTitle, OUTPUTWIN,&matchMethod,maxTrack,matchCallback);
	matchCallback(0,0);


	waitKey(0);
	return 0;
}

opencv 旋转目标检测_opencv_09

15.5 模板匹配的不足

  1. 不同的图像需要需要按实际测验匹配方式的有效性;
  2. 目标与模板大小不一致时,小模板无法检测大目标;
  3. 目标与模板方向不一致,会导致无法识别;

不具有旋转不变性、不具有尺度不变性