• ORB-SLAM2 ---- Tracking::UpdateLastFrame函数


    目录

    1.函数作用

    2.步骤 

    3.code 

    4.函数解释

    4.1 利用参考关键帧更新上一帧在世界坐标系下的位姿

    4.2 对于双目或rgbd相机,为上一帧生成新的临时地图点 


    1.函数作用

            更新上一帧位姿,在上一帧中生成临时地图点。

            单目情况:只计算了上一帧的世界坐标系位姿
            双目和rgbd情况:选取有有深度值的并且没有被选为地图点的点生成新的临时地图点,提高跟踪鲁棒性

    2.步骤 

    Step 1:利用参考关键帧更新上一帧在世界坐标系下的位姿

    Step 2:对于双目或rgbd相机,为上一帧生成新的临时地图点

    Step 2.1:得到上一帧中具有有效深度值的特征点(不一定是地图点)

    Step 2.2:从中找出不是地图点的部分  

    Step 2.3:需要创建的点,包装为地图点。只是为了提高双目和RGBD的跟踪成功率,并没有添加复杂属性,因为后面会扔掉

    Step 2.4:如果地图点质量不好,停止创建地图点

    3.code 

    1. void Tracking::UpdateLastFrame()
    2. {
    3. // Update pose according to reference keyframe
    4. // Step 1:利用参考关键帧更新上一帧在世界坐标系下的位姿
    5. // 上一普通帧的参考关键帧,注意这里用的是参考关键帧(位姿准)而不是上上一帧的普通帧
    6. KeyFrame* pRef = mLastFrame.mpReferenceKF;
    7. // ref_keyframe 到 lastframe的位姿变换
    8. cv::Mat Tlr = mlRelativeFramePoses.back();
    9. // 将上一帧的世界坐标系下的位姿计算出来
    10. // l:last, r:reference, w:world
    11. // Tlw = Tlr*Trw
    12. mLastFrame.SetPose(Tlr*pRef->GetPose());
    13. // 如果上一帧为关键帧,或者单目的情况,则退出
    14. if(mnLastKeyFrameId==mLastFrame.mnId || mSensor==System::MONOCULAR)
    15. return;
    16. // Step 2:对于双目或rgbd相机,为上一帧生成新的临时地图点
    17. // 注意这些地图点只是用来跟踪,不加入到地图中,跟踪完后会删除
    18. // Create "visual odometry" MapPoints
    19. // We sort points according to their measured depth by the stereo/RGB-D sensor
    20. // Step 2.1:得到上一帧中具有有效深度值的特征点(不一定是地图点)
    21. vectorfloat,int> > vDepthIdx;
    22. vDepthIdx.reserve(mLastFrame.N);
    23. for(int i=0; i
    24. {
    25. float z = mLastFrame.mvDepth[i];
    26. if(z>0)
    27. {
    28. // vDepthIdx第一个元素是某个点的深度,第二个元素是对应的特征点id
    29. vDepthIdx.push_back(make_pair(z,i));
    30. }
    31. }
    32. // 如果上一帧中没有有效深度的点,那么就直接退出
    33. if(vDepthIdx.empty())
    34. return;
    35. // 按照深度从小到大排序
    36. sort(vDepthIdx.begin(),vDepthIdx.end());
    37. // We insert all close points (depth
    38. // If less than 100 close points, we insert the 100 closest ones.
    39. // Step 2.2:从中找出不是地图点的部分
    40. int nPoints = 0;
    41. for(size_t j=0; jsize();j++)
    42. {
    43. int i = vDepthIdx[j].second;
    44. bool bCreateNew = false;
    45. // 如果这个点对应在上一帧中的地图点没有,或者创建后就没有被观测到,那么就生成一个临时的地图点
    46. MapPoint* pMP = mLastFrame.mvpMapPoints[i];
    47. if(!pMP)
    48. bCreateNew = true;
    49. else if(pMP->Observations()<1)
    50. {
    51. // 地图点被创建后就没有被观测,认为不靠谱,也需要重新创建
    52. bCreateNew = true;
    53. }
    54. if(bCreateNew)
    55. {
    56. // Step 2.3:需要创建的点,包装为地图点。只是为了提高双目和RGBD的跟踪成功率,并没有添加复杂属性,因为后面会扔掉
    57. // 反投影到世界坐标系中
    58. cv::Mat x3D = mLastFrame.UnprojectStereo(i);
    59. MapPoint* pNewMP = new MapPoint(
    60. x3D, // 世界坐标系坐标
    61. mpMap, // 跟踪的全局地图
    62. &mLastFrame, // 存在这个特征点的帧(上一帧)
    63. i); // 特征点id
    64. // 加入上一帧的地图点中
    65. mLastFrame.mvpMapPoints[i]=pNewMP;
    66. // 标记为临时添加的MapPoint,之后在CreateNewKeyFrame之前会全部删除
    67. mlpTemporalPoints.push_back(pNewMP);
    68. nPoints++;
    69. }
    70. else
    71. {
    72. // 因为从近到远排序,记录其中不需要创建地图点的个数
    73. nPoints++;
    74. }
    75. // Step 2.4:如果地图点质量不好,停止创建地图点
    76. // 停止新增临时地图点必须同时满足以下条件:
    77. // 1、当前的点的深度已经超过了设定的深度阈值(35倍基线)
    78. // 2、nPoints已经超过100个点,说明距离比较远了,可能不准确,停掉退出
    79. if(vDepthIdx[j].first>mThDepth && nPoints>100)
    80. break;
    81. }
    82. }

    4.函数解释

    4.1 利用参考关键帧更新上一帧在世界坐标系下的位姿

             如上图,我们获得上一普通帧mLastFrame的参考关键帧pRef,获得ref_keyframe 到 lastframe的位姿变换Tlr,用Tlw = Tlr*Trw获得lastframe的位姿。

            如果上一帧为关键帧,或者单目的情况,则退出。

    4.2 对于双目或rgbd相机,为上一帧生成新的临时地图点 

            注意这些地图点只是用来跟踪,不加入到地图中,跟踪完后会删除。

            遍历上一帧LastFrame中具有有效深度值的特征点(不一定是地图点),记录特征点的深度和序号到vDepthIdx容器中。接着按照深度从小到大排序。

            遍历具有有效深度值的特征点vDepthIdx,用变量i记录是该特征点LastFrame中的哪个索引,如果这个点:

            ①对应在上一帧LastFrame中的地图点没有(!pMP)

            ②或者创建后就没有被观测到(pMP->Observations()<1)

            那么就生成一个临时的地图点

            将这个特征点反投影到世界坐标系中得到3D点x3D,并包装成地图点pNewMP,加入上一帧LastFrame的地图点mvpMapPoints中,标记为临时添加的MapPointmlpTemporalPoints.,之后在CreateNewKeyFrame之前会全部删除。将标记nPoints++。

            如果地图上有地图点我们也需要将nPoints++。

            直到满足下列条件我们停止新增LastFrame的地图点:

            ①当前的点的深度已经超过了设定的深度阈值(35倍基线)(我们之前把地图点的深度从小到大排序)

            ②nPoints已经超过100个点,说明距离比较远了,可能不准确,停掉退出

  • 相关阅读:
    数据库的基本概念
    【管理运筹学】第 7 章 | 图与网络分析(1,图论背景以及基本概念、术语、矩阵表示)
    C# 连接SQL Sever 数据库与数据查询实例 数据仓库
    mindspore1.5版本下能正常运行到了1.6‘_check_version.py’报错
    无框折叠玻璃隔断,上下轨道自由折叠门,集美丽与实用一体,开启空间最大化
    PHP 5 SimpleXML 函数
    2022年,谁才是编程语言中的天选之子?
    高职院校云计算人才培养成果导向系统构建、实施要点与评量方法
    【最佳实践】高可用mongodb集群(1分片+3副本):规划及部署
    Centos7根目录扩容方法(添加一块磁盘扩容根目录)
  • 原文地址:https://blog.csdn.net/qq_41694024/article/details/128192577