1、模板匹配

模板匹配是在图像中寻找目标的方法之一。Come On, Boy.我们一起来看看模板匹配到底是怎么回事。

参考链接:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

http://www.cnblogs.com/xrwang/archive/2010/02/05/MatchTemplate.html

模板匹配的工作方式

模板匹配的工作方式跟直方图的反向投影基本一样,大致过程是这样的:通过在输入图像上滑动图像块对实际的图像块和输入图像进行匹配。

    假设我们有一张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 归一化相关系数匹配法

    根据我的测试结果来看,上述几种匹配方式需要的计算时间比较接近(跟《学习OpenCv》书上说的不同),我们可以选择一个能适应场景的匹配方式。

显示结果图像

    模板匹配和直方图反向投影生成的结果图像都是32位浮点型单通道图像

模板匹配和直方图反向投影的效率

总的来说,模板匹配和直方图反向投影的效率都不高。在我的机器上,在1136*852大小的输入图像上匹配104*132的大小的模板图像(都是单通道灰度图像),大约需要700毫秒;而直方图反向投影大约需要75000毫秒(1.25分钟)。看来还需要继续学习,寻找更好的处理方法。

    另一方面,通过搜索OpenCv的源代码,发现OpenCv基本上没有使用并行计算。如果学习完之后,还有时间和热情,我准备尝试优化下OpenCv的并行计算;如果.net 4.0正式版推出了,也可以选择在这一方面做点优化。

代码:

	// 用于存储匹配结果的矩阵
cv::Mat result;
int result_cols = minM.cols - tempMat.cols + 1;
int result_rows = minM.rows - tempMat.rows + 1;
result.create( result_cols, result_rows, CV_32FC1 ); // 进行模板匹配
int match_method = CV_TM_SQDIFF;
cv::matchTemplate( MatSrc, tempMat, result, match_method ); // 归一化结果(方便显示结果)
//cv::normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() ); // 找到最佳匹配位置
double minVal =0;
double maxVal =0;
cv::Point minLoc(0,0);
cv::Point maxLoc(0,0);
cv::Point matchLoc(0,0);
cv::Point matchCenter(0,0);
cv::Point matchSrc(0,0); cv::minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() ); // 寻找result中的最大和最小值,以及它们所处的像素位置 // 使用SQDIFF和SQDIFF_NORMED方法时:值越小代表越相似
// 使用其他方法时:值越大代表越相似
if( match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{
matchLoc = minLoc;
}
else
{
matchLoc = maxLoc;
}

2、Filter2d

OpenCv Filter2d进行二维卷积进行的是相关运算;

参考链接:http://blog.csdn.net/superdont/article/details/6662365

高通和低通滤波

#include "cv.h"
#include "highgui.h" int main(int argc,char**argv)
{
IplImage* src, *dst, src_f; float low[9] ={ 1.0/16, 2.0/16, 1.0/16, 2.0/16, 4.0/16, 2.0/16, 1.0/16, 2.0/16, 1.0/16 };//低通滤波核
float high[9]={-1,-1,-1,-1,9,-1,-1,-1,-1};//高通滤波核 CvMat km = cvMat( 3, 3, CV_32FC1, low); //构造单通道浮点矩阵,将图像IplImage结构转换为图像数组 src = cvLoadImage( "lena.jpg" );
st = cvCreateImage( cvGetSize(src), IPL_DEPTH_8U, 3 ); cvFilter2D( src, dst, &km, cvPoint( -1, -1 ) ); //设参考点为核的中心 cvNamedWindow( "src", 0 );
cvNamedWindow( "filtering", 0 ); cvShowImage( "src", src );
cvShowImage( "filtering", dst ); cvWaitKey(0);
cvReleaseImage( &src );
cvReleaseImage( &dst ); return 0;
}

3、通过傅里叶变换求图像卷积

参考链接:http://blog.csdn.net/lichengyu/article/details/18848281

各种滤波(平滑、锐化)的情况,基本方法都是将图像与一个核进行卷积实现。而卷积定理指出,两个函数的卷积的傅里叶变换等于各自的傅里叶变换的乘积,即:

[1]

那么,两个函数的卷积可以通过如下方式得到,对两个函数傅里叶变换的乘积做傅里叶反变换,即:

[1]

在进行卷积运算时,一般是将核沿着图像从左到右从上到下计算每一个像素处与核卷积后的值,这样的计算量较大,采用傅里叶变换的方法可以提高运算效率。

............................................

代码见原文章.....

需要注意的是,一般求法中,利用核游走整个图像进行卷积运算,实际上进行的是相关运算,真正意义上的卷积,应该首先把核翻转180度,再在整个图像上进行游走。OpenCV中的filter2D实际上做的也只是相关,而非卷积。"The function does actually compute correlation, not the convolution: ... That is, the kernel is not mirrored around the anchor point. If you need
a real convolution, flip the kernel using flip() and set the new anchor to (kernel.cols - anchor.x - 1, kernel.rows - anchor.y - 1)

OpenCV中的模板匹配/Filter2d的更多相关文章

  1. 使用Opencv中matchTemplate模板匹配方法跟踪移动目标

    模板匹配是一种在图像中定位目标的方法,通过把输入图像在实际图像上逐像素点滑动,计算特征相似性,以此来判断当前滑块图像所在位置是目标图像的概率. 在Opencv中,模板匹配定义了6种相似性对比方式: C ...

  2. 【计算机视觉】OpenCV篇(10) - 模式识别中的模板匹配

    什么是模式识别? 它指的是,对表征事物或现象的各种形式的信息进行处理和分析,从而达到对事物或现象进行描述.辨认.分类和解释的目的. 我们之所以可以很快辨别猫是猫.O不是0,就是因为在我们大脑中已经给猫 ...

  3. 使用OpenCV&&C++进行模板匹配.

    一:课程介绍 1.1:学习目标 学会用imread载入图像,和imshow输出图像. 用nameWindow创建窗口,用createTrackbar加入滚动条和其回调函数的写法. 熟悉OpenCV函数 ...

  4. 使用Python+OpenCV进行图像模板匹配(Match Template)

    2017年9月22日 BY 蓝鲸 LEAVE A COMMENT 本篇文章介绍使用Python和OpenCV对图像进行模板匹配和识别.模板匹配是在图像中寻找和识别模板的一种简单的方法.以下是具体的步骤 ...

  5. 【工程应用五】 opencv中linemod模板匹配算法诸多疑惑和自我解读。

    研究这个前前后后也有快两三个月了,因为之前也一直在弄模板匹配方面的东西,所以偶尔还是有不少朋友咨询或者问你有没有研究过linemod这个算法啊,那个效率啥的还不错啊,有段时间一直不以为然,觉得我现在用 ...

  6. opencv如何用模板匹配寻找目标

    首先使用: MatchTemplate 比较模板和重叠的图像区域 void cvMatchTemplate( const CvArr* image, const CvArr* templ, CvArr ...

  7. opencv 单目标模板匹配(只适用于模板与目标尺度相同)

    #include <iostream> #include "opencv/cv.h" #include "opencv/cxcore.h" #inc ...

  8. Opencv for android 模板匹配

    因为有这方面的需要所以,对模板查找搜寻了相关资料,只是对于算法的东西很难看得动,特别是opencv涉及的很多的数学方法. 所以只为了实现这个功能,因为需求比较简单,在网上也搜寻到了相关代码,就直接拿来 ...

  9. OPENCV中特征提取和匹配的步骤

    1.定义特征提取器和描述子提取器: cv::Ptr<cv::FeatureDetector> detector; cv::Ptr<cv::DescriptorExtractor> ...

随机推荐

  1. Huawei-R&S-网络工程师实验笔记20190530-FTP上传下载、STelnet登录、SFTP登录

    >Huawei-R&S-网络工程师实验笔记20190530-FTP上传下载.STelnet登录.SFTP登录 >>实验开始,参考<Huawei-R&S-网络工程 ...

  2. zookeeper概念与原理

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. 1 Zookeeper的基本概念 1.1 角色 ...

  3. 这书真的不错--Spring MVC Beginner's Guide

    五百多页,我干到三百多页了. 每个知识点都有说明,操作,解释. 学SPRING MVC,有它就够了. 遗憾的是,这个PDF的文档格式太稀松啦,且,无中文版~~~ 我都想作汉化翻译工作了...算了,忍住 ...

  4. BlockQueue中ArrayBlockingQueue和LinkedBlockingQueue比较

    LinkedBlockingQueue是BlockingQueue的一种使用Link List的实现,它对头和尾(取和添加操作)采用两把不同的锁,相对于ArrayBlockingQueue提高了吞吐量 ...

  5. QT中使用高速排序

    今天想到了用QT做一个高速排序.所以研究了一下. 由于用习惯了,C++的std::sort.就算是C的时候也用得是stdlib.h中的qsort. 手写板 手写板的快排事实上不难,仅仅是自从用C++打 ...

  6. swift 雨燕 新手教程

    Apple Swift编程语言新手教程 chox 2014-06-03 文件夹 简单介绍 入门 简单值 控制流 函数与闭包 对象与类 枚举与结构 1   简单介绍 今天凌晨Apple刚刚公布了Swif ...

  7. 专业函数画图软件Origin

    首先:Origin软件已经是科研院所等单位的必备工作软件之中的一个,之所以大家讨论得较少,有可能并非其上手难度低.而是这些使用人群的学习理解能力要相对高一点吧: 其次:Excel不垃圾,但在函数画图方 ...

  8. Buy or Build (poj 2784 最小生成树)

    Buy or Build Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1348   Accepted: 533 Descr ...

  9. bzoj 2252 [ 2010 Beijing wc ] 矩阵距离 —— 多源bfs

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2252 又没能自己想出来... 一直在想如何从每个1开始广搜更新答案,再剪剪枝,什么遇到1就不 ...

  10. awk查找特定字段

    在一行中,查找字段包含exe的: ###########awk.awk######## { for(i=1;i<NF;i++) { if($i ~ /exe/) { print $i } } } ...