ORB-SLAM3 Sim3Solver.cc相关理解与分析
2021SC@SDUSC
一、MapPoints相关知识
1、Tracking、LocalMapping线程与MapPoint的关系
· 对于Tracking线程中的三个Track函数而言,其主要目的在于估计Frame位姿,解算每一帧的地图点MapPoint,并放在各自帧的成员变量mvpMapPoints中。然后,固定解算的地图点,只对估计的帧位姿进行优化,得到较为精确的位姿。其主要作用是将Frame类与MapPoint类关联起来,将2D的特征点转换成3D坐标。这个时候新建的地图点还没有与Map或LocalMap有任何关联。更准确来说,在Tracking的Track()函数中调用了StereoInitialization(),在这个函数中新建了地图点,并将它们与Map进行了关联。而对于三个Track函数,就没有进行关联了。
· 在LocalMapping线程中,通过取出输入帧里所包含的MapPoint进行局部建图,如果满足条件,将地图点放到LocalMapping的成员变量mvpLocalMapPoints中,构建局部地图LocalMap,关联的关键帧放到mvpLocalKeyFrames中。并在LocalMapping完成之后进行一次整体的局部优化,同时优化局部地图点坐标与关联的关键帧位姿。所以,其主要作用是将MapPoint与Map或LocalMap关联起来。
二、代码分析
1.SetRansacParameters函数
void Sim3Solver::SetRansacParameters(double probability, int minInliers, int maxIterations)
{
mRansacProb = probability; // 0.99
mRansacMinInliers = minInliers; // 20
mRansacMaxIts = maxIterations; // 最大迭代次数 300
// 匹配点的数目
N = mvpMapPoints1.size(); // number of correspondences
// 内点标记向量
mvbInliersi.resize(N);
// Adjust Parameters according to number of correspondences
float epsilon = (float)mRansacMinInliers/N;
// Set RANSAC iterations according to probability, epsilon, and max iterations
// 计算迭代次数的理论值,也就是经过这么多次采样,其中至少有一次采样中,三对点都是内点
// epsilon 表示了在这 N 对匹配点中,我随便抽取一对点是内点的概率;
// 为了计算Sim3,我们需要从这N对匹配点中取三对点;那么如果我有放回的从这些点中抽取三对点,取这三对点均为内点的概率是 p0=epsilon^3
// 相应地,如果取三对点中至少存在一对匹配点是外点, 概率为p1=1-p0
// 当我们进行K次采样的时候,其中每一次采样中三对点中都存在至少一对外点的概率就是p2=p1^k
// K次采样中,至少有一次采样中三对点都是内点的概率是p=1-p2
// 候根据 p2=p1^K 我们就可以导出 K 的公式:K=\frac{\log p2}{\log p1}=\frac{\log(1-p)}{\log(1-epsilon^3)}
// 也就是说,我们进行K次采样,其中至少有一次采样中,三对点都是内点; 因此我们就得到了RANSAC迭代次数的理论值
int nIterations;
if(mRansacMinInliers==N)
nIterations=1; // 这种情况的时候最后计算得到的迭代次数的确就是一次
else
nIterations = ceil(log(1-mRansacProb)/log(1-pow(epsilon,3)));
// 外层的max保证RANSAC能够最少迭代一次;
// 内层的min的目的是,如果理论值比给定值要小,那么我们优先选择使用较少的理论值来节省时间(其实也有极大概率得到能够达到的最好结果);
// 如果理论值比给定值要大,那么我们也还是有限选择使用较少的给定值来节省时间
mRansacMaxIts = max(1,min(nIterations,mRansacMaxIts));
// 当前正在进行的迭代次数
mnIterations = 0;
}
2、计算Sim3函数
在分析代码之前,先了解相关概念与计算
·旋转矩阵计算
·平移向量计算
·尺度计算
未完待续