在Sim3Solver.cc文件中的第153行SetRansacParameters()函数
/**
* @brief 设置进行RANSAC时的参数
*
* @param[in] probability 当前这些匹配点的置信度,也就是一次采样恰好都是内点的概率
* @param[in] minInliers 完成RANSAC所需要的最少内点个数
* @param[in] maxIterations 设定的最大迭代次数
*/
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;
}