ORB-SLAM2详解(四)跟踪

本文详细介绍了ORB-SLAM2系统中的跟踪模块。主要包括ORB特征提取、使用运动模型和关键帧进行位姿初始化、全局重定位、局部地图跟踪以及关键帧判断标准等内容。

ORB-SLAM2详解(四)跟踪

欢迎转载,转载请注明网址http://blog.youkuaiyun.com/u010128736/



  这一部分是ORB_SLAM系统中最基本的一步,会对每一帧图像进行跟踪计算。Tracking线程运行在主线程中,主要思路是在当前帧和(局部)地图之间寻找尽可能多的对应关系,来优化当前帧的位姿。每次新采集到一帧图像,就是用下列接口将图像传入SLAM系统就行处理。该代码位于主程序中:

    // Pass the image to the SLAM system
    SLAM.TrackMonocular(im,tframe);
   
  • 1
  • 2
  • 1
  • 2

在检查完系统将模式切换为跟踪模式后,是用下面接口进入功能:

mpTracker->GrabImageMonocular(im,timestamp);
   
  • 1
  • 1

一、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();
}
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

当使用运动模式匹配到的特征点数较少时,就会选用关键帧模式。即尝试和最近一个关键帧去做匹配。为了快速匹配,本文利用了bag of words(BoW)来加速。首先,计算当前帧的BoW,并设定初始位姿为上一帧的位姿;其次,根据位姿和BoW词典来寻找特征匹配,使用函数matcher.SearchByBoW();最后,利用匹配的特征优化位姿。

三、通过全局重定位来初始化位姿估计

  假如使用上面的方法,当前帧与最近邻关键帧的匹配也失败了,那么意味着需要重新定位才能继续跟踪。重定位的入口如下:

bOK = Relocalization();
   
  • 1
  • 1

此时,只有去和所有关键帧匹配,看能否找到合适的位置。首先,计算当前帧的BOW向量,在关键帧词典数据库中选取若干关键帧作为候选。使用函数如下:


    // Relocalization is performed when tracking is lost
    // Track Lost: Query KeyFrame Database for keyframe candidates for relocalisation
    vector<KeyFrame*> vpCandidateKFs = mpKeyFrameDB->DetectRelocalizationCandidates(&mCurrentFrame);

   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

其次,寻找有足够多的特征点匹配的关键帧;最后,利用RANSAC迭代,然后使用PnP算法求解位姿。这一部分也在Tracking::Relocalization() 里。

四、局部地图跟踪

  通过之前的计算,已经得到一个对位姿的初始估计,我们就能透过投影,从已经生成的地图点中找到更多的对应关系,来精确结果。函数入口为:

bOK = TrackLocalMap();
   
  • 1
  • 1

为了降低复杂度,这里只是在局部图中做投影。局部地图中与当前帧有相同点的关键帧序列成为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
  • 2
  • 3
  • 1
  • 2
  • 3

确定关键帧的标准如下: 
(1)在上一个全局重定位后,又过了20帧; 
(2)局部建图闲置,或在上一个关键帧插入后,又过了20帧; 
(3)当前帧跟踪到大于50个点; 
(4)当前帧跟踪到的比参考关键帧少90%。

六、代码架构

这里写图片描述

### ORB-SLAM 源码详解与教程解析 ORB-SLAM 是一个开源的视觉 SLAM 系统,支持单目、双目和 RGB-D 相机。其源码结构复杂,涉及多线程、特征提取、位姿估计等多个模块。以下是对 ORB-SLAM 源码的详细解析和教程内容。 #### 1. ORB-SLAM 的代码框架 ORB-SLAM 的代码框架分为多个模块,包括跟踪(Tracking)、局部映射(Local Mapping)、回环检测(Loop Closing)等[^1]。这些模块通过多线程并行运行,确保系统的实时性和鲁棒性。推荐使用 Understand 工具来分析代码的流程图和依赖关系,这有助于理解整个框架的设计思路。如果预算有限,SourceInsight 也是一个不错的选择,可以方便地查看类的定义和方法实现[^1]。 #### 2. 运行 ORB-SLAM 的基本步骤 以 TUM 数据集为例,运行 ORB-SLAM 的命令如下: ```bash ./Examples/RGB-D/rgbd_tum Vocabulary/ORBvoc.txt Examples/RGB-D/TUM1.yaml PATH_TO_SEQUENCE_FOLDER ASSOCIATIONS_FILE ``` 其中: - `ORBvoc.txt` 是词袋模型文件,用于回环检测。 - `TUM1.yaml` 是相机的配置文件,包含内参信息。 - `PATH_TO_SEQUENCE_FOLDER` 是数据集路径。 - `ASSOCIATIONS_FILE` 是时间戳文件,用于同步图像和深度数据[^2]。 #### 3. 跟踪模块的具体实现 跟踪模块的核心任务是估计当前帧的相机位姿,并建立当前帧与地图点(Map Points, MP)之间的对应关系。具体流程如下: - 根据上一帧的位姿和匹配的 3D-2D 点对,预测当前帧的相机位姿。 - 将上一帧的地图点投影到当前帧的图像平面上。 - 在投影点附近搜索匹配的特征点,更新当前帧与地图点的关系[^3]。 #### 4. 局部映射模块的作用 局部映射模块负责构建和维护局部地图。它通过三角化当前帧中的特征点,生成新的地图点,并优化它们的空间位置。此外,局部映射还会剔除不可靠的地图点,确保地图的质量[^1]。 #### 5. 回环检测模块的功能 回环检测模块通过比较当前帧与全局地图的关键帧,检测是否存在闭环。一旦检测到闭环,系统会通过非线性优化调整地图点和关键帧的位姿,消除累积误差[^1]。 #### 6. 学习资源推荐 对于初学者,建议从官方文档和相关论文入手,了解 ORB-SLAM 的设计原理和算法细节。同时,可以参考以下教程: - [ORB-SLAM 官方 GitHub 页面](https://github.com/raulmur/ORB_SLAM2) - [ORB-SLAM 代码详解系列博客](https://blog.youkuaiyun.com/column/details/orb-slam-code-analysis.html) #### 示例代码:初始化 ORB 特征提取器 以下是 ORB-SLAM 中初始化 ORB 特征提取器的代码示例: ```cpp #include <opencv2/opencv.hpp> int main() { cv::Ptr<cv::ORB> orb = cv::ORB::create(); cv::Mat image = cv::imread("example.jpg", cv::IMREAD_GRAYSCALE); std::vector<cv::KeyPoint> keypoints; cv::Mat descriptors; orb->detectAndCompute(image, cv::Mat(), keypoints, descriptors); return 0; } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值