參考http://www.cnblogs.com/xrwang/archive/2010/02/05/MatchTemplate.html和"learning openCV"
模板匹配的工作方式
模板匹配的工作方式跟直方圖的反向投影基本一樣,大致過程是這樣的:通過在輸入圖像上滑動圖像塊對實際的圖像塊和輸入圖像進行匹配。
假設我們有一張100x100的輸入圖像,有一張10x10的模板圖像,查找的過程是這樣的:
(1)從輸入圖像的左上角(0,0)開始,切割一塊(0,0)至(10,10)的臨時圖像;
(2)用臨時圖像和模板圖像進行對比,對比結果記爲c;
(3)對比結果c,就是結果圖像(0,0)處的像素值;
(4)切割輸入圖像從(0,1)至(10,11)的臨時圖像,對比,並記錄到結果圖像;
(5)重複(1)~(4)步直到輸入圖像的右下角。
大家可以看到,直方圖反向投影對比的是直方圖,而模板匹配對比的是圖像的像素值;模板匹配比直方圖反向投影速度要快一些,但是我個人認爲直方圖反向投影的魯棒性會更好。
模板匹配的匹配方式
在OpenCv和EmguCv中支持以下6種對比方式:
CV_TM_SQDIFF 平方差匹配法:該方法採用平方差來進行匹配;最好的匹配值爲0;匹配越差,匹配值越大。
CV_TM_CCORR 相關匹配法:該方法採用乘法操作;數值越大表明匹配程度越好。
CV_TM_CCOEFF 相關係數匹配法:1表示完美的匹配;-1表示最差的匹配。
CV_TM_SQDIFF_NORMED 歸一化平方差匹配法
CV_TM_CCORR_NORMED 歸一化相關匹配法
CV_TM_CCOEFF_NORMED 歸一化相關係數匹配法
[code]#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <stdio.h>
int main( int argc, char** argv ) {
IplImage *src, *templ,*ftmp[6]; //ftmp will hold results
int i;
if( argc == 3){
//Read in the source image to be searched:
if((src=cvLoadImage(argv[1], 1))== 0) {
printf("Error on reading src image %s/n",argv[i]);
return(-1);
}
//Read in the template to be used for matching:
if((templ=cvLoadImage(argv[2], 1))== 0) {
printf("Error on reading template %s/n",argv[2]);
return(-1);
}
//ALLOCATE OUTPUT IMAGES:
int iwidth = src->width - templ->width + 1;
int iheight = src->height - templ->height + 1;
for(i=0; i<6; ++i){
ftmp[i] = cvCreateImage(
cvSize(iwidth,iheight),32,1);
}
//DO THE MATCHING OF THE TEMPLATE WITH THE IMAGE:
for(i=0; i<6; ++i){
cvMatchTemplate( src, templ, ftmp[i], i);
cvNormalize(ftmp[i],ftmp[i],1,0,CV_MINMAX);
}
//DISPLAY
cvNamedWindow( "Template", 0 );
cvShowImage( "Template", templ );
cvNamedWindow( "Image", 0 );
cvShowImage( "Image", src );
cvShowImage( "SQDIFF", ftmp[0] );
cvNamedWindow( "SQDIFF_NORMED", 0 );
cvShowImage( "SQDIFF_NORMED", ftmp[1] );
cvNamedWindow( "CCORR", 0 );
cvShowImage( "CCORR", ftmp[2] );
cvNamedWindow( "CCORR_NORMED", 0 );
cvShowImage( "CCORR_NORMED", ftmp[3] );
cvNamedWindow( "CCOEFF", 0 );
cvShowImage( "CCOEFF", ftmp[4] );
cvNamedWindow( "CCOEFF_NORMED", 0 );
cvShowImage( "CCOEFF_NORMED", ftmp[5] );
//LET USER VIEW RESULTS:
cvWaitKey(0);
}
else { printf("Call should be: "
"match Template image template /n");}
}
[/code]
測試結果: