本文结构

为了看懂ORB特征提取算法,来看了BRIEF算法的原文,并查看了OpenCV中BRIEF的相关实现,来验证论文的解读正确与否。

BRIEF论文解读

摘要

用二进制串描述局部特征,好处有二:一是很少的bit就能描述独特的性质;二是可以用汉明距离计算两个二进制串之间的特征,计算速度快。在实际应用中的好处是:算的准;算的快;省内存

BRIEF特征的建立和用于匹配,都很快。性能测试表明,BRIEF比SURF和U-SURF快,准确度差不多。

Introduction

经验表明,用256甚至128个bit表示一个BRIEF特征就够用了。算的快,省内存,适合实时计算的应用,比如SLAM(省计算)或者三维重建(省存储)。

先前一些算法,先计算浮点型特征描述向量,再转化为二进制表示。这样的算法,匹配很快,但是前期还是慢。

BRIEF是在keypoint周边随机取点对进行灰度计算,直接得到二进制特征描述向量。

Method

图像patch先做平滑操作,再根据检验结果(response of test,比如t检验,即t-test)生成二进制描述符。

创建这样的特征向量,需要考虑的是高斯模糊的模糊核kernel(即\(\sigma\))值的选取,以及点对\((\vecx_1, \vecx_2)\)的选取,其中\(\vec x_1=(u,v)^T\)_

模糊的作用是消噪。

识别率的实验表明,sigma取2的效果最好,对应的高斯窗口为9x9规格。

论文提出了5种选择[x,y]的方式,并根据识别率进行实验,发现第二种性能最好:(X, Y) ∼ i.i.d. Gaussian(0, (1/25)S^2)

注意:这里的高斯分布容易引起混淆,详细讲是:每次t-检验中,要选取的两个点为(X,Y),其中X=(u1,v1)T,Y=(u2,v2)T,(X,Y)~N(0, (1/25)S^2)

实际测试发现sigma2=(1/25)S2能有最高的识别率。

我还是不明白,空域中到底要怎么选点?

看了OpenCV中的实现发现,所谓随机选点,只是最开始的一个patch是随机选点,并且这个选出来的点的顺序要记录下来给后面所有的patch使用。并且,这些选出的点并不是真正的、纯粹的随机,而是服从上述高斯分布的。

为什么patch在t-检验前要做平滑?

因为论文原文提出的t-检验,每次检查的是两个像素点。单个像素点是噪声敏感的。因此要做平滑操作。(而平滑操作比较耗时,这也为后来的优化做了伏笔。Calonder等人又于2011年提出采用盒状滤波器的处理方法来代替高斯平滑处理方法)

实验和结果

在6种图片上,分别使用SURF、U-SURF、BRIEF-16、BRIEF-32、BRIEF-64进行测试,发现BRIEF-32除了在涂鸦(Graffitti)上表现不如SURF和U-SURF好之外,其他图片序列上基本都是最好的。而且显然BRIEF-32也和BRIEF-64差不了太多,并且也基本胜过SURF和U-SURF。

上述比较过程中,keypoint是用的SURF的keypoint。实际上SURF的keypoint会吃掉BRIEF带来的速度提升,一般用其他更快的keypoint检测子,比如CenSurE(Center Surround Extremas Realtime Feature Detector and Matching这篇论文提出。也可以考虑FAST等算法,FAST:Rosten, E., Drummond, T.: Machine Learning for High-Speed Corner Detection. In: European Conference on Computer Vision)。但是,换用了更快的检测子,能保证识别率吗?

同样的测试图片,对比分别用SURF和CenSurE检测的keypoint然后接上BREIF描述符,测量匹配的准确度,CenSurE在大多数情况下比SURF准确率还高;个别情况稍低于SURF。

旋转角的讨论

BRIEF没有专门考虑旋转的问题。那么就从0°~360°进行旋转测试吧。

发现小范围(0-15°)内,BRIEF识别率最高,其次是U-SURF,然后是SURF和o-BRIEF;

角度再大一点(15°~30°),BRIEF和U-SURF准确率迅速下降到0,角度再大,则这两个算法的识别率保持为0.而SURF和o-BRIEF这两个考虑旋转方向的算法,始终能保持大于60%的准确率,而且在90°的倍数角度处,识别率有极大值。

这里的o-BRIEF是:用SURF算出旋转角度,然后用BRIEF按照这个角度旋转再进行描述的一个算法。

这里的BRIEF都是BRIEF-32。

o-BRIEF和SURF的识别率,在旋转角度从0到180度变化时,几乎是重合的。

实验中还测量了SURF和BRIEF在description和matching两个阶段的对比,发现特征描述的计算时间上相差35-40倍,精确邻近匹配的计算时间上相差3~10倍。

通常U-SURF比SURF快上3倍左右。

当前BRIEF的大多数时间消耗在高斯模糊操作上。基于积分图像的近似平滑操作,能加速。

结论

BRIEF算的快(二进制描述,汉明距离匹配),算的准(这很重要),省内存(远少于SIFT和SURF的描述符位数)。

下一步考虑方向和尺度。使用快速的方向估测子(fast orientation estimators),没理由不相信速度不快!

OpenCV中的实现

对一个keypoint(及其所在区域,称为patch),在生成其描述符之前,BRIEF要先对patch做高斯平滑,这会消耗时间。

OpenCV在具体的实现上,结合了平滑和积分图像的思想,将t-检验中原本的两个点p1、p2,替换成p1、p2各自一个模板区域内的像素之和,这个模板区域以p1或p2为左上角定点。也就是,从原来的单独两个点的像素值比较,换成了两个模板区域内的像素和的比较,参与比较的点多了,降低了噪声的影响。但是计算效率呢?没关系,因为使用了积分图像,因此计算时间是O(4)=O(1)的:

inline int smoothedSum(const Mat& sum, const KeyPoint& pt, int y, int x)
{
static const int HALF_KERNEL = BriefDescriptorExtractor::KERNEL_SIZE / 2; int img_y = (int)(pt.pt.y + 0.5) + y;
int img_x = (int)(pt.pt.x + 0.5) + x;
return sum.at<int>(img_y + HALF_KERNEL + 1, img_x + HALF_KERNEL + 1)
- sum.at<int>(img_y + HALF_KERNEL + 1, img_x - HALF_KERNEL)
- sum.at<int>(img_y - HALF_KERNEL, img_x + HALF_KERNEL + 1)
+ sum.at<int>(img_y - HALF_KERNEL, img_x - HALF_KERNEL);
}

这里的积分图像的使用,其实也就是盒状滤波器:指定区域内的像素和,或者像素和的归一化结果;也就是一个元素全为1,再乘以一个系数的矩阵。

当然,盒状滤波器在实现的过程中可以有更快的实现方式,即分别指定一维的行内滤波器和列内滤波器,每个滤波器都是计算整个行或列的元素和:先逐列扫描,每列计算元素和,并存储到临时数组中;再对临时数组使用行滤波器进行求和,这样就得到一个区域的盒状滤波结果了。

参考:

Opencv2.4.9源码分析——BRIEF

极限优化:Haar特征的另一种的快速计算方法—boxfilter

BRIEF算法的更多相关文章

  1. B树——算法导论(25)

    B树 1. 简介 在之前我们学习了红黑树,今天再学习一种树--B树.它与红黑树有许多类似的地方,比如都是平衡搜索树,但它们在功能和结构上却有较大的差别. 从功能上看,B树是为磁盘或其他存储设备设计的, ...

  2. 分布式系列文章——Paxos算法原理与推导

    Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不齐.看了很多关于Paxos的资 ...

  3. 【Machine Learning】KNN算法虹膜图片识别

    K-近邻算法虹膜图片识别实战 作者:白宁超 2017年1月3日18:26:33 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

  4. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  5. 散列表(hash table)——算法导论(13)

    1. 引言 许多应用都需要动态集合结构,它至少需要支持Insert,search和delete字典操作.散列表(hash table)是实现字典操作的一种有效的数据结构. 2. 直接寻址表 在介绍散列 ...

  6. 虚拟dom与diff算法 分析

    好文集合: 深入浅出React(四):虚拟DOM Diff算法解析 全面理解虚拟DOM,实现虚拟DOM

  7. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  8. 神经网络、logistic回归等分类算法简单实现

    最近在github上看到一个很有趣的项目,通过文本训练可以让计算机写出特定风格的文章,有人就专门写了一个小项目生成汪峰风格的歌词.看完后有一些自己的小想法,也想做一个玩儿一玩儿.用到的原理是深度学习里 ...

  9. 46张PPT讲述JVM体系结构、GC算法和调优

    本PPT从JVM体系结构概述.GC算法.Hotspot内存管理.Hotspot垃圾回收器.调优和监控工具六大方面进行讲述.(内嵌iframe,建议使用电脑浏览) 好东西当然要分享,PPT已上传可供下载 ...

  10. 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法

    若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...

随机推荐

  1. Hadoop和Spark的异同

    谈到大数据,相信大家对Hadoop和Apache Spark这两个名字并不陌生.但我们往往对它们的理解只是提留在字面上,并没有对它们进行深入的思考,下面不妨跟我一块看下它们究竟有什么异同. 解决问题的 ...

  2. php基础04:字符串函数

    <?php //1.strlen(),strlen() 函数返回字符串的长度,以字符计. echo strlen("hello world"); echo "< ...

  3. js如何判断一组数字是否连续,得到一个临时数组[[3,4],[13,14,15],[17],[20],[22]];

    var arrange = function(arr){ var result = [], temp = []; arr.sort(function(source, dest){ return sou ...

  4. [CareerCup] 6.5 Drop Eggs 扔鸡蛋问题

    6.5 There is a building of 100 floors. If an egg drops from the Nth floor or above, it will break. I ...

  5. [C++] 在Visual Studio工程中管理C++第三方库

    目前的项目依赖于很多第三方库,每次要再一个新的环境编译/运行,都要花很长时间先编译/安装各种第三方库,而且会出现各种问题,因此决定将所有第三方库编译好之后,放入工程的子目录中,以后就不用重复编译了. ...

  6. 20135316王剑桥 linux第五周课实验笔记

    4.1.1程序员的可见的状态 ———— Y86的每条指令都会读取或修改处理器状态的某些部分,称为程序员可见状态.如图1所示. 1.程序寄存器(Program registers): %eax, %ec ...

  7. Buffer lab——20145326蔡馨熠

    Buffer lab   缓冲区溢出攻击的原理 缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况.这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段.这一漏洞的出现是由 ...

  8. 微软office web apps 服务器搭建之在线文档预览(一)

    office web apps安装 系统要求为Windows Server 2012, 注意:转换文档需要两台服务器,一台为转换server,另外一台为域控server.(至于为什么要两台,这个请自行 ...

  9. 零散知识记录-一个MQ问题

    [背景]我有一项零散工作:维护大部门的一台测试公用MQ服务器.当大部分MQ被建立起来,编写了维护手册,大家都按照规程来后,就基本上没有再动过它了.周五有同学跟我反映登录不进去了,周日花了1个小时来解决 ...

  10. Chrome扩展开发之一——Chrome扩展的文件结构

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...