重读ORB之Tracking线程难点

Posted Eason_Jiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重读ORB之Tracking线程难点相关的知识,希望对你有一定的参考价值。

1. 初始化

当获取第一帧图像与深度图后,首先设置第一帧位姿为4*4单位矩阵,然后为整个map添加关键帧与地图点。且更新地图点与关键帧的联系,例如地图点被哪个关键帧观测到,而此关键帧又包含哪些地图点。而且不得不为ORB的处理细节感动,每个地图点因为对应着不同关键帧的特征点,需要择优选取地图点最合适的描述子,pNewMP->ComputeDistinctiveDescriptors()。然后为localmapping线程添加关键帧,以及其他一些准备工作。

2. 正常定位建图模式

后续的定位工作,主要由四个函数完成,首先如果有速度信息,就会采取TrackWithMotionModel,没有速度信息或者重定位后的第一帧就会采用TrackReferenceKeyFrame(),当运动速度快,或者其他原因导致定位失败,会一直采用重定位方法。在跟踪当前帧成功后,还要在TrackLocalMap里继续对局部地图做跟踪以及优化位姿。这个localmap局部地图很有迷惑性,跟localMapping感觉很相似。但是两者有很大不同,localmap有两部分组成,一个是局部关键帧,一个是局部地图点。局部关键帧由与当前关键帧有共同观测点的其他关键帧组成,且包括其自身。如果localkeyframes不到80帧,则继续添加每个localkeyframes内的邻居关键帧,孩子与父关键帧。localMapping 则是根据传来的关键帧,经过计算,往整体的map中添加数据。localPoints就很容易理解了,把局部关键帧内所有的看到的地图点都添加进去。重定位函数Relocalization,就是在关键帧库里搜索能匹配上的关键帧,做相对位姿计算。

3. 只定位不建图模式

这种模式下,首先会进行重定位,然后根据mbVO 参数判断是进行正常的跟踪定位操作还是要结合重定位信息。mbVO为真表示当前图像和上一帧地图点匹配数目小于10,有可能是运动过快的原因。

  1. 假如上次定位显示,mbVO为0,则进行正常的定位跟踪,但是发现跟踪后mbVO在TrackWithMotionModel里被设置为1了,且定位是成功的,则进行正常的更新速度以及显示操作,如果mbVO仍然为0,则要先跟局部地图进行匹配跟踪,优化位姿,再进行后续操作。因为如果mbVO为1时,也就是跟上一帧地图点匹配较少时,可能得不到有效的局部地图信息。
  2. 在下次定位时,如果mbVO为1,则先进行TrackWithMotionModel跟踪,再进行重定位,为的是保证定位不会轻易丢失。但是如果运动速度仍然过快,mbVO 仍然为1,则下次任然重复步骤2。直到TrackWithMotionModel里设置mbVO为0,或者重定位成功把mbVO设置为0。

4. 结尾处理

此处有两个点比较难理解:

  1. 为什么会存在观测值小于1的地图点?

             // Clean VO matches
            for(int i=0; i<mCurrentFrame.N; i++)
            {
                MapPoint* pMP = mCurrentFrame.mvpMapPoints[i];
                if(pMP)
                    if(pMP->Observations()<1)
                    {
                        mCurrentFrame.mvbOutlier[i] = false;
                        mCurrentFrame.mvpMapPoints[i]=static_cast<MapPoint*>(NULL);
                    }
            }

    梳理之后发现,在localMapping中,会对局部地图进行优化,会对地图点和关键帧的关系做出调整,有些地图点就会删掉某些observation。所以这里需要处理。

  2. 要删去一些临时地图点,这些点从哪里来的?

            // Delete temporal MapPoints
            for(list<MapPoint*>::iterator lit = mlpTemporalPoints.begin(), lend =  mlpTemporalPoints.end(); lit!=lend; lit++)
            {
                MapPoint* pMP = *lit;
                delete pMP;
            }
            mlpTemporalPoints.clear()

    在TrackWithMotionModel里有一个UpdateLastFFrame函数,在纯定位模式下,会根据深度图新增一些临时地图点,为的是增加匹配点数,使位姿更准确。所以后面要把这些临时的地图点删去。

以上是关于重读ORB之Tracking线程难点的主要内容,如果未能解决你的问题,请参考以下文章

ORB-SLAM2 论文&代码学习 —— Tracking 线程

ORB-SLAM2学习5 Tracking.h

ORB-SLAM2 论文&代码学习 —— LoopClosing 线程

orb slam 的哪一个线程的代码量最大

回炉重造之重读Windows核心编程-011-线程池和其他异步方式

ORBSLAM2代码阅读-tracking.cpp