(二)ORB描述子提取源码思路与实现
ORBSLAM2中ORB特征提取的特点
ORBSLAM2中通过对OpenCV中的ORB特征点提取类进行修改,对图像进行分块提取,而后划分节点,使得每个节点中保存的特征点性能是该节点所有特征点中最好的。
可能按照上面说的方式,大家不太能理解。
这么说吧。将铺满苹果的桌子进行画格子,然后每个格子中就会有不同数量的苹果,在每个格子中选出最好吃的苹果,格子中其他的苹果全部扔掉。(虽然有点可惜,但是大局为重嘛),那么原先摆满苹果的桌子(如图1所示),现在就剩下每个格子一个苹果的桌子,尽管苹果少了很多,但是剩下的都是精英,极品(如图2所示)。


根据上面的类比,还有我那抽象派的苹果,应该可以对ORBSLAM2中的ORB特征提取做的事情有个大概的了解。
这里需要提一下的是原生态的ORB特征提取的方法,他主要是通过阈值条件选出所有满足条件的ORB描述子,然后计算所有描述子的响应强度并排序M,根据输入要求的特征点数量N,取M中前N个描述子,即响应值最大的前N个描述子。显然,这种提取的方法会导致特征点的分布非常不均匀。而这也会影响到SLAM系统中定位的精度。文末在实现源码的时候会给大家看看两种方法提取特征的结果。
ORB特征提取的源码流程
ORB描述子的提取流程:
1. 输入图像,并对输入图像进行预处理,将其转换成灰度图像;
2. 初始化参数,包括特征点数量nfeatures,尺度scaleFactor,金字塔层数nlevel,初始阈值iniThFAST,最小阈值minThFAST等参数;
3. 计算金字塔图像,源码中使用8层金字塔,尺度因子为1.2,则通过对原图像进行不同层次的resize,可以获得8层金字塔的图像;
4. 计算特征点:
1)将图像分割成网格,每个网格大小为W*W=30*30像素;
2)遍历每个网格;
3)对每个网格提取FAST关键点,先用初始阈值iniThFAST提取,若提取不到关键点,则改用最小阈值minThFAST提取。(注意,初始阈值一般比最小阈值大)
5. 对所有提取到的关键点利用八叉树的形式进行划分:
1)按照像素宽和像素高的比值作为初始的节点数量,并将关键点坐标落在对应节点内的关键点分配入节点中;
2)根据每个节点中存在的特征点数量作为判断依据,如果当前节点只有1个关键点,则停止分割。否则继续等分成4份;
3)按照上述方法不断划分下去,如图3所示,可见出现一个八叉树的结构,终止条件是节点的数目Lnode大于等于要求的特征点数量nfeatures;
4)对满足条件的节点进行遍历,在每个节点中保存响应值最大的关键点,保证特征点的高性能;
6. 对上述所保存的所有节点中的特征点计算主方向,利用灰度质心的方法计算主方向,上一讲中我们已经讲解过方法,这讲就不再赘述了;
7. 对图像中每个关键点计算其描述子,值得注意的是,为了将主方向融入BRIEF中,在计算描述子时,ORB将pattern进行旋转,使得其具备旋转不变性;

综上,ORB描述子提取的方法已经讲解完毕了。现在就是上源码了。由于许多人都对源码进行过注释,本文就直接上github:https://github.com/yepeichu123/orbslam2_learn的链接给大家,笔者是在ubuntu14.04 + opencv3.2的环境下运行的,已经实测可以运行。另外,本文还对比了ORB分网格提取和原始方法提取的异同,具体如图4所示。可以看见,分网格提取,特征点质量更好,分布也更均匀,对于SLAM问题的跟踪和三角化等能实现更鲁邦的效果。

总结
这一讲我们讲解了ORBSLAM2中,ORB的分块提取源码是如何实现的,并且分析了分块提取和原生态的ORB之间的对比;
另外,本文还将源码进行单独实现,提供了一个github的源码,给大家练手。
PS:
如果您觉得我的博客对您有所帮助,欢迎关注我的博客。此外,欢迎转载我的文章,但请注明出处链接。
对本文有任何问题可以在留言区进行评论,也可以在泡泡机器人论坛:http://paopaorobot.org/bbs/index.php?c=cate&fid=1中的SLAM技术交流模块发帖提问。
(二)ORB描述子提取源码思路与实现的更多相关文章
- (一)ORB描述子提取
ORBSLAM2中使用ORB描述子的方法 经典的视觉SLAM系统大体分为两种:其一是基于特征点法的,其二是基于直接法的.那么本文主要就讲特征点法的SLAM. 基于特征点法的视觉SLAM系统典型的有PT ...
- 【学】jQuery的源码思路2——$符号是如何封装的
jQuery中的$符号功能很强大,原因在于对函数参数的个数以及种类的控制,还有对于面向对象思想的运用 function jQuery(args){ //接受参数,并对其判断 this.elements ...
- 【学】jQuery的源码思路1——后代选择器
jQuery的源码思路1--后代选择器 这里探讨一下jQuery中后代选择器的封装原理,并自己写一下 getEle('#div1 ul li .box');接受的参数就是个后代选择器,类似于这样: # ...
- Android 音视频深入 二十 FFmpeg视频压缩(附源码下载)
项目源码https://github.com/979451341/FFmpegCompress 这个视频压缩是通过类似在mac终端上输入FFmpeg命令来完成,意思是我们需要在Android上达到能够 ...
- 6 HandlerDescriptor 处理程序描述类——Live555源码阅读(一)基本组件类
这是Live555源码阅读的第一部分,包括了时间类,延时队列类,处理程序描述类,哈希表类这四个大类. 本文由乌合之众 lym瞎编,欢迎转载 http://www.cnblogs.com/oloroso ...
- 原生javascript实现老.虎机抽奖点名demo源码思路解析
想着使用原生Javascript做一个随机点名的小应用, 也可以做抽奖使用. html简单化,人名单可以通过js生成并处理. 可以非常随意的添加修改人名字. 应用想带点特效,比如老.虎机转动的特效. ...
- Eclipse用法和技巧二十三:查看JDK源码
使用java开发,如果能阅读JDK的经典代码,对自己的水平提高是很有帮助的.笔者在实际工作中总结了两种阅读JDK源码的方式.第一种下载android源代码,直接在android源码代码中,这里的代码虽 ...
- MPSOC之4——petalinux提取源码
petalinux使用太不方便,捆绑的太死板,也不通用,还不如直接用编译器来的简单高效. 本文说明从petalinux中提取出源代码的过程,前提是已经petalinux-build完成. 1. ubo ...
- Spring 3.1新特性之二:@Enable*注解的源码,spring源码分析之定时任务Scheduled注解
分析SpringBoot的自动化配置原理的时候,可以观察下这些@Enable*注解的源码,可以发现所有的注解都有一个@Import注解.@Import注解是用来导入配置类的,这也就是说这些自动开启的实 ...
随机推荐
- Jenkins + Ansible + Gitlab之gitlab篇
前言 持续交付 版本控制器:Gitlab.GitHub 持续集成工具:jenkins 部署工具:ansible 课程安排 Gitlab搭建与流程使用 Ansible环境配置与Playbook编写规范 ...
- 深度学习识别CIFAR10:pytorch训练LeNet、AlexNet、VGG19实现及比较(一)
版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 前面几篇文章介绍了MINIST,对这种简单图片的识别,LeNet-5可以达到99%的识别率. CIFA ...
- [BZOJ 1095] [ZJOI 2007] 捉迷藏
Description 传送门 Solution 先将原树转化成点分树: 然后维护三个堆: \(c[i]\) 保存点分树中子树 \(i\) 中的黑色节点到 \(fa[i]\) 的距离: \(b[i]\ ...
- Day 1 上午
唉,上午就碰到一个开不了机的电脑,白白浪费了半个小时,真的难受QwQ POINT1 枚举 枚举也称作穷举,指的是从问题所有可能的解的集合中一一枚举各元素. 用题目中给定的检验条件判定哪些是无用的,哪些 ...
- SWIG 扩展Opencv python调用C++
osx:10.12 g++ 7.1 swig 3.0.12 opencv 3.2.0 SWIG是Simplified Wrapper and Interface Generator的缩写.是Pytho ...
- ELK日志系统:Elasticsearch+Logstash+Kibana+Filebeat搭建教程
ELK日志系统:Elasticsearch + Logstash + Kibana 搭建教程 系统架构 安装配置JDK环境 JDK安装(不能安装JRE) JDK下载地址:http://www.orac ...
- PWN! 第一次测试答案及讲解
题目链接:https://vjudge.net/contest/279567#overview 题目密码:190118 1.A+B:(考察点:EOF输入.加法运算) Topic: Calculate ...
- 小白月赛13 小A的路径 (矩阵快速幂求距离为k的路径数)
链接:https://ac.nowcoder.com/acm/contest/549/E来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 深入理解JVM(6)——Java内存模型和线程
Java虚拟机规范中定义了Java内存模型(Java Memory Model,JMM)用来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果(“即Ja ...
- 微信小程序之:wepy(二)
一大堆实例:人家的博客园 代码规范: 1.尽量使用驼峰命名,避免使用$开头,框架内建属性都已$开头,可以使用this直接调用. 2.入口文件.页面.组件后缀都为.wpy. 3.使用ES6语法开发. 4 ...