这里指模板匹配的方法之一:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
调用函数:
MatchTemplate
在输入的源图像中与模板图像作重叠比较
void cvMatchTemplate( const CvArr* image, const CvArr* templ, CvArr* result, int method );
-
image
- 被搜索的输入图像。它应该是单通道、8-比特或32-比特 浮点数图像 templ
- 搜索模板,不能大于输入图像,且与输入图像具有一样的数据类型 result
- 比较结果的映射图像。单通道、32-比特浮点数. 如果图像是 W×H 而 templ 是 w×h ,则 result 一定是 (W-w+1)×(H-h+1). method
- 指定匹配方法:
函数 cvMatchTemplate 与函数 cvCalcBackProjectPatch 类似。它滑动过整个图像 image, 用指定方法比较 templ 与图像尺寸为 w×h 的重叠区域,并且将比较结果存到 result 中。 下面是不同的比较方法,可以使用其中的一种 (I 表示图像,T - 模板, R - 结果. 模板与图像重叠区域 x'=0..w-1, y'=0..h-1 之间求和):
-
method=CV_TM_SQDIFF(平方差):
-
R(x,y) = ∑ [T(x',y') − I(x + x',y + y')]2 x',y'
-
-
method=CV_TM_SQDIFF_NORMED:
-
method=CV_TM_CCORR(互相关):
-
method=CV_TM_CCORR_NORMED:
-
method=CV_TM_CCOEFF(归零化互相关):
- ,
-
其中
- (mean template brightness=>0)
- (mean patch brightness=>0)
-
method=CV_TM_CCOEFF_NORMED:
函数完成比较后,通过使用cvMinMaxLoc找全局最小值CV_TM_SQDIFF*) 或者最大值 (CV_TM_CCORR* and CV_TM_CCOEFF*)。
实现代码:
/*
模板匹配
*/
#include "highgui.h"
#include "cv.h"
void domatch(IplImage* img)
{
IplImage* templ = cvLoadImage("ad.gif");
int iwidth = img->width - templ->width +1;
int iheight = img->height -templ->height +1;
IplImage* ftmp = cvCreateImage(cvSize(iwidth, iheight),32,1);
double minv;
double maxv;
CvPoint minl;
CvPoint maxl;
cvMatchTemplate(img, templ, ftmp, 0);
cvMinMaxLoc(ftmp, &minv,&maxv,&minl,&maxl,NULL);
cvRectangle(img,cvPoint(minl.x, minl.y),cvPoint((minl.x+templ->width),(minl.y + templ->height)),CV_RGB(255,0,0),1);
cvNamedWindow("match",1);
cvShowImage("match",img);
cvWaitKey(0);
}
原图像:
匹配部分:
匹配结果:
参考代码: