/*cv20 by txwtech——opencv3.0
模板匹配(Template Matching)算法模板匹配(Template Matching)是图像识别中最具代表性的方法之一。 它从待识别图像中提取若干特征向量与模板对应的特征向量进行比较, 计算图像与模板特征向量之间的距离,用最小距离法判定所属类别。 模板匹配通常事先建立好标准模板库。
模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。 所以模板匹配首先需要一个模板图像T(给定的子图像) 另外需要一个待检测的图像-源图像S 工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。
模板匹配的工作方式 模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。 假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的: (1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像; (2)用临时图像和模板图像进行对比,对比结果记为c; (3)对比结果c,就是结果图像(0,0)处的像素值; (4)切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到结果图像; (5)重复(1)~(4)步直到输入图像的右下角。 可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值; 模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。
模板匹配的匹配方式
minMaxLoc(dst2,&min,&max,&minPos,&maxPos,Mat());
在OpenCv和EmguCv中支持以下6种对比方式:CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。判断min值 CV_TM_SQDIFF_NORMED 归一化平方差匹配法,最好的匹配值为0;匹配越差,匹配值越大。判断min值
CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。判断max值,经测试此方式效果差 CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。判断max值
CV_TM_CCORR_NORMED 归一化相关匹配法,1表示完美的匹配;-1表示最差的匹配。判断max值 CV_TM_CCOEFF_NORMED 归一化相关系数匹配法,1表示完美的匹配;-1表示最差的匹配。判断max值
matchTemplate(
InputArray image,// 源图像,必须是8-bit或者32-bit浮点数图像
InputArray templ,// 模板图像,类型与输入图像一致
OutputArray result,// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh, 则结果必须为W-w+1, H-h+1的大小。 int method,//使用的匹配方法
InputArray mask=noArray()//(optional) )
测试发现一个问题:当模板在原图上占据大于50%的空间时,匹配后的目标图像会很小。与原图小很多。
*/
/*cv20 by txwtech
模板匹配(Template Matching)算法
模板匹配(Template Matching)是图像识别中最具代表性的方法之一。
它从待识别图像中提取若干特征向量与模板对应的特征向量进行比较,
计算图像与模板特征向量之间的距离,用最小距离法判定所属类别。
模板匹配通常事先建立好标准模板库。
模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域。
所以模板匹配首先需要一个模板图像T(给定的子图像)
另外需要一个待检测的图像-源图像S
工作方法,在带检测图像上,从左到右,从上向下计算模板图像与重叠子图像的匹配度,匹配程度越大,两者相同的可能性越大。
模板匹配的工作方式
模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)用临时图像和模板图像进行对比,对比结果记为c;
(3)对比结果c,就是结果图像(0,0)处的像素值;
(4)切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到结果图像;
(5)重复(1)~(4)步直到输入图像的右下角。
可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值;
模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。
模板匹配的匹配方式
minMaxLoc(dst2,&min,&max,&minPos,&maxPos,Mat());
在OpenCv和EmguCv中支持以下6种对比方式:
CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。判断min值
CV_TM_SQDIFF_NORMED 归一化平方差匹配法,最好的匹配值为0;匹配越差,匹配值越大。判断min值
CV_TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。判断max值,经测试此方式效果差
CV_TM_CCOEFF 相关系数匹配法:1表示完美的匹配;-1表示最差的匹配。判断max值
CV_TM_CCORR_NORMED 归一化相关匹配法,1表示完美的匹配;-1表示最差的匹配。判断max值
CV_TM_CCOEFF_NORMED 归一化相关系数匹配法,1表示完美的匹配;-1表示最差的匹配。判断max值
matchTemplate(
InputArray image,// 源图像,必须是8-bit或者32-bit浮点数图像
InputArray templ,// 模板图像,类型与输入图像一致
OutputArray result,// 输出结果,必须是单通道32位浮点数,假设源图像WxH,模板图像wxh,
则结果必须为W-w+1, H-h+1的大小。
int method,//使用的匹配方法
InputArray mask=noArray()//(optional)
)
测试发现一个问题:当模板在原图上占据大于50%的空间时,匹配后的目标图像会很小。与原图小很多。
*/
#include
#include
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
Mat src;
//Mat dst2;
Mat dst3;
Mat src_template;
// src = imread("e:\\pictures\\荷花2.jpg",CV_LOAD_IMAGE_COLOR);
// src_template = imread("e:\\pictures\\荷花2_template_match.jpg", CV_LOAD_IMAGE_COLOR);
src = imread("e:\\pictures\\flower1.jpg");
src_template = imread("e:\\pictures\\flower1_template.jpg");
if (!src.data)
{
printf("failed to load image");
return 0;
}
namedWindow("原图模板",CV_WINDOW_AUTOSIZE);
imshow("原图模板", src_template);
//int width = src.cols-src_template.cols+1 ;
//int height = src.rows-src_template.rows+1 ;
//dst2.create(Size(width, height),CV_32FC1);
// Mat dst2(width,height,CV_32FC1);
//模板匹配API
Mat dst2;
//CV_TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;最好的匹配值为0;匹配越差,匹配值越大。
matchTemplate(src,src_template, dst2, CV_TM_SQDIFF);//平方不同,取最小值。其余取最大值 //min=0,max=1
//matchTemplate(src, src_template, dst2, CV_TM_CCORR);//min=0,max=1,匹配效果不好
//matchTemplate(src, src_template, dst2, CV_TM_CCOEFF);//min=-2.9,max=1
//matchTemplate(src, src_template, dst2, CV_TM_SQDIFF_NORMED);//平方不同,取最小值min=0,max=0.99
//matchTemplate(src, src_template, dst2, CV_TM_CCORR_NORMED);//min=0,max=1
//matchTemplate(src, src_template, dst2, CV_TM_CCOEFF_NORMED);//min=0,max=1
//归一化处理
normalize(dst2, dst2,0,1,NORM_MINMAX,-1,Mat());
Point minPos;
Point maxPos;
Point tempPos;
double max, min;
src.copyTo(dst3);//拷贝原图
//取结果的最大值与最小值
minMaxLoc(dst2,&min,&max,&minPos,&maxPos,Mat());
//绘制矩形在原图与目标图形(CV_TM_SQDIFF,CV_TM_SQDIFF_NORMED),平方不同,取minPos
rectangle(dst3,Rect(minPos.x, minPos.y,src_template.cols,src_template.rows),Scalar(0,0,255),2,6);
rectangle(dst2, Rect(minPos.x, minPos.y, src_template.cols, src_template.rows), Scalar(0, 0, 255), 2, 6);
//除了CV_TM_SQDIFF,CV_TM_SQDIFF_NORMED,其余都取maxPos
//rectangle(dst3, Rect(maxPos.x, maxPos.y, src_template.cols, src_template.rows), Scalar(0, 0, 255), 2, 8);
//rectangle(dst2, Rect(maxPos.x, maxPos.y, src_template.cols, src_template.rows), Scalar(0, 0, 255), 2, 8);
namedWindow("拷贝原图",CV_WINDOW_AUTOSIZE);
namedWindow("匹配结果", CV_WINDOW_AUTOSIZE);
imshow("拷贝原图", dst3);
imshow("匹配结果", dst2);
waitKey(0);
return 0;
}