ORB-SLAM2源码逐行解析系列(十七):ORB-SLAM2中的跟踪方法

(1)原理​  参考关键帧跟踪是将当前普通帧(位姿未知)和它对应的参考关键帧(位姿已知)进行特征匹配及优化,从而估计当前普通帧的位姿。其中,可通过基于词袋的SearchByBoW来加速两帧之间的特征匹配。(2)应用场景(3)大致流程(4)代码实现。
摘要由CSDN通过智能技术生成

1. 参考关键帧跟踪

(1)原理

​  参考关键帧跟踪是将当前普通帧(位姿未知)和它对应的参考关键帧(位姿已知)进行特征匹配及优化,从而估计当前普通帧的位姿。其中,可通过基于词袋的SearchByBoW来加速两帧之间的特征匹配。

(2)应用场景

  • 地图刚刚初始化之后,此时恒速模型中的速度为空,只能使用参考关键帧,即使用初始化后的第1、2帧对当前帧进行跟踪
  • 恒速模型跟踪失败后,尝试使用最近的参考关键帧跟踪当前普通帧。

(3)大致流程

  • 通过基于词袋的方法,对当前普通帧和参考关键帧进行特征匹配,获取匹配上的地图点(此时,也属于当前普通帧的地图点)
  • 通过优化3D-2D的重投影误差,获取当前普通帧的准确位姿,同时标记匹配点中的外点。其中,3D点通过匹配得到的,2D点来自于当前普通帧,优化时需要的当前普通帧位姿来自于上一帧位姿。
  • 统计经过优化并剔除外点后的成功匹配点数,若超过10,则认为跟踪成功。

(4)代码实现

/*
 * @brief 用参考关键帧的地图点来对当前普通帧进行跟踪
 * 
 * Step 1:将当前普通帧的描述子转化为BoW向量,通过计算出的词袋将当前帧的特征点分配到特定层的nodes上
 * Step 2:通过词袋BoW加速当前帧与参考帧之间的特征点匹配: 对属于同一node的描述子进行匹配
 *         根据匹配特征点对来估计当前帧的位姿
 * Step 3: 将上一帧的位姿作为当前普通帧位姿的初始值
 * Step 4: 通过优化3D-2D的重投影误差来获得位姿
 * Step 5:根据位姿剔除优化后的匹配点中的外点
 * @return 如果匹配数超过10,返回true
 * 
 */
bool Tracking::TrackReferenceKeyFrame()
{
   
    // Step 1:将当前帧的描述子转化为BoW向量
    mCurrentFrame.ComputeBoW();
    ORBmatcher matcher(0.7,true);
    vector<MapPoint*> vpMapPointMatches;
    
    // Step 2:通过词袋BoW加速当前帧与参考帧之间的特征点匹配
    int nmatches = matcher.SearchByBoW(
        mpReferenceKF,          // 参考关键帧
        mCurrentFrame,          // 当前帧
        vpMapPointMatches);     // 存储的是匹配上的当前帧与参考帧的共同MapPoint
    // 若匹配地图点数目小于15,则认为跟踪失败
    if(nmatches<15)
        return false;
    
    // Step 3:将上一帧的位姿作为当前普通帧位姿的初始值,可以加速BA收敛
    mCurrentFrame.mvpMapPoints = vpMapPointMatches;  // 从上面的匹配中获取当前帧的地图点
    mCurrentFrame.SetPose(mLastFrame.mTcw); 
    
    // Step 4:通过优化3D-2D的重投影误差来获得位姿  仅对当前普通帧位姿进行优化,没有对3D点进行优化
    Optimizer::PoseOptimization(&mCurrentFrame);
    
    // Step 5:剔除优化后的匹配点中的外点,在优化过程中对这些外点做了标记
    int nmatchesMap = 0;  // 成功匹配的3D点数目(仅含内点)
    for(int i =0; i<mCurrentFrame.N; i++)  // 遍历当前帧中优化后还存在的特征点
    {
   
		if(mCurrentFrame.mvpMapPoints[i])  // 判断特征点对应的地图点是否存在
        {
   
            // 存在地图点的情况下,判断该特征点是否为外点
            if(mCurrentFrame.mvbOutlier[i])
            {
   
                // 清除此时的外点在当前帧中存在过的痕迹
                MapPoint* pMP = mCurrentFrame.mvpMapPoints[i];

                mCurrentFrame.mvpMapPoints[i]=static_cast<MapPoint*>(NULL);
                mCurrentFrame.mvbOutlier[i]=false;
                pMP->mbTrackInView = false;
                pMP->mnLastFrameSeen = mCurrentFrame.mnId;
                nmatches--;
            }
            else if(mCurrentFrame.mvpMapPoints[i]->Observations()>0)
                // 累加成功匹配到的地图点数目
                nmatchesMap++;
        }
    }
    
    // 跟踪成功的地图点数目超过10才认为跟踪成功,否则认为跟踪失败
    return nmatchesMap>=10;
}

2. 恒速模型跟踪

(1)应用场景

​ 参考关键帧跟踪涉及到词袋匹配、非线性优化等过程,比较复杂,实时性难以实现。

​ 恒速模型跟踪是假设在相邻帧间极短的时间内,相机处于匀速运动状态,使用上一帧位姿以及通过参考关键帧跟踪获取到的速度来估计当前帧位姿。相比参考关键帧跟踪而言,恒速模型跟踪估计位姿更简单、更快,可实现SLAM的实时性要求。因此,在初始使用参考关键帧跟踪后,大部分时间使用恒速模型跟踪。

注意:这里说的速度是指上一帧到当前帧的位姿变化,并不是指实际中的物理速度。

(2)原理

​ 恒速模型中认为相邻帧间的速度(位姿变换)是不变的,即认为上一帧到当前最新帧之间的位姿变换和上上一帧到上一帧之间的位姿变换相同,那么当前帧的位姿就可以通过上一帧位姿以及速度(上一帧到当前帧的位姿变换)计算出来:
T c w = V T l w T_{cw} = VT_{lw} Tcw=VTlw
​ 式中, c c c表示 c u r r e n t current current,即当前普通帧; l l l表示 l a s t last last,即上一帧; w w w表示 w o r l d world world,即世界坐标系。

​ 对于速度 V V V,它在跟踪线程Track中是不断更新的,对应代码中的成员变量 m V e l o c i t y mVelocity mVelocity,更新方程为:
V = T c l = T c w T w l V = T_{cl} = T_{cw}T_{wl} V=Tcl=TcwTwl
​ 对于上一帧位姿 T l w T_{lw} Tlw​,在上一帧跟踪成功后可直接获取。但由于上一帧可能是普通帧,没有参与优化,对应的位姿不太准确,而关键帧会在局部建图线程中进一步优化。因此,代码中是通过上一帧对应的参考关键帧来获取上一帧的准确位姿,计算如下:
T l w = T l r T r w T_{lw} = T_{lr}T_{rw} Tlw=TlrTrw
​ 式中, r r r表示 r e f e r e n c e reference reference,即参考关键帧。 T l r T_{lr} Tlr表示参考关键帧到上一帧的位姿变换,对应代码中的成员变量 m l R e l a t i v e F r a m e P o s e s mlRelativeFramePoses mlRelativeFramePoses,在跟踪线程Track中不断更新, T r w T_rw Trw表示参考关键帧的位姿。

(3)更新上一帧位姿UpdateLastFrame

​ 对于单目相机,只需要获取上一帧位姿即可。对于双目/RGB-D相机,还需要将深度值符合要求,且未创建为地图点的3D点创建为临时地图点,用以提高跟踪的鲁棒性。

大致流程

  • 利用参考关键帧更新上一帧在世界坐标系下的位姿,具体实现如下:
    • 获取上一帧的参考关键帧pRef
    • 获取参考关键帧的位姿pRef->GetPose()
    • 从mlRelativaFramePoses中获取参考关键帧到上一帧的位姿变换Tlr
    • 通过公式获取上一帧的位姿
  • 对于双目/RGB-D相机,还需要为上一帧生成临时地图点mlpTemporalPoints,其目的是用来增加跟踪的稳定性,在跟踪结束后会丢弃掉,具体实现如下:
    • 获取上一帧每个地图点对应的深度值,并将深度值按照从小到大的顺序进行排序
    • 遍历上一帧的地图点,若该地图点不存在,或没有被观测到,则将bCreateNew置为True
    • 在bCreateNew为True的前提下,将该3D点创建为临时地图点
    • 若遍历到的3D点深度值超过阈值,或遍历到的点个数超过100,则停止创建临时地图点。因为遍历前已经将深度值进行从小到大排序,若遍历到的点深度值过大或者遍历点数过多,说明此时的点已经较远,无需再考虑了。

代码实现

/**
 * @brief 更新上一帧位姿,在上一帧中生成临时地图点
 * 单目情况:只计算了上一帧在世界坐标系下的位姿
 * 双目和rgbd情况:选取有深度值的并且没有被选为地图点的点生成新的临时地图点,提高跟踪鲁棒性
 */
void Tracking::UpdateLastFrame()
{
   
    // Step 1:利用参考关键帧更新上一帧在世界坐标系下的位姿
    KeyFrame* pRef = mLastFrame.mpReferenceKF;  // 获取上一帧的参考关键帧
    // ref_keyframe 到 lastframe的位姿变换  相对位姿
    cv::Mat Tlr = mlRelativeFramePoses.back();  // mlRelativeFramePoses是在Track中更新的??

    // 将上一帧在世界坐标系下的位姿计算出来  Tlw = Tlr*Trw    l:last, r:reference, w:world
    // Trw:参考关键帧在世界坐标系下的位姿  Tlr:参考关键帧到上一帧的位姿 Tlw: 上一帧在世界坐标系下的位姿
    mLastFrame.SetPose(Tlr*pRef->GetPose()); 
    
    // 如果上一帧为关键帧,或者单目的情况,则退出  (已计算出上一帧的位姿)
    if(mnLastKeyFrameId==mLastFrame.mnId || mSensor==System::MONOCULAR)
        return;
    
    // Step 2:对于双目或rgbd相机,因为其本身是有深度值的,所以可为上一帧生成新的临时地图点
    // Step 2.1:得到上一帧中具有有效深度值的特征点(不一定是地图点)
    vector<pair<float,int> > vDepthIdx;  // 存储的是特征点深度值及其索引的键值对
    vDepthIdx.reserve(mLastFrame.N);
    for(int i=0; i<mLastFrame.N;i++) 
    {
   
        float z = mLastFrame.mvDepth[i];  // 获取遍历到的上一帧中地图点的深度值
        if(z>0)  // 若深度值存在
        {
   
            // vDepthIdx第一个元素是某个点的深度,第二个元素是对应的特征点id
            vDepthIdx.push_back(make_pair(z,i));
        }
    }
    // 如果上一帧中没有有效深度的点,那么就直接退出
    if(vDepthIdx.empty())
        return;
    
    // 按照深度从小到大排序
    sort(vDepthIdx.begin()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: ORB-SLAM2是一款基于特征点的SLAM算法,可以在实时运行实现稠密地图的构建和定位。ORB-SLAM2的源代码解析v1.2 pdf为ORB-SLAM2算法的源代码进行详细讲解的文档。 这个文档详细介绍了ORB-SLAM2算法的各个模块以及其组成部分,包括图像预处理、特征点提取、视觉里程计、回环检测、地图构建和定位等。对于每个模块,文档都进行了详细的讲解,并展示了一些代码实现和示例。 其ORB特征点的提取是ORB-SLAM2的一个重要特点。文档详细介绍了ORB特征点的提取与描述,并对其进行了性能优化。在视觉里程计,文档详细介绍了基于ORB-SLAM2的相机位姿估计算法,并同时对其进行了实验验证。 此外,orb-slam2源码解析 v1.2 pdf还对ORB-SLAM2的一些扩展进行了介绍,如RGBD-SLAM、半稠密点云地图构建、直接法视觉里程计等等。 总之,ORB-SLAM2是一个非常强大的SLAM算法,通过对orb-slam2源码解析 v1.2 pdf的学习,可以更好地理解其原理和实现,也为进一步研究和应用提供了参考。 ### 回答2: ORB-SLAM2是一种基于单目相机的实时稠密SLAM系统,被广泛应用于机器人、自动驾驶、增强现实等领域。ORB-SLAM2源码解析v1.2 pdf是一份PDF文档,对ORB-SLAM2源代码进行了详细的解析和分析。 该文档分为多个章节,首先介绍了ORB-SLAM2的概述和背景,包括SLAM系统的基本原理和ORB特征点的提取与匹配算法。接着,文档对ORB-SLAM2的系统框架、流程和算法进行了详细介绍,主要包括定位、建图、闭环检测和重定位等核心模块的实现细节。 文档还对ORB-SLAM2的实验结果和性能进行了评估和分析,包括系统的重定位精度、建图质量、算法复杂度和实时性等指标。同时,文档还针对ORB-SLAM2的应用场景进行了讨论和展望,包括基于ORB-SLAM2的三维重建、SLAM与深度学习的融合等前沿研究方向。 总之,ORB-SLAM2源码解析v1.2 pdf是一份非常有价值的文档,对想要深入了解和应用ORB-SLAM2的研究者和开发者有很大的帮助和启发作用。它不仅详细介绍了ORB-SLAM2的理论基础和实现细节,还从实验和应用角度对其性能和前景进行了评估和展望,为相关领域的技术人员提供了重要的参考和指导。 ### 回答3: ORB-SLAM2是一种基于单目或双目相机的实时视觉SLAM系统,可以在无GPS信号的情况下,通过对相机的位置和姿态的估计,构建3D环境地图。 ORB-SLAM2源码解析 v1.2 PDF是一份解析ORB-SLAM2源码的文档,其包含了ORB-SLAM2的基本架构、算法实现以及关键代码的详细解释。通过学习该文档,可以深入了解ORB-SLAM2的原理和实现方法,从而更好地应用该系统进行SLAM操作。 该文档主要包括以下几个部分: 1.ORB-SLAM2的系统结构:介绍ORB-SLAM2的整体结构和各模块之间的关系。 2.特征提取与匹配:详细介绍ORB特征的提取和匹配算法,包括ORB算法原理、特征对齐和描述符生成等。 3.全局BA和回环检测:讲解ORB-SLAM2的全局优化和回环检测方法,其包括BA算法流程、优化目标函数、回环检测的实现等。 4.实时定位:探讨如何实现ORB-SLAM2的实时运动估计和位姿估计,包括相机位姿估计、尺度恢复和点云重建等内容。 除此之外,该文档还对ORB-SLAM2的一些高级技术进行了讲解,如基于深度学习的特征提取、基于语义信息的地图构建等。 总之,该文档是一份非常有价值的ORB-SLAM2源码解析资料,对于深入了解ORB-SLAM2的实现原理、优化方法和应用场景,具有重要的参考意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值