图解ORBSLAM2流程

这篇博文主要是梳理ORBSLAM2的流程,对于细节暂时不会很详细的描述(之后的博文会深究细节),且本博文暂时只描述ORBSLAM2中的Monocular(单目)情况。

在ORBSLAM2中,主要的三个线程是Tracking、LocalMapping、LoopClosing。三个线程的创建都是在System.cpp中,也就是在System类中的构造函数中创建了这三个线程。

以mono_tum.cc文件为例子,我们从main函数开始看。

1、首先构造System对象,对象名叫SLAM。正如上面所言,构造System之后,便创建了Tracking、LocalMapping、LoopClosing三个线程。

2、接下来便是一帧一帧地读取数据集中的图像,调用SLAM对象中的TrackMonocular()函数。

3、TrackMonocular()函数调用GrabImageMonocular()函数,在GrabImageMonocular()中,将第二步读取的图像转化为灰度图,并用该图像创建了mCurrentFrame对象,该对象由Frame类所构造的。调用Track()函数。

 

Track()函数便是Tracking线程中精髓所在。接下我们看Track()函数。

1、初始化,选取特征点匹配很好的相邻两帧进行初始化,具体细节另一篇博客再说,

2、跟踪,Track有TrackWithMotionModel()、TrackReferenceKeyFrame()、Relocalization(),这三个函数分别对应不同情况

下面以TrackReferenceKeyFrame()为track方式说明ORBSLAM2的流程。

 

说明下示意图中各种颜色及箭头的含义

红色为当前帧,紫色为参考关键帧。

双向箭头表示地图点和图像帧特征点之间建立了双向联系

1、图像帧与地图点建立联系:mCurrentFrame.mvpMapPoints = vpMapPointMatches;

2、地图点与图像帧建立联系:mObservations[pKF]=idx;表示pKF的第idx个特征点是这个MapPoint的对应点,是用

pMP->AddObservation(mpCurrentKeyFrame, idx); 来建立这种关系,pMP表示地图点吗,详情看MapPoint类的实现

 

从图像帧指向地图点的箭头表示图像帧的特征点和地图点建立了联系,但地图点到图像帧并没有建立联系,也就是只有mCurrentFrame.mvpMapPoints = vpMapPointMatches;却没有pMP->AddObservation(mpCurrentKeyFrame, idx);

 

当前帧进入Track线程之后,调用TrackReferenceKeyFrame()函数,TrackReferenceKeyFrame()通过与参考关键帧的特征点匹配,将匹配上的特征点所对应的MapPoint作为当前帧的MapPoint。参考关键帧和当前帧不是每一个点都是匹配的,所以参考关键帧的部分MapPoint不是当前帧的MapPoint。

经过了TrackReferenceKeyFrame(),我们得到了图1,当前帧和参考关键帧有一部分MapPoint是相同的。

图解ORBSLAM2流程_第1张图片

                                                                         图1

根据匹配特征点的数量是否超过阈值来判断TrackReferenceKeyFrame()是否成功,若是成功,则在当前帧进行 TrackLocalMap();,不成功会在下一帧进行Relocalization();

TrackLocalMap()的目的是为了建立局部地图。

TrackLocalMap()运行之后,其中的UpdateLocalMap()会将以下步骤得到的关键帧作为局部关键帧

1、所有能观测到当前帧地图点的关键帧(帧3,4,5都能够观测到当前帧地图点a)

2、由1所得到的每个关键帧共视程度最高的10帧(帧2和帧3共视地图点为2,帧1和帧3的共视地图点为1,所以帧2选入,当然这是一种假设,帧2已经是帧3共视程度最高的10帧中排名最低的一帧)

3、由1中得到的每个关键帧的子关键帧和父关键帧(子父关键帧的更新在UpdateConnections()中,该函数出现在初始化以及localMapping中)

同时将局部关键帧所能观察到的所有地图点作为局部地图点

结果如图2所示,用虚线圈住的便是当前帧的局部地图。

 

图解ORBSLAM2流程_第2张图片

                                                                          图2

可是我们现在当前帧的地图点仍旧只有红色的三个地图点,我们需要寻找更多的地图点。接下来就是TrackLocalMap()中的SearchLocalPoints()函数,会为当前帧匹配更多的地图点

SearchLocalPoints()会将在当前帧视野内的地图点投影到当前帧

如图3所示,当前帧的视野范围由两条黑实线所表示,紫色虚线所选中的五个点便是在当前帧的视野范围内。

图解ORBSLAM2流程_第3张图片

                                                                       图3

 

投影之后如图4所示,便是建立了当前帧到新寻找地图点的联系,注意此时是当前帧到地图点的单向联系,而没有建立双向联系。

 

图解ORBSLAM2流程_第4张图片

                                                                        图4

 

经过一番条件的比对,若是当前帧能够作为关键帧,则将关键帧传到LocalMapping线程,此时我们不妨称其为当前关键帧

若是不能够当作关键帧,则需要处理下一帧,当前帧的处理就到此结束。

 

当前帧作为关键帧之后,也就是当前帧成为当前关键帧之后,LocalMapping线程中ProcessNewKeyFrame()会建立地图点和当前关键帧的联系,如图5所示,建立地图点到当前关键帧的箭头

图解ORBSLAM2流程_第5张图片

                                                                    图5

 

 

如果只是根据上面步骤获得MapPoint,我们会发现帧数的增加却不会带来MapPoint的增加

所以需要通过CreateNewMapPoints()三角化恢复一些MapPoint,当前关键帧和其共视程度最高的n帧关键帧三角化恢复一些MapPoint。

如图6所示,当前关键帧和紫色帧以及蓝色帧恢复了绿色的MapPoint。注意使用的是双向箭头。

图解ORBSLAM2流程_第6张图片

                                                                     图6

 

 

以上就是ORBSLAM2的在处理图像帧的流程,以及对应的示意图。其中的细节和原理会在接下来的博客中说明(立个flag)

这里还有一些东西可能需要补充,我想到的时候再进行更改

 

 

你可能感兴趣的:(图解ORBSLAM2)