ORB-SLAM2源码学习:Tracking.cc:Tracking::TrackWithMotionModel恒速模型跟踪

ops/2024/12/16 13:36:54/

前言

什么是恒速跟踪模型?

两个图像帧之间一般只有几十毫秒的时间,在这么短的时间内,可以做出如下合理的假设:

假设相机在短时间内的运动速度是恒定的,用之前帧的位姿和速度来预测当前帧的相机位姿,我们称之为恒速模型跟踪。

在系统初始化时,由于缺乏足够的信息(如速度信息),只能依赖于参考关键帧来进行粗略的位姿估计,这时常常会使用词袋匹配等简单的方法来获取初步位姿。这一步是“被逼无奈”的,因为此时没有足够的动态信息。然而,一旦参考关键帧跟踪成功并且速度信息得到了确定,系统就可以切换到更高效的恒速模型。恒速模型在此时非常合适,因为它假设在短时间内运动速度变化不大,可以直接利用前一帧的速度信息来估计当前位姿。这种方法比起参考关键帧跟踪要简单得多,同时也能显著提高跟踪的速度和效率,这对于实时性要求较高的SLAM系统是非常有意义的。

恒速模型跟踪的优缺点:跟踪仅需要上一帧的信息, 是跟踪第一阶段中最常使用的跟踪方法。增加了一些技巧,可提高跟踪的稳定性。比如,在双目相机和RGB-D相机模式下生成的临时地图点可提高跟踪的成功率;投影匹配数目不足时没有马上放弃,而是将搜索范围扩大一倍再试一次。但恒速模型过于理想化, 在帧率较低且运动变化较大的场景中可能会跟踪丢失。 

1.函数声明

bool Tracking::TrackWithMotionModel()

2.函数定义 

步骤:

1.更新上一帧的位姿,对于双目相机或者是RGBD相机来说,还会根据深度值生成临时地图点。

2.根据之前估计的速度,用恒速模型得到当前帧的初始位姿。 

3.用上一帧的地图点进行投影匹配,如果匹配点不够,则扩大搜索半径再试一次。

4. 利用3D-2D 投影关系,优化当前帧的位姿。

5.剔除地图点中的外点,并清除其所有关系。 

6.统计匹配成功的特征点对数目,若超过阈值,则认为跟踪成功。 

/*根据恒定速度模型用上一帧地图点来对当前帧进行跟踪1:更新上一帧的位姿;对于双目或RGB-D相机,还会根据深度值生成临时地图点2:根据上一帧特征点对应地图点进行投影匹配3:优化当前帧位姿4:剔除地图点中外点return 如果匹配数大于10,认为跟踪成功,返回true*/
bool Tracking::TrackWithMotionModel()
{// 最小距离 < 0.9*次小距离 匹配成功,检查旋转ORBmatcher matcher(0.9,true);// Update last frame pose according to its reference keyframe// Create "visual odometry" points// Step 1:更新上一帧的位姿;对于双目或RGB-D相机,还会根据深度值生成临时地图点UpdateLastFrame();// Step 2:根据之前估计的速度,用恒速模型得到当前帧的初始位姿。mCurrentFrame.SetPose(mVelocity*mLastFrame.mTcw);// 清空当前帧的地图点fill(mCurrentFrame.mvpMapPoints.begin(),mCurrentFrame.mvpMapPoints.end(),static_cast<MapPoint*>(NULL));// Project points seen in previous frame// 设置特征匹配过程中的搜索半径int th;if(mSensor!=System::STEREO)th=15;//单目elseth=7;//双目// Step 3:用上一帧地图点进行投影匹配,如果匹配点不够,则扩大搜索半径再来一次int nmatches = matcher.SearchByProjection(mCurrentFrame,mLastFrame,th,mSensor==System::MONOCULAR);// If few matches, uses a wider window search// 如果匹配点太少,则扩大搜索半径再来一次if(nmatches<20){fill(mCurrentFrame.mvpMapPoints.begin(),mCurrentFrame.mvpMapPoints.end(),static_cast<MapPoint*>(NULL));nmatches = matcher.SearchByProjection(mCurrentFrame,mLastFrame,2*th,mSensor==System::MONOCULAR); // 2*th}// 如果还是不能够获得足够的匹配点,那么就认为跟踪失败if(nmatches<20)return false;// Optimize frame pose with all matches// Step 4:利用3D-2D投影关系,优化当前帧位姿Optimizer::PoseOptimization(&mCurrentFrame);// Discard outliers// Step 5:剔除地图点中外点int nmatchesMap = 0;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++;}}    if(mbOnlyTracking){// 纯定位模式下:如果成功追踪的地图点非常少,那么这里的mbVO标志就会置位mbVO = nmatchesMap<10;return nmatches>20;}// Step 6:匹配超过10个点就认为跟踪成功return nmatchesMap>=10;
}

结束语 

以上就是我学习到的内容,如果对您有帮助请多多支持我,如果哪里有问题欢迎大家在评论区积极讨论,我看到会及时回复。


http://www.ppmy.cn/ops/142374.html

相关文章

第三十八天|动态规划|背包问题总结,322. 零钱兑换,279.完全平方数,139.单词拆分,多重背包

目录 322. 零钱兑换 279.完全平方数 先遍历物品, 再遍历背包&#xff08;好理解一点&#xff09; 先遍历背包, 再遍历物品 139.单词拆分 方法1&#xff1a;完全背包 方法2&#xff1a;完全背包2 方法3&#xff1a;回溯法记忆化 多重背包 背包问题总结 背包递推公式 …

MySQL 性能调优:打造高效数据库

SQL 语句层面的性能调优策略 合理选择字段属性 在创建 MySQL 表时&#xff0c;为了获取更好的性能&#xff0c;选择合适的字段属性至关重要。 首先&#xff0c;要依据实际情况合理设置字段的类型及宽度。例如&#xff0c;对于像手机号码这类固定长度为 11 位的字段&#xff…

我们来对接蓝凌OA --报文格式

题记 数智化办公专家、国家高新技术企业、知识管理国家标准制定者、信创供应商10强…等等&#xff0c;这些和咱们有关系吗&#xff01;&#xff01;不好意思&#xff0c;走错片场了&#xff0c;刚和项目经理在甲方那边吹牛B想想刚刚的大饼&#xff0c;看看支付宝余额&#xff…

Selenium WebDriver:自动化网页交互的利器

Selenium WebDriver&#xff1a;自动化网页交互的利器 在当今快速发展的Web开发领域&#xff0c;自动化测试已经成为确保应用程序质量和用户体验的重要手段。Selenium WebDriver&#xff0c;作为Selenium工具包中的核心组件&#xff0c;正是这一领域的佼佼者。本文将详细介绍S…

ARM/Linux嵌入式面经(五五):未岚大陆

文章目录 0、项目中既有flash又有E2,为什么不只使用一个?问题回答:1、uart通信与i2c通讯的硬件区别;2、说说你理解的pid算法;问题回答3、串口转usb怎么实现的?问题回答:4、软件采集的adc数据有没有滤波;问题回答5、是否使用过boot?你觉得使用boot的注意事项是什么?问…

FPGA的EDA工具的测试方法

一&#xff1a;概述 都说EDA工具很难&#xff08;芯片设计不可缺少的工具&#xff09;&#xff0c;目前我国正在举国之力来发展它&#xff08;因为之前我国一直没在这个领域做基础研究&#xff0c;一直是使用者&#xff0c;所以&#xff0c;被美国拉开了很大的差距&#xff09…

k8s调度策略

调度策略 binpack&#xff08;装箱策略&#xff09; Binpacking策略&#xff08;又称装箱问题&#xff09;是一种优化算法&#xff0c;用于将物品有效地放入容器&#xff08;或“箱子”&#xff09;中&#xff0c;使得所使用的容器数量最少&#xff0c;Kubernetes等集群管理系…

Python(动态语言)和C++(静态语言)运行时和编译时比较:中英双语

中文版 什么是“动态调用方法”&#xff1f; 动态调用方法指在程序运行时&#xff0c;根据方法名称&#xff08;通常以字符串形式提供&#xff09;来调用对象的具体方法&#xff0c;而不是在代码编写和编译时就明确调用的方法。这种特性可以使程序更加灵活&#xff0c;尤其在…