ORB-SLAM2详解(四)跟踪
ORB-SLAM2详解(四)跟踪
本人邮箱:sylvester0510@163.com,欢迎交流讨论,
欢迎转载,转载请注明网址http://blog.csdn.net/u010128736/
这一部分是ORB_SLAM系统中最基本的一步,会对每一帧图像进行跟踪计算。Tracking线程运行在主线程中,主要思路是在当前帧和(局部)地图之间寻找尽可能多的对应关系,来优化当前帧的位姿。每次新采集到一帧图像,就是用下列接口将图像传入SLAM系统就行处理。该代码位于主程序中:
// Pass the image to the SLAM systemSLAM.TrackMonocular(im,tframe);
在检查完系统将模式切换为跟踪模式后,是用下面接口进入功能:
mpTracker->GrabImageMonocular(im,timestamp);
一、ORB提取
本文做匹配的过程中,是用的都是ORB特征描述子。先在8层图像金字塔中,提取FAST特征点。提取特征点的个数根据图像分辨率不同而不同,高分辨率的图像提取更多的角点。然后对检测到的特征点用ORB来描述,用于之后的匹配和识别。跟踪这部分主要用了几种模型:运动模型(Tracking with motion model)、关键帧(Tracking with reference keyframe)和重定位(Relocalization)。
二、从前一帧初始化位姿估计
在成功与前面帧跟踪上之后,为了提高速率,本文使用与之前速率相同的运动模式来预测相机姿态,并搜索上一帧观测到的地图点。这个模型是假设物体处于匀速运动,例如匀速运动的汽车、机器人、行人等,就可以用上一帧的位姿和速度来估计当前帧的位姿。使用的函数为TrackWithMotionModel()。这里匹配是通过投影来与上一帧看到的地图点匹配,使用的是matcher.SearchByProjection()。
if(mVelocity.empty() || mCurrentFrame.mnId<mnLastRelocFrameId+2)
{bOK = TrackReferenceKeyFrame();
}
else
{bOK = TrackWithMotionModel();if(!bOK)bOK = TrackReferenceKeyFrame();
}
当使用运动模式匹配到的特征点数较少时,就会选用关键帧模式。即尝试和最近一个关键帧去做匹配。为了快速匹配,本文利用了bag of words(BoW)来加速。首先,计算当前帧的BoW,并设定初始位姿为上一帧的位姿;其次,根据位姿和BoW词典来寻找特征匹配,使用函数matcher.SearchByBoW();最后,利用匹配的特征优化位姿。
三、通过全局重定位来初始化位姿估计
假如使用上面的方法,当前帧与最近邻关键帧的匹配也失败了,那么意味着需要重新定位才能继续跟踪。重定位的入口如下:
bOK = Relocalization();
此时,只有去和所有关键帧匹配,看能否找到合适的位置。首先,计算当前帧的BOW向量,在关键帧词典数据库中选取若干关键帧作为候选。使用函数如下:
// Relocalization is performed when tracking is lost// Track Lost: Query KeyFrame Database for keyframe candidates for relocalisationvector<KeyFrame*> vpCandidateKFs = mpKeyFrameDB->DetectRelocalizationCandidates(&mCurrentFrame);
其次,寻找有足够多的特征点匹配的关键帧;最后,利用RANSAC迭代,然后使用PnP算法求解位姿。这一部分也在Tracking::Relocalization() 里。
四、局部地图跟踪
通过之前的计算,已经得到一个对位姿的初始估计,我们就能透过投影,从已经生成的地图点中找到更多的对应关系,来精确结果。函数入口为:
bOK = TrackLocalMap();
为了降低复杂度,这里只是在局部图中做投影。局部地图中与当前帧有相同点的关键帧序列成为K1,在covisibility graph中与K1相邻的称为K2。局部地图有一个参考关键帧Kref∈K1,它与当前帧具有最多共同看到的地图云点。针对K1, K2可见的每个地图云点,通过如下步骤,在当前帧中进行搜索:
(1)将地图点投影到当前帧上,如果超出图像范围,就将其舍弃;
(2)计算当前视线方向向量v与地图点云平均视线方向向量n的夹角,舍弃n·v < cos(60°)的点云;
(3)计算地图点到相机中心的距离d,认为[dmin, dmax]是尺度不变的区域,若d不在这个区域,就将其舍弃;
(4)计算图像的尺度因子,为d/dmin;
(5)将地图点的特征描述子D与还未匹配上的ORB特征进行比较,根据前面的尺度因子,找到最佳匹配。
这样,相机位姿就能通过匹配所有地图点,最终被优化。
五、关键帧的判断标准
最后一步是确定是否将当前帧定为关键帧,由于在Local Mapping中,会剔除冗余关键帧,所以我们要尽快插入新的关键帧,这样才能更鲁棒。这个部分代码为:
// Check if we need to insert a new keyframe
if(NeedNewKeyFrame())CreateNewKeyFrame();
确定关键帧的标准如下:
(1)在上一个全局重定位后,又过了20帧;
(2)局部建图闲置,或在上一个关键帧插入后,又过了20帧;
(3)当前帧跟踪到大于50个点;
(4)当前帧跟踪到的比参考关键帧少90%。
六、代码架构
ORB-SLAM2详解(四)跟踪相关推荐
- ORB特征提取详解 BRUEF rBRIEF steered BRIEF
ORB特征提取详解 1.算法介绍 ORB(Oriented FAST and Rotated BRIEF)是一种快速特征点提取和描述的算法.这个算法是由Ethan Rublee, Vincent Ra ...
- linux 进程间通信 dbus-glib【实例】详解四(上) C库 dbus-glib 使用(附代码)(编写接口描述文件.xml,dbus-binding-tool工具生成绑定文件)(列集散集函数)
linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...
- Android Studio 插件开发详解四:填坑
转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78265540 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...
- springboot 详解 (四)redis filter
---------------------------------------------------------------------------------------------------- ...
- 数据结构--图(Graph)详解(四)
数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...
- .NET DLL 保护措施详解(四)各操作系统运行情况
我准备了WEB应用程序及WinForm应用程序,分别在WIN SERVER 2012/2008/2003.Win7/10上实测,以下为实测结果截图: 2012 2008 2003 WIN7 WIN10 ...
- mybatis 鉴别其_MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询
MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询 白玉 IT哈哈 支持的 JDBC 类型 为了未来的参考,MyBatis 通过包含的 jdbcType 枚举型,支持下面的 ...
- App Widgets 详解四 RemoteViews、RemoteViewsService和RemoteViewsFactory
导读 本篇文章将介绍"集合视图",App Widget 复杂布局的实现 App Widget 小部件系列其他文章链接 App Widgets 详解一 简单使用 App Widget ...
- java实现标准化考试系统详解(四)-----初始化操作实现
(一)初始化操作实现 如上图所示当管理员需要更改适用工程.试题数量.考试时间时直接在文本中更改就好我们只需要每次在用户打开程序时初始化这些参数就可以 1.初始化试题模型,这里需要实现随机抽题,方法是用 ...
- Linux字符设备驱动详解四(使用自属的xbus驱动总线)
文章目录 系列文章目录 前言 驱动目录 正文 驱动总线 总线管理 总线注册 设备注册 驱动注册 代码示例 总结 系列文章目录 Linux字符设备驱动详解 Linux字符设备驱动详解二(使用设备驱动模型 ...
最新文章
- 【神经网络】(17) EfficientNet 代码复现,网络解析,附Tensorflow完整代码
- Vue搜索框保存临时搜索的记录
- 如果要将对象用作Map中的key,需要注意什么
- 华为精益敏捷专家:DevOps转型中的那些坑
- 如何快速学习Java?
- 恐龙拼图游戏 - 恐龙拼图乐园积木游戏
- 【EasyUI】DataGrid 合并单元格 - 使用实例
- shell管道重定向程序的实现
- ros构建机器人运动学模型_机器人开源控制软件 OROCOS
- Android 横屏启动activity,点击屏幕的单击、双击和长按事件
- jq json格式化工具
- JAVA 异或校验byte数组
- Understanding Deep Image Representations by Inverting Them
- miRNA 在基因调控中的作用
- 黑苹果html5,黑苹果配置必备神器 Clover Configurator v5.10.0.0 官方中文原版
- webERP安装配置超详细
- 干货 | 万字长文详解携程酒店订单缓存 存储系统升级实践
- java编写出一个小船的代码
- Oracle EBS R12开发工具安装
- dns-服务器--转发设置-域控dns配置
热门文章
- 枚举类与注解(复习)
- linux php 验证码不显示_如何解决linux php 验证码不显示的问题
- BackTrack V5的汉化
- Qmail+Mini Howto
- TesseractOCR(光学字符识别)引擎概述(一)
- 7.2 IDEA 没有Java EE
- 网络流中最大流和最小割算法
- C#Windows7任务栏开发Thumbnail Toolbars(缩略图、工具栏按钮)
- 鲁棒优化入门(4)-两阶段鲁棒优化及行列生成算法(CCG)超详细讲解(附matlab代码)
- Python tkinter Text 多行文本框变化事件