作者lowkeyway
时间为友,记录点滴。
费尽千辛万苦,总算是把SIFT看得懵懂了,还好OpenCV给我们的API已经完全封装了所有的步骤。只是这个专利费让9012年的我们即便学习也要折腾折腾。
最重要的是,有大神们也对SIFT不满意,持续不断优化它。直到Ethan Rublee, Vincent Rabaud, Kurt Konolige以及Gary R.Bradski在2011年一篇名为“ORB:An Efficient Alternative to SIFTor SURF”的文章,开启了一个新篇章。
为什么引入ORB
嗯,跟Harris一样,如果你运行过SIFT,也一定有所感悟。即便它集尺度不变、旋转不变、光变不敏感等优点于一身,但是它运行实在是慢了点。
那么改善SIFT,从SURF开始,大家的重点都是集中在速度优化上。据论文中提供,ORB要比SIFT快两个数量级!
这么厉害,我们先了解一下啥是ORB。
什么是ORB
ORB(Oriented FAST and Rotated BRIEF)是Oriented FAST + Rotated BRIEF的缩写(感觉应该叫OFRB)。是目前最快速稳定的特征点检测和提取算法,许多图像拼接和目标追踪技术利用ORB特征进行实现。
当然,没看懂不要紧,先记住我们的初衷:
- 首先要实现目标检测的功能;
- 其次在不牺牲性能的代价下提高速度;
- 最后,开源无专利;
大神们在ORB上都做到了!
怎么实现ORB
要了解ORB,如果直接去看他们的论文,感觉多半会蒙圈。那是写给学术圈有一定基础的人看的。我等工程狗要了解ORB用简单的公式就可以:
ORB = Oriented FAST(特征点) + Rotated BRIEF(特征描述)
弗洛伊德说:一个问题搞不定,就拆成两个小问题,这样我们就有了两个搞不定的问题。
我们再来分别了解一下什么是FAST,为什么叫 Oriented FAST;什么是什么是BRIEF,为什么叫Rotated BRIEF。
FAST
FAST,正如其名。它的出现就是为了解决SIFT在建立特征点时速度慢的问题。我们程序员都知道,要解Bug首先要做的是定位问题。
那么,SIFT为什么慢呢?
SIFT进行特征点检测时需要建立尺度空间,基于局部图像的梯度直方图来计算描述子,整个算法的计算和数据存储复杂度比较高,不适用于处理实时性很强的图像。
好了,FAST的解决方案是什么呢?
若某像素与其周围领域内足够多的像素点相差较大,则该像素可能是特征点。
如何用计算机实现呢?
两步走,海选 + 筛选。
Step1: 确定候选角点(Segment Test)
看图说话
- 选择某个像素 , 其像素值为 。以 为圆心,半径为3, 确立一个圆,圆上有16个像素,分别为
- 确定一个阈值: (比如 Ip 的 20%)。
- 让圆上的像素的像素值分别与 的像素值做差,如果存在连续n个点满足 或 (其中 代表此圆上16个像素中的一个点),那么就把该点作为一个候选点。根据经验,一般令n=12(n 通常取 12,即为 FAST-12。其它常用的 N 取值为 9 和 11, 他们分别被称为 FAST-9,FAST-11).
补充:
由于在检测特征点时是需要对图像中所有的像素点进行检测,然而图像中的绝大多数点都不是特征点,如果对每个像素点都进行上述的检测过程,那显然会浪费许多时间,因此FAST采用了一种进行非特征点判别的方法。如上图中,对于每个点都检测第1、5、9、13号(即上下左右)像素点,如果这4个点中至少有3个满足都比 大或者都比 小,则继续对该点进行16个邻域像素点都检测的方法,否则则判定该点是非特征点(也不可能是角点,如果是一个角点,那么上述四个像素点中至少有3个应该和点相同),直接剔除即可。
Step2:非极大值抑制
经过Step 1的海选后,还是会有很多个特征点。好在他们有个缺点:很可能大部分检测出来的点彼此之间相邻,我们要去除一部分这样的点。为了解决这一问题,可以采用非最大值抑制的算法:
- 假设P,Q两个点相邻,分别计算两个点与其周围的16个像素点之间的差分和为V。
- 去除V值较小的点,即把非最大的角点抑制掉。
经过上述两步后FAST特征值筛选的结果就结束了。
Oriented FAST
是不是对FAST感觉意犹未尽?
FAST有什么缺点呢?
嗯,FAST快是快,但是无法体现出一个优良特征点的尺度不变性和旋转不变性。
Fast角点本不具有方向,由于特征点匹配需要,ORB对Fast角点进行了改进,改进后的 FAST 被称为 Oriented FAST,具有旋转和尺度的描述。
那么,Oriented FAST是怎么解决这个问题呢?
从SIFT过来的我们对这个问题不陌生。
- 尺度不变性:可以用金字塔解决;
- 旋转不变性:可以用质心标定方向解决;
尺度不变性:
- 对图像做不同尺度的高斯模糊
- 对图像做降采样(隔点采样)
- 对每层金字塔做FAST特征点检测
- n幅不同比例的图像提取特征点总和作为这幅图像的oFAST特征点。
旋转不变性:
1、在一个小的图像块 B 中,定义图像块的矩。
2、通过矩可以找到图像块的质心
3、连接图像块的几何中心 O 与质心 C,得到一个方向向量 ,这就是特征点的方向
旋转测量。灰度质心在人工旋转噪声影响下,与直方图算法和MAX算法相比,具有最好的恢复主方向的性能。
BRIEF
BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度直方图描述特征点的传统方法,采用二级制、位异或运算,大大的加快了特征描述符建立的速度,同时也极大的降低了特征匹配的时间,是一种非常快速,很有潜力的算法。
如果说FAST用来解决寻找特征点的速度问题,那么BRIEF就用来解决描述子的空间占用冗余问题。
特征点怎么来?
好了,我们知道了BRIEF的实质就是特征点的描述子。那么前提就是描述对象特征点从何而来?实际上,Harris/FAST/SIFT/SURF等算法提供的特征点都可以。
描述子怎么加?
先定格调:在关键点周围做像素值比较,得到的结果是二进制串。
那下面就看一看它是如何给这些特征点加上描述子的:
1、为减少噪声干扰,先对图像进行高斯滤波(方差为2,高斯窗口为9x9)
2、以特征点为中心,取SxS的邻域窗口。在窗口内随机选取一对(两个)点,比较二者像素的大小,进行如下二进制赋值。
如下二进制赋值。
其中,p(x),p(y)分别是随机点x=(u1,v1),y=(u2,v2)的像素值。
3、在窗口中随机选取N对随机点,重复步骤2的二进制赋值,形成一个二进制编码,这个编码就是对特征点的描述,即特征描述子。(一般N=256)
这个特征可以由n位二进制测试向量表示,BRIEF描述子:
这里面,最关键的地方其实是随机特征对的选取,论文中就给出了5种方法(其中第二种比较好),分别为:
- 都呈均匀分布 ;
- 都呈高斯分布 ,准则采样服从各向同性的同一高斯分布;
- 服从高斯分布 , 服从高斯分布 ,采样分两步进行:首先在原点处为 进行高斯采样,然后在中心为 处为 进行高斯采样;
- 在空间量化极坐标下的离散位置处进行随机采样;
- 在空间量化极坐标下的离散位置处进行随机采样;
这5种方法生成的256对(OpenCV中用32个字节存储这256对)随机点如下(一条线段的两个端点是一对):
这个图有助于帮我们理解随机对描述子
经过上面三个步骤,我们就可以为每个特征点表示为一个256bit的二进制编码。
Rotated BRIEF
在介绍ORB的改善之前,我们先思考一个问题。描述子是用来描述一个特征点的属性的,除了标记特征点之外,它最重要的一个功能就是要实现特征点匹配。BRIEF是如何实现特征点匹配的呢?
答案是:Hamming距离!
汉明距离是使用在数据传输差错控制编码里面的,汉明距离是一个概念,它表示两个(相同长度)字对应位不同的数量,我们以d(x,y)表示两个字x,y之间的汉明距离。对两个字符串进行异或运算,并统计结果为1的个数,那么这个数就是汉明距离。
- 两个特征编码对应bit位上相同元素的个数小于128的,一定不是配对的。
- 一幅图上特征点与另一幅图上特征编码对应bit位上相同元素的个数最多的特征点配成一对。
其实就是按位求异或的过程。(相同为0,不同为1)
所以,对于BRIEF来说,描述子里不包含旋转属性,所以一旦匹配图片有稍微大点的旋转角度,按照Hamming算法,匹配度将会大幅下降。
ORB如何优化?
首先,做一些前期优化:
- ORB算法进一步增强描述子的抗噪能力,采用积分图像来进行平滑;
- 在特征点的31x31邻域内,产生随机点对,并以随机点为中心,取5x5的子窗口。
- 比较两个随机点的子窗口内25个像素的大小进行编码(而不仅仅是两个随机点了)
其次,为BRIEF增加旋转不变性(Steered BRIEF):
ORB算法采用关键点的主方向来旋转BEIEF描述子。
1、对于任意特征点,在31x31邻域内位置为 的n对点集,可以用2 x n的矩阵来表示:
2、利用FAST求出的特征点的主方向 和对应的旋转矩阵 ,算出旋转的 来代表 :
3、计算旋转描述子(steered BRIEF):
其中 为BRIEF的描述子。
最后,rBRIEF-改进特征点描述子的相关性
使用steeredBRIEF方法得到的特征描述子具有旋转不变性,但是却在另外一个性质上不如原始的BRIEF算法。是什么性质呢,是描述符的可区分性,或者说是相关性。这个性质对特征匹配的好坏影响非常大。描述子是特征点性质的描述。描述子表达了特征点不同于其他特征点的区别。我们计算的描述子要尽量的表达特征点的独特性。如果不同特征点的描述子的可区分性比较差,匹配时不容易找到对应的匹配点,引起误匹配。ORB论文中,作者用不同的方法对100k个特征点计算二进制描述符,对这些描述符进行统计,如下表所示:
特征描述子的均值分布。X轴代表距离均值0.5的距离;y轴是相应均值下的特征点数量统计
我们先不看rBRIEF的分布。对BRIEF和steeredBRIEF两种算法的比较可知,BRIEF算法落在0上的特征点数较多,因此BRIEF算法计算的描述符的均值在0.5左右,每个描述符的方差较大,可区分性较强。而steeredBRIEF失去了这个特性。
至于为什么均值在0.5左右,方差较大,可区分性较强的原因,这里大概分析一下。这里的描述子是二进制串,里面的数值不是0就是1,如果二进制串的均值在0.5左右的话,那么这个串有大约相同数目的0和1,那么方差就较大了。用统计的观点来分析二进制串的区分性,如果两个二进制串的均值都比0.5大很多,那么说明这两个二进制串中都有较多的1时,在这两个串的相同位置同时出现1的概率就会很高。那么这两个特征点的描述子就有很大的相似性。这就增大了描述符之间的相关性,减小之案件的可区分性。
下面我们介绍解决上面这个问题的方法:rBRIEF。
原始的BRIEF算法有5种去点对的方法,原文作者使用了方法2。为了解决描述子的可区分性和相关性的问题,ORB论文中没有使用5种方法中的任意一种,而是使用统计学习的方法来重新选择点对集合。
首先,建立300k个特征点测试集。
备注:
对于测试集中的每个点,预处理参考第一个步骤。考虑其31x31邻域。这里不同于原始BRIEF算法的地方是,这里在对图像进行高斯平滑之后,使用邻域中的某个点的5x5邻域灰度平均值来代替某个点对的值,进而比较点对的大小。这样特征值更加具备抗噪性。另外可以使用积分图像加快求取5x5邻域灰度平均值的速度。
其次,特征点选取
从上面可知,在31 x 31的邻域内共有(31-5+1)x(31-5+1)=729个这样的子窗口,那么取点对的方法共有M=205590种,我们就要在这M种方法中选取256种取法,选择的原则是这256种取法之间的相关性最小。怎么选取呢?
- 在300k特征点的每个31x31邻域内按M种方法取点对,比较点对大小,形成一个300k x M的二进制矩阵Q。矩阵的每一列代表300k个点按某种取法得到的二进制数。
- 对Q矩阵的每一列求取平均值,按照平均值到0.5的距离大小重新对Q矩阵的列向量排序,形成矩阵T。
- 将T的第一列向量放到R中
- 取T的下一列向量和R中的所有列向量计算相关性,如果相关系数小于设定的阈值,则将T中的该列向量移至R中。
- 按照第四步的方式不断进行操作,直到R中的向量数量为256。
通过这种方法就选取了这256种取点对的方法。这个算法是对均值靠近0.5的不相关测试进行贪婪搜索,结果称为rBRIEF。rBRIEF在方差和相关性上与旋转BRIEF相比有明显进步(如图4)。PCA的特征值较高,它们的下降速度要快得多。
三个特征向量超过100k个关键点的PCA分解的特征值分布:BRIEF,旋转BRIEF,和rBRIEF。
至此,ORB的优化就结束了。我们尝试总结一下:
- FAST是用来寻找特征点的。ORB在FAST基础上通过金字塔、质心标定解决了尺度不变和旋转不变。即oFAST。
- BRIEF是用来构造描述子的。ORB在BRIEF基础上通过引入oFAST的旋转角度和机器学习解决了旋转特性和特征点难以区分的问题。即rBRIEF.
现在,有了特征点寻找和描述子,ORB就成了!
跟以往一样,OpenCV给我们提供了便捷的接口和使用方法。外部看上跟SIFT简直不要太一样。
C++
运行结果
Python
运行结果
▲长按关注我们