文档章节

ORB图像特征检测

Pulsar-V
 Pulsar-V
发布于 2017/08/03 13:22
字数 1938
阅读 86
收藏 1

#ORB算法推导

ORB采用FAST (features from accelerated segment test) 算法来检测特征点。FAST核心思想就是找出那些卓尔不群的点,即拿一个点跟它周围的点比较,如果它和其中大部分的点都不一样就可以认为它是一个特征点。 首先来做几个定义:
U : 参考像素点周围的区域阈值
t : 与参考像素点作对比的阈值点的灰度值当参考点的灰度值之差的绝对值大于t时,我们认为这两个点不相同
Gp : 像素点的灰度值
u : 区域阈值内不同的像素点数量
Un : 区域阈值内的连续像素点数目

FAST计算过程:

  1. 遍历图像矩阵一个参考像素点P。
  2. 考虑该像素点周围的Un个像素。
  3. 现在如果这Un个点中有连续的u个点都和参考点不同,那么它就是一个角点。
  4. 现在我们考虑一下这个检测思路,当我们遍历图像矩阵的时候还需要再一次的去遍历图像参考像素点周边的点,所以这个思路需要进行优化,所以我们 只需要检测参考像素点的矩形区域阈值内的对角像素即可,当对角像素内的像素点存在u (此处u与上面的连续点有所不同) 个不同的像素的时候。可以认为这个点与参考像素点不同。

计算特征描述子 (Feature DescritorS):

计算机是一个二进制机器,它读取的数据流或者是图像,只是一个data流或者是一个像素矩阵,它本身并没有任何特性,即使我们找到了像素的特征点坐
标,我们给它标记出来,可以通过肉眼直观的看到像素特征,但是计算机并不知道这些像素有什么意义,这个时候我们就需要构造一个特征描述子去描述当前像
素点的特征。

定义 O:参考特征点的圆形区域
d : 区域半径
N : 半径内点的个数
P(A,B):提取的点对的向量其中A, B为像素点A与像素点B的向量 具体来讲分为以下几步。

  1. 以关键点P为圆心,以d为半径做圆O。
  2. 在圆O内某一模式选取N个点对。(在OpenCV的FAST算法描述中,默认取512作为点对的个数)
  3. 定义一个函数T (P (A, B)) 使得当函数过程满足条件的时候取0, 时取1。其中为像素点的灰度值

通过上面的函数计算,就可以拿到列如101000101这样的特征描述子 但是实际上来讲,我们提取到的特征描述子仅仅是在同一坐标系中的描述子,当我们旋转这张图片以后呢,就会发现,上面的算法,会导致即是是同一个点,但是因为旋转了 图像而导致匹配失效。

在现实生活中,我们从不同的距离,不同的方向、角度,不同的光照条件下观察一个物体时,物体的大小,形状,明暗都会有所不同。但我们的大脑依然可以判断它是同一件物体。理想的特征描述子应该具备这些性质。即,在大小、方向、明暗不同的图像中,同一特征点应具有足够相似的描述子,称之为描述子的可复现性。

所有获取到的特征描述子应该必须要有:

对光照(亮度)不敏感,具备尺度一致性(大小 ),旋转一致性(角度)

在OpenCV的ORB实现中采用了图像金字塔来改善这方面的性能。ORB主要解决BRIEF描述子不具备旋转不变性的问题。当我们选取点对的时候,是以当前关键点为原点,以水平方向为X轴,以垂直方向为Y轴建立坐标系。当图片发生旋转时,坐标系不变,同样的取点模式取出来的点却不一样,计算得到的描述子也不一样,这样进行的匹配会出问题,因此需要建立一个新的坐标系去解决这个问题,来保证我们的一致性。

在OpenCV中通过构建高斯金字塔,然后在每一层金字塔图像上检测角点,来实现尺度不变性。那么,对于局部不变性,我们还差一个问题没有解决,就是FAST特征点不具有方向,ORB的论文中提出了一种利用灰度质心法来解决这个问题,灰度质心法假设角点的灰度与质心之间存在一个偏移,这个向量可以用于表示一个方向。对于任意一个特征点 来说,我们定义 的邻域像素的矩为:

图像的质心为:

至此,我们可以把特征点与质心的夹角定义为FAST特征点的方向:

给BRIEF加上旋转不变性,把这种方法称为“Steer BREIF”。对于任何一个特征点来说,它的BRIEF描述子是一个长度为 的二值码串,这个二值串是由特征点周围n个点对(2n个点)生成的,现在我们将这2n个点组成一个矩阵S

下面是OpenCV中的ORB实现函数

ORB::ORB(int nfeatures=500, float scaleFactor=1.2f, int nlevels=8, int edgeThreshold=31, int firstLevel=0, int WTA_K=2, int scoreType=ORB::HARRIS_SCORE, int patchSize=31)

nfeatures - 最多提取的特征点的数量
scaleFactor- 金字塔图像之间的尺度参数,类似于SIFT中的
nlevels– 高斯金字塔的层数;

edgeThreshold– 边缘阈值,这个值主要是根据后面的patchSize来定的,靠近边缘edgeThreshold以内的像素是不检测特征点的。

firstLevel - 看过SIFT都知道,我们可以指定第一层的索引值,这里默认为0。

WET_K - 用于产生BIREF描述子的 点对的个数,一般为2个,也可以设置为3个或4个,那么这时候描述子之间的距离计算就不能用汉明距离了,而是应该用一个变种。OpenCV中,如果设置WET_K = 2,则选用点对就只有2个点,匹配的时候距离参数选择NORM_HAMMING,如果WET_K设置为3或4,则BIREF描述子会选择3个或4个点,那么后面匹配的时候应该选择的距离参数为NORM_HAMMING2。

scoreType- 用于对特征点进行排序的算法,你可以选择HARRIS_SCORE,也可以选择FAST_SCORE,但是它也只是比前者快一点点而已。

patchSize– 用于计算BIREF描述子的特征点邻域大小。

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/features2d/features2d.hpp>

using namespace cv;

int main(int argc, char** argv) 
{ 
    Mat img_1 = imread("test.png"); 
    Mat img_2=imread("test2.png") ;

    // -- Step 1: 初始化ORB匹配点集
    std::vector<KeyPoint> keypoints_1,keypoints_2; 
    ORB orb; 
    orb.detect(img_1, keypoints_1); 
    orb.detect(img_2, keypoints_2);

    // -- Stpe 2: 计算特征描述子
    Mat descriptors_1, descriptors_2; 
    orb.compute(img_1, keypoints_1, descriptors_1); 
    orb.compute(img_2, keypoints_2, descriptors_2);

    //-- Step 3: 匹配相似的特征向量
    BFMatcher matcher(NORM_HAMMING); 
    std::vector<DMatch> mathces; 
    matcher.match(descriptors_1, descriptors_2, mathces); 

    // -- 绘制匹配线
    Mat img_mathes; 
    drawMatches(img_1, keypoints_1, img_2, keypoints_2, mathces, img_mathes); 

    // --显示图像
    imshow("Mathces", img_mathes);
    waitKey(0); 
    return 0; 
}

参考资料:

  1. An Efficient Alternative to SIFT or SURF
  2. 原文paper

© 著作权归作者所有

共有 人打赏支持
Pulsar-V

Pulsar-V

粉丝 52
博文 109
码字总数 81470
作品 1
成都
后端工程师
私信 提问
特征向量(Feature Vectors)

角点与目标检测(Corners and Object Detection) 已经可以从图像中提取基于形状的特征,如何使用这一组特征来检测整个对象,以山峰图像角点检测举例: 假设想要在其他图像中检测这座山的方法,...

徐凯_xp
08/27
0
0
视觉SLAM的方案大全

MoNoSLAM 以扩展卡尔曼滤波为后端,追踪前端非常稀疏的特征点,以相机的当前状态和所有路标点为状态量,更新其均值和协方差。 优点:在2007年,随着计算机性能的提升,以及该系统用稀疏的方式...

问题终结者
01/30
0
0
图像处理之特征提取

知乎上看到一个话题—— 目前火热的 Deep Learning 会灭绝传统的 SIFT / SURF 特征提取方法吗? 由于之前研究过SIFT和HOG这两种传统的特征提取方法,故本篇文章先对SIFT和HOG作一综述,并比较...

牛奶芝麻
2017/11/27
0
0
opencv MSER(最大极值稳定区域)

最大极值稳定区域,是一种类似分水岭图像的分割与匹配算法。它具有SIFT SURF及 ORB等特征不具备的仿射不变性,近年来广泛应用于图像分割与匹配领域。 详细算法原理介绍可参见链接 http://blo...

moki_oschina
2016/11/24
128
0
LSD SLAM和ORB SLAM的对比

现在开始找实习了,开始回顾研究生做的工作,把之前做的东西都总结一下,梳理梳理知识。 LSD SLAM的介绍: LSD SLAM是slam界大牛 Jakob Engel的著作,也是直接法的代表性工作。和LSD SLAM想对...

osgoodwu
04/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP生成CSV之内部换行

当我们使用PHP将采集到的文件内容保存到csv文件时,往往需要将采集内容进行二次过滤处理才能得到需要的内容。比如网页中的换行符,空格符等等。 对于空格等处理起来都比较简单,这里我们单独...

豆花饭烧土豆
21分钟前
0
0
使用 mjml 生成 thymeleaf 邮件框架模板

发邮件算是系统开发的一个基本需求了,不过搞邮件模板实在是件恶心事,估计搞过的同仁都有体会。 得支持多种客户端 支持响应式 疼彻心扉的 outlook 多数客户端只支持 inline 形式的 css 布局...

郁也风
24分钟前
2
0
让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字

让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字: 作者:孙冬梅;以前读韩国前总统朴槿惠的著作《绝望锻炼了我》时,里面有一句话令我印象深刻,她说“在我最困难的时期,...

原创小博客
今天
3
0
JAVA-四元数类

public class Quaternion { private final double x0, x1, x2, x3; // 四元数构造函数 public Quaternion(double x0, double x1, double x2, double x3) { this.x0 = ......

Pulsar-V
今天
17
0
Xshell利用Xftp传输文件,使用pure-ftpd搭建ftp服务

Xftp传输文件 如果已经通过Xshell登录到服务器,此时可以使用快捷键ctrl+alt+f 打开Xftp并展示Xshell当前的目录,之后直接拖拽传输文件即可。 pure-ftpd搭建ftp服务 pure-ftpd要比vsftp简单,...

野雪球
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部