ORB-SLAM2的ORBMATCHER代码阅读

本文详细介绍了ORB-SLAM2系统中ORBMATCHER模块的工作原理及优化技巧,包括快速描述符距离计算、搜索范围优化等,并对关键函数如DescriptorDistance、CheckDistEpipolarLine进行了深入剖析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先给出泡泡机器人的ORB-SLAM2的源码详解链接:【泡泡机器人公开课】第三十六课:ORB-SLAM2源码详解 by 吴博

这里主要介绍ORB MATCHER模块,ORBSLAM2对ORB MATCHER做了许多有意思的优化,比如加速的描述子距离计算,搜索范围的优化等等,这里简单介绍他的几个函数

DescriptorDistance函数

Counting bits set, in parallel
这里摘一部分过来说明:

unsigned int v; // count bits set in this (32-bit value)
unsigned int c; // store the total here
static const int S[] = {1, 2, 4, 8, 16}; // Magic Binary Numbers
static const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F,
0x00FF00FF, 0x0000FFFF};
c = v - ((v >> 1) & B[0]);
c = ((c >> S[1]) & B[1]) + (c & B[1]);
c = ((c >> S[2]) + c) & B[2];
c = ((c >> S[3]) + c) & B[3];
c = ((c >> S[4]) + c) & B[4];
The B array, expressed as binary, is:
B[0] = 0x55555555 = 01010101 01010101 01010101 01010101
B[1] = 0x33333333 = 00110011 00110011 00110011 00110011
B[2] = 0x0F0F0F0F = 00001111 00001111 00001111 00001111
B[3] = 0x00FF00FF = 00000000 11111111 00000000 11111111
B[4] = 0x0000FFFF = 00000000 00000000 11111111 11111111
We can adjust the method for larger integer sizes by continuing with the patterns for the Binary Magic Numbers, B and S. If there are k bits, then we need the arrays S and B to be ceil(lg(k)) elements long, and we must compute the same number of expressions for c as S or B are long. For a 32-bit v, 16 operations are used.
The best method for counting bits in a 32-bit integer v is the following:
v = v - ((v >> 1) & 0x55555555); // reuse input as temporary
v = (v & 0x33333333) + ((v >> 2) & 0x33333333); // temp
c = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24; // count
The best bit counting method takes only 12 operations, which is the same as the lookup-table method, but avoids the memory and potential cache misses of a table. It is a hybrid between the purely parallel method above and the earlier methods using multiplies (in the section on counting bits with 64-bit instructions), though it doesn’t use 64-bit instructions. The counts of bits set in the bytes is done in parallel, and the sum total of the bits set in the bytes is computed by multiplying by 0x1010101 and shifting right 24 bits.

CheckDistEpipolarLine函数

已知基础矩阵F,两幅图像中的点 x x ,根据关系

xFx=0

从而定义出对应的epipolar line直线: l=xF ,和另外一幅图像中的点到该直线的距离 d <script type="math/tex" id="MathJax-Element-5">d</script> 可以作为误差,因此有CheckDistEpipolarLine函数,判断两个点的对应关系是否满足机和约束关系

    // Epipolar line in second image l = x1'F12 = [a b c]
    const float a = kp1.pt.x*F12.at<float>(0,0)+kp1.pt.y*F12.at<float>(1,0)+F12.at<float>(2,0);
    const float b = kp1.pt.x*F12.at<float>(0,1)+kp1.pt.y*F12.at<float>(1,1)+F12.at<float>(2,1);
    const float c = kp1.pt.x*F12.at<float>(0,2)+kp1.pt.y*F12.at<float>(1,2)+F12.at<float>(2,2);
    const float num = a*kp2.pt.x+b*kp2.pt.y+c;
    const float den = a*a+b*b;
    if(den==0)return false;
    //计算kp2点到直线的l = x1'F12距离
    const float dsqr = num*num/den;
    //返回距离误差是否在允许范围内
    return dsqr<3.84*pKF2->mvLevelSigma2[kp2.octave];

整体采用特征点匹配的方式,先进性搜索范围缩小,在逐个匹配,并进行旋转一致性检测。此外还要求最优匹配要比次优匹配好一定程度才算匹配成功。
在其余的函数介绍如下:

SearchByProjection和SearchBySim3函数

投影
具体流程如下:

Created with Raphaël 2.1.0 初始化相机内参和外参 确认MapPoint有效? 反投影3D点 确定在图像中搜索范围 求与搜索范围中descriptor距离最近的点 MapPoint队列队尾? 结束 yes no yes no

SearchByBoW函数

BOW
主要流程和SearchByProjection类似,主要是匹配变换成为BOW的特征搜索与匹配

SearchForTriangulation函数

三角化
主要流程和SearchByProjection类似,搜索范围为整张图的点,主要是加了CheckDistEpipolarLine函数,用来验证最近的匹配点是否合格

Fuse函数

融合
除了上面函数的作用,主要可以更新匹配的MapPoint,获取更优的匹配
具体流程如下:

Created with Raphaël 2.1.0 初始化相机内参和外参,获取待处理MapPoints 取出MapPoint 确认MapPoint有效? 反投影3D点 投影点满足约束? 确定在图像中搜索范围 求与搜索范围中descriptor距离最近的点 已有3D MapPoint? 保留可被观测到帧数多的MapPoint 队列队尾? 结束 将该MapPoint和最优匹配二维点绑定 yes no yes no yes no yes no
<think>好的,我现在需要帮助用户查找ORBSLAM3中ORBmatcher相关的代码实现或使用教程。首先,我应该回忆一下ORBSLAM3的结构,了解ORBmatcher在其中的作用。ORBmatcher主要用于特征点的匹配,这在SLAM系统中非常关键,比如在跟踪、地图构建和回环检测等模块中都会用到。 接下来,我需要确定用户的需求。用户可能是在开发或研究ORBSLAM3时遇到了特征匹配的问题,想要了解具体的实现细节或如何正确使用这部分代码。用户提到了“代码实现”和“使用教程”,所以需要同时提供代码位置和实际应用场景。 根据提供的引用内容,引用[2]提到了ORBextractor.cc,这可能与ORB特征的提取有关,而ORBmatcher可能在不同的文件中。不过,ORBmatcher通常是一个单独的类,可能在ORBmatcher.cc/.h中。我需要确认ORBSLAM3的代码结构,通常这些匹配函数会放在src目录下的ORBmatcher.cpp文件中,比如SearchByProjection、SearchForTriangulation等方法。 然后,用户可能需要了解如何调用这些匹配方法。比如在跟踪线程中,如何利用ORBmatcher进行特征匹配,或者在建图时如何生成新的地图点。这时,可以参考引用[3]中的Initializer::ReconstructF函数,其中可能调用了ORBmatcher的方法来进行特征匹配和三角化。 另外,引用[5]提到了MapPointCulling函数,这可能涉及到地图点的筛选标准,这也可能与ORBmatcher的匹配结果有关。比如,在创建新地图点后,需要通过匹配验证其可靠性,不符合条件的会被剔除。 关于使用教程,ORBSLAM3的官方文档可能不够详细,所以可能需要参考一些社区资源,比如优快云博客或GitHub上的示例项目。比如引用[1]中的优快云博客和GitHub链接可能包含相关的实现分析或教程。此外,逆向索引和正向索引的应用(引用[4])可能与特征匹配中的快速检索有关,比如在回环检测中使用词袋模型进行特征匹配时,ORBmatcher可能会与这些索引结构交互。 现在需要将以上信息整合成一个清晰的回答,分点说明ORBmatcher的功能、代码位置、核心函数、使用场景以及相关资源。同时,生成相关问题,帮助用户进一步探索,比如性能优化、参数调整、不同传感器的影响等。 需要确保回答符合用户的要求,结构清晰,引用正确,并且使用中文。同时,按照系统级指令,数学公式使用正确的格式,但在这个问题中可能涉及较少数学内容,主要关注代码和算法流程。最后,生成的相关问题要围绕ORBmatcher的实现和应用展开,帮助用户深入理解。</think>### ORBSLAM3 ORBmatcher 代码实现与使用解析 #### 一、核心功能定位 ORBmatcherORBSLAM3 中实现特征匹配的核心模块,主要负责以下任务: 1. **帧间匹配**:相邻帧的特征点跟踪(Tracking线程) 2. **地图点匹配**:地图点与关键帧的投影匹配(LocalMapping线程) 3. **回环检测验证**:候选关键帧的几何验证(LoopClosing线程) 代码文件位于:`src/ORBmatcher.cc` 和 `include/ORBmatcher.h`[^2][^5] #### 二、关键函数实现解析 ```cpp // 基于投影的匹配(Tracking线程核心方法) int ORBmatcher::SearchByProjection(Frame &F, const vector<MapPoint*> &vpMapPoints, float th) { // 通过地图点在当前帧的投影位置搜索匹配 // 使用极线约束和描述子距离筛选候选点 // 返回成功匹配数量 } ``` ```cpp // 三角化新地图点的匹配(LocalMapping线程) int ORBmatcher::SearchForTriangulation(KeyFrame *pKF1, KeyFrame *pKF2, vector<pair<size_t, size_t> > &vMatchedPairs) { // 使用词袋加速匹配 // 计算特征点方向一致性 // 应用对极几何约束 } ``` #### 三、典型使用场景 1. **跟踪线程初始化**: - 调用 `SearchByProjection()` 实现运动模型预测匹配 - 参考 `Tracking::TrackWithMotionModel()` 实现[^3] 2. **地图点创建**: ```cpp void LocalMapping::CreateNewMapPoints() { // 使用SearchForTriangulation寻找匹配对 // 三角化成功后执行MapPointCulling质量筛选 } ``` 3. **回环检测验证**: - 在 `LoopClosing::DetectLoop()` 中通过词袋匹配候选帧 - 结合逆向索引加速匹配过程[^4] #### 四、参数调优要点 1. **阈值参数**(位于 `ORBmatcher.h`): ```cpp #define TH_HIGH 100 // 描述子距离阈值 #define TH_LOW 50 // 低质量匹配阈值 static const float HISTO_LENGTH = 30; // 方向直方图分箱数 ``` 2. **传感器适配**: - RGB-D模式会跳过部分几何验证步骤 - 单目模式需要严格的对极约束检查 #### 五、学习资源推荐 1. 代码精读:`ORBmatcher.cc` 中的 `SearchByBoW()` 实现词袋匹配 2. 实践教程:参考优快云系列文章《ORBSLAM3源码解析》[^1] 3. 扩展应用:GitHub上的RGBD-Inertial实现案例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值