ORB-SLAM2之局部地图SearchInNeighbors函数

本文详细解析了SearchInNeighbors函数的工作流程,包括从相邻关键帧获取数据,融合地图点,以及进行反向融合等步骤,旨在提升3D点云的准确性和完整性。

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

SearchInNeighbors函数

数据来源:与当前关键帧共视程度最高的相邻关键帧,以及与邻帧共视程度最高的相邻关键帧;

更新的信息:更新融合后的3D点,并更新共视关系;

Step 1 获取数据

1、获取与当前关键帧共视程度最高的相邻关键帧;

2、获取与相邻关键帧共视程度最高的相邻关键帧,添加到待融合的关键帧向量中。

Step 2 将当前帧的所有地图点与所有的待融合关键帧融合

融合函数matcher.fuse(关键帧,地图点向量)

投影当前帧的MapPoints到相邻关键帧pKFi中,并判断是否有重复的MapPoints。总结一句话:重复的地图点选择被观测次数多的地图点,没有对应地图点的,添加地图点。

  1. 如果MapPoint能匹配关键帧的特征点,并且该点有对应的MapPoint,那么将两个MapPoint合并(选择观测数多的);
  2. 如果MapPoint能匹配关键帧的特征点,并且该点没有对应的MapPoint,那么为该点添加MapPoint

注意这个时候对地图点融合的操作是立即生效的。

(1) 判断地图点是否满足条件

在这里插入图片描述

  • 地图点反投影到像素坐标,判断是否在图像范围内;
  • 地图点到相机中心的距离是否满足金字塔的尺度范围;
  • 地图点与相机中心形成的向量与平均观测方向向量的夹角是否满足可视范围;
(2) 确定搜索范围内所有特征点的ID

根据上述约束得到所有满足条件的特征点的ID。

(3) 遍历得到的特征点vector
  1. 判断特征点的像素位置与地图点反投影的像素位置的距离是否满足基于卡方检验计算的阈值;
  2. 计算特征点的描述子与地图点对应的描述子之间的距离;
  3. 如果特征点对应的地图点存在,取被观测次数多的地图点,否则,将地图点和特征点对应的关键帧匹配。

Step 3 将当前帧与所有的待融合关键帧对应的地图点进行反向融合

  1. 获取所有一级邻接和二级邻接关键帧对应的地图点(确保无重复);
  2. 将当前关键帧与所有地图点进行再次融合。

Step 4 将当前帧与所有的待融合关键帧对应的地图点进行反向融合

对当前关键帧对应的地图点添加属性。

### 多相机系统的重叠区域处理 在Multicam-SLAM中,为了提高轨迹精度,在多个相机间建立并有效利用重叠区域能够显著提升整体性能。具体而言,通过优化算法来同步不同视角下的图像数据,从而确保各相机捕捉到的信息能够无缝对接[^1]。 对于多相机设置中的每一对相邻摄像头,系统会计算它们之间的几何关系,并基于此调整各自坐标系的位置与方向,使得两者的视野部分可以相互补充而不是简单叠加。这种做法不仅有助于扩大感知范围,而且能增强特征匹配的效果,进而改善位姿估计准确性。 当涉及到具体的编程实现时,通常会在初始化阶段完成这些参数配置工作;而在运行期间,则依靠实时校准机制维持良好的协同作业状态。此外,针对可能出现的时间差问题,还需引入时间戳管理策略以保障同步质量。 ### ORB-SLAM2 的闭环检测线程分析 ORB-SLAM2 是一种先进的视觉 SLAM 系统,它实现了单目、双目以及 RGB-D 相机的支持,并具备强大的回环检测能力。其闭环线程主要负责识别环境中的循环路径,并修正累积误差带来的漂移现象。这一过程涉及到了一系列复杂而高效的算法设计: - **关键帧选取**:跟踪线程和局部映射线程共同作用下产生的新地图点会被立即加入最近的关键帧观察列表里。每当本地映射进程结束对一批待处理关键帧的操作之后,便会触发邻近搜索操作,旨在发现那些可能存在于当前节点及其周边已知位置上的重复地标对象[^2]。 - **重复点云融合**:上述提到的 `SearchInNeighbors()` 函数内部调用了专门用于消除冗余观测记录的方法——`ORBmatcher::Fuse()` 。该方法通过对候选集内的每一个潜在配对项执行相似度评估,最终决定保留最有可能代表同一物理实体的那一组测量值作为标准版本存入数据库之中。 - **全局一致性维护**:一旦确认存在闭合回路事件发生,即意味着找到了一条连接起点与终点相同的历史行走路线片段。此时,程序将启动一次全面的地图更新流程,借助于图优化技术重新排列所有受影响顶点的空间布局,以此恢复整个三维场景模型应有的连贯性和稳定性[^4]。 ```cpp // C++ 伪代码展示如何在一个简化版 ORB-SLAM2 中处理闭环检测逻辑 void LoopClosingThread() { while (running_) { KeyFrame* currKF = GetLatestKeyframe(); // 寻找历史关键帧中最接近当前姿态的一个 std::vector<KeyFrame*> matchedKFs = FindMatchedKeyFrames(currKF); if (!matchedKFs.empty()) { MapPointsCorrection(matchedKFs); // 对应点云矫正 GraphOptimization(); // 执行全局图优化 } SleepForNextCycle(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值