ORB-SLAM3特征点随机性问题的解决

即使是在同一数据集的同一张图像上,在不同时刻运行ORB-SLAM3,提取的特征点位置或数量都会存在一定随机性。比如我们要在第0帧上提取10000个特征点,第一次运行时,系统提取了10002个,第二次运行可能就变成了10004个。虽然这种微小的差异不会对系统运行产生影响,但会给调试带来不便。我们希望,不同时刻运行时,特征点的结果都是稳定的,即对于同一图像和配置文件,Frame类的data member std::vector<cv::KeyPoint> mvKeys存储的特征点信息是不变的。

问题出在函数vector<cv::KeyPoint> ORBextractor::DistributeOctTree()中。这个函数将图像视作root node,将每个node分割成4个child node,不断迭代直到node的数量达到要求(比如10000)。之后从每个node中的fast角点里挑选出结果最好的那个,这样就保证了特征点的分布均匀。迭代中会对node按照包含角点的数量进行一次升序排序:

sort(vPrevSizeAndPointerToNode.begin(), vPrevSizeAndPointerToNode.end());

如果某些node包含相同数量的角点,那么每次排序的结果都会出现一定差异。通俗些,大家都有x个角点,按照数量排序,这次你在前,他在后,下次就是他在前,你在后。这种差异就导致了后续分割结果的随机性。解决这个问题也很容易,我们再写一个cmp()函数指定排序方法:

bool cmp( pair<int,ExtractorNode*>& a, pair<int,ExtractorNode*>& b)
{
    return a.first < b.first;
}

修改被调用的sort()函数为:

sort(vPrevSizeAndPointerToNode.begin(), vPrevSizeAndPointerToNode.end(), cmp);

这样就保证了特征点提取结果的稳定,也方便后面的调试。

上一篇:179. 最大数


下一篇:Salesforce学习之路-developer篇(五)Aura组件原理及常用属性