这个比较好玩,先来两张照片
原图:
模板:
效果:
原理:
假设有100*100像素的一张原图,模板大小5*5像素,从(0,0)开始,根据不同的方法匹配模板大小即(0,0)到(5,5)空间,把用方法得到的值算作(0,0)这个像素的特征值,接下来重新从(0,1),按照这样从左到右,从上到下。
API:
CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ,
OutputArray result, int method, InputArray mask = noArray() );
imag:原图像
temp1:模板图像
result:使用method得到的结果,也就是像素特征值集合。
method:方法:有以下6种
差值平方和匹配 CV_TM_SQDIFF
标准化差值平方和匹配 CV_TM_SQDIFF_NORMED
相关匹配 CV_TM_CCORR
标准相关匹配 CV_TM_CCORR_NORMED
相关匹配 CV_TM_CCOEFF
标准相关匹配 CV_TM_CCOEFF_NORMED
其中CV_TM_SQDIFF和 CV_TM_SQDIFF_NORMED值越小说明匹配度越高,取值为0~1
#include <iostream>
#include <opencv.hpp>
using namespace cv;
using namespace std;
char *name="Window";
int current=CV_TM_CCOEFF;//5
int max_value=5;
void cal_back(int ,void *);
Mat src,mould;
int main()
{
src=imread("E:\\opencv\\yibu.jpg");
mould=imread("E:\\opencv\\templt.jpg");
namedWindow(name);
createTrackbar("method",name,¤t,max_value,cal_back);
cal_back(0,0);
waitKey(0);
return 0;
}
void cal_back(int ,void *)
{
Mat dst;
int width=src.cols-mould.cols+1;
int height=src.rows-mould.rows+1;
Mat result;
result.create(width,height,CV_32FC1);
matchTemplate(src,mould,result,current,Mat());
normalize(result,result,0,1,NORM_MINMAX);
Point minloc;
Point maxloc;
double mymin,mymax;
minMaxLoc(result,&mymin,&mymax,&minloc,&maxloc,Mat());
cout<<"mymin"<<mymin;
cout<<"mymax"<<mymax;
src.copyTo(dst);
Point temploc;
if(current==CV_TM_SQDIFF||current==CV_TM_SQDIFF_NORMED)
{
temploc=minloc;
}else{
temploc=maxloc;
}
rectangle(dst,Rect(temploc.x,temploc.y,mould.cols,mould.rows),
Scalar(0,0,255),2,LINE_AA);
rectangle(result,Rect(temploc.x,temploc.y,mould.cols,mould.rows),
Scalar(0,0,255),2,LINE_AA);
imshow(name,result);
imshow("dst",dst);
imwrite("dst.jpg",dst);
}