ORB-SLAM笔记——(3)单目模式的地图初始化

单目SLAM地图初始化的目标是构建初始的三维点云地图。由于不能仅仅从单帧得到深度信息,因此需要从图像序列中选取两帧以上的图像,估计摄像机姿态并重建出初始的三维点云。要注意的是这样构建出的全局地图是在相对尺度下的,因为我们无法像双目模式那样,借助左右目之间的外参便可获得绝对尺度下的位姿变换。

ORB的作者在单目情况下提出了地图的自动初始化,这包括第一点,自动选定两个初始帧,这与PTAM不太一样,PTAM直接选择了初始的连续两帧做处理。这样做太过简单粗暴,毕竟初始化的好坏决定了建图的质量。还有第二点,在恢复这两帧之间的运动时,ORB-MONO根据给出评价函数打分的方式自动选择求解运动的方法。

以上流程图给出了单目ORB的初始化过程,具体实现在Tracking::MonocularInitialization()中。首先若mpInitializer对象尚未初始化,说明该帧是第一帧。先处理这一帧,若当前帧的特征点大于100,我们认为算是满足要求,此时去set mpInitializer否则do nothing至该函数结束,需继续确定第一帧信息。有了第一帧,第二帧图像进来后也先判断找到的特征点是否大于100。若小于100,要将mpInitializer释放,也就是将前面找到的第一帧直接丢弃,然后重新找。当大于100的时候,将当前帧与第一帧做特征点匹配,若匹配的对数小于100我们也认为这两帧不满足要求,释放mpInitializer并重新初始化。匹配数大于100,此时我们完成了第一步,即选定了最开始的两帧。

[1]

         

[2]

有了这两帧,我们的目的便是无论在什么场景下,以及在不同视差下,都能精确地解算出运动。mpInitializer调用Initialize(),这个函数会开两个线程同时计算两帧之间的基本矩阵(F)和单应矩阵(H)。然后,我们分别用两个矩阵,分别把每一帧的特征点投到另一帧计算误差(公式[1])。最后,利用这些误差,我们为F和H恢复运动的精度分别打分并计算(公式[2]),根据选一个去恢复R和t,如果大于所设定的经验值(论文中写的是0.45),我们一般认为这两帧的大部分特征点全在一个平面上,并且两帧的视差较小,此时应选单应矩阵,否则就用基础矩阵F。

//initialize()部分代码
vector<bool> vbMatchesInliersH, vbMatchesInliersF;
float SH, SF;
cv::Mat H, F;

//同时计算H和F,findHomography或fundamental中,他们的得分SH和SF也会计算出来
thread threadH(&Initializer::FindHomography,this,ref(vbMatchesInliersH), ref(SH), ref(H));
thread threadF(&Initializer::FindFundamental,this,ref(vbMatchesInliersF), ref(SF), ref(F));

// Wait until both threads have finished
threadH.join();
threadF.join();

// Compute ratio of scores
float RH = SH/(SH+SF);

// Try to reconstruct from homography or fundamental depending on the ratio (0.40-0.45)
if(RH>0.40)
    return ReconstructH(vbMatchesInliersH,H,mK,R21,t21,vP3D,vbTriangulated,1.0,50);
else //if(pF_HF>0.6)
    return ReconstructF(vbMatchesInliersF,F,mK,R21,t21,vP3D,vbTriangulated,1.0,50);

当上述过程完毕得到运动之后,进行初始化的收尾工作,同时也是该过程的终极目标即创建初始地图。具体实现在Tracking::CreateInitialMapMonocular()中。

选定的两帧作为初始化地图的两帧,理所应当要以关键帧的身份添加到地图里,然后便可以利用他们之间的运动以及匹配好的点对,创建第一批地图点出来。更新KFs的连接由关键帧的成员函数UpdateConnections()完成,主要更新的是与其他关键帧的连接权重,体现在有多少共视点上。此时地图已经建立起来了,调用Optimizer::GlobalBundleAdjustemnt对所有的MapPointsKeyframes联合进行优化。最后如果得到的地图点仍能大于100,我们利用第一帧的中位逆深度去scale基线以及所有的地图点。

(欢迎批评指正,若转发请标明出处)

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页