opencv学习笔记(三十二)模板匹配
来源:互联网 发布:这个男人来自地球 知乎 编辑:程序博客网 时间:2024/06/04 17:40
模板匹配的工作方式
模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。
假设我们有一张100x100的输入图像,有一张10x10的模板图像,查找的过程是这样的:
(1)从输入图像的左上角(0,0)开始,切割一块(0,0)至(10,10)的临时图像;
(2)用临时图像和模板图像进行对比,对比结果记为c;
(3)对比结果c,就是结果图像(0,0)处的像素值;
(4)切割输入图像从(0,1)至(10,11)的临时图像,对比,并记录到结果图像;
(5)重复(1)~(4)步直到输入图像的右下角。
大家可以看到,直方图反向投影对比的是直方图,而模板匹配对比的是图像的像素值;模板匹配比直方图反向投影速度要快一些,但是我个人认为直方图反向投影的鲁棒性会更好。
参考的是:
http://www.cnblogs.com/xrwang/archive/2010/02/05/MatchTemplate.html
cvMatchTemplate()函数
http://www.lxway.com/914114412.htm
定义:
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)。
所以在下面的程序中,才会有
int iwidth = src->width - temp1->width + 1;
int iheight = src->height - temp1->height + 1;
method 指定匹配方法:
在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 归一化相关系数匹配法
根据我的测试结果来看,上述几种匹配方式需要的计算时间比较接近(跟《学习OpenCv》书上说的不同),我们可以选择一个能适应场景的匹配方式。
cvMinMaxLoc()函数
通过使用 cvMinMaxLoc函数,我们确定结果矩阵 R 的最大值和最小值的位置。cvMinMaxLoc()必须对单通道做处理。
函数中的参数有:
double minVal; double maxVal; Point minLoc; Point maxLoc;
Point matchLoc;
格式:
cvMinMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );
result: 匹配结果矩阵
&minVal 和 &maxVal: 在矩阵 result 中存储的最小值和最大值。该值是矩阵中的最大值和最小值。
&minLoc 和 &maxLoc: 在结果矩阵中最小值和最大值的坐标.
Mat(): 可选的掩模
程序实例:
代码来自:
http://www.lxway.com/914114412.htm
#include <iostream>#include <cv.h>#include <highgui.h>#include <cxcore.h>using namespace std;void GetHSV(const IplImage *image,IplImage **h,IplImage **s,IplImage **v);int main(){ IplImage *src = cvLoadImage("t1.jpg"); IplImage *h_src = NULL ,*s_src = NULL; GetHSV(src,&h_src,&s_src,NULL); IplImage *images[] = {h_src,s_src}; CvHistogram *hist_src; {//计算二维直方图 int dims = 2; int size[] = {30,32}; // 这个地方不要取的太大! float range_h[] = {0,180} //再用cvCvtColor转换时h已经归一化到180了 ,range_s[] = {0,256}; float *ranges[] = {range_h,range_s}; hist_src = cvCreateHist(dims,size,CV_HIST_ARRAY,ranges); cvCalcHist(images,hist_src); cvNormalizeHist(hist_src,1); } IplImage *dst = cvLoadImage("t2.jpg"); IplImage *h_dst = NULL,*s_dst = NULL; GetHSV(dst,&h_dst,&s_dst,NULL); images[0] = h_dst ,images[1] = s_dst; CvSize patch_size = cvSize(src->width,src->height); IplImage *result = cvCreateImage(cvSize(h_dst->width - patch_size.width +1,h_dst->height - patch_size.height +1) ,IPL_DEPTH_32F,1);//块搜索时处理边缘是直接舍去,故result的大小比dst小path_size大小 //32F类型,取值为0~1最亮为1,可直接显示 //CV_COMP_CORREL相关度,1时最匹配,0时最不匹配 cvCalcBackProjectPatch(images,result,patch_size,hist_src,CV_COMP_CORREL,1); cvShowImage("result",result); //找出最大值位置,可得到此位置即为杯子所在位置 CvPoint max_location; cvMinMaxLoc(result,NULL,NULL,NULL,&max_location,NULL); //加上边缘,得到在原始图像中的实际位置 max_location.x += cvRound(patch_size.width/2); max_location.y += cvRound(patch_size.height/2); //在dst图像中用红色小圆点标出位置——小圆点就表示杯子所在区域 cvCircle(dst,max_location,3,CV_RGB(255,0,0),-1); cvShowImage("dst",dst); cvWaitKey(); cvReleaseImage(&src); cvReleaseImage(&dst); cvReleaseImage(&h_src); cvReleaseImage(&h_dst); cvReleaseImage(&s_dst); cvReleaseImage(&s_src); cvReleaseHist(&hist_src); cvReleaseImage(&result); cvDestroyAllWindows();}void GetHSV(const IplImage *image , IplImage **h,IplImage **s,IplImage **v){ IplImage *hsv = cvCreateImage(cvGetSize(image),8,3); cvCvtColor(image,hsv,CV_BGR2HSV); if((h != NULL) && (*h == NULL)) *h = cvCreateImage(cvGetSize(image),8,1); if((s != NULL) && (*s == NULL)) *s = cvCreateImage(cvGetSize(image),8,1); if((v != NULL) && (*v == NULL)) *v = cvCreateImage(cvGetSize(image),8,1); cvSplit(hsv,*h,(s == NULL)?NULL:*s,(v==NULL)?NULL:*v,NULL); cvReleaseImage(&hsv);}
运行结果
用到的图片和上一个实验一样,就不传了。最终结果是用红色的小圆点标记出杯子的位置。
- opencv学习笔记(三十二)模板匹配
- OpenCV 学习笔记(模板匹配)
- OpenCV学习笔记(十七)模板匹配
- 【OpenCV学习笔记】【算法学习】一(模板匹配)
- OpenCV学习笔记(十三)——模板匹配
- OpenCV学习笔记(十三)——模板匹配
- Opencv Python版学习笔记(三)模板匹配
- OpenCV学习笔记(5)——模板匹配
- OpenCV学习笔记[4]模板匹配
- Python+OpenCV学习(7)---模板匹配
- JAVA学习笔记(三十二)
- 【openCV笔记1】模板匹配
- opencv笔记之模板匹配
- OpenCV 2 学习笔记(26): 自选区域进行模板匹配
- opencv学习之模板匹配
- Opencv学习之模板匹配
- OpenCV学习2 模板匹配
- 【OpenCV学习笔记】三十二、分水岭算法及图像修补
- OpenFace做人脸识别
- Android led灯实现大致流程
- 合并列表中有相同元素的列表
- 删除windows中服务项目记录
- RTP的有效负载类型
- opencv学习笔记(三十二)模板匹配
- JAVA线程池
- Raspi物体检测
- Spring AOP详解
- 批量删除execl单元格第一个字符`
- C链栈基础
- 获得当前窗口的hwnd的方法整理
- leetCode 264. Ugly Number II
- 值得推荐的C/C++框架和库 (真的很强大)