ORB-SLAM3 SearchByBoW 2
以下是ORB-SLAM3中ORBmatcher::SearchByBoW函数的完整代码及详细解读。 完整代码cppint ORBmatcher::SearchByBoW(KeyFrame* pKF, Frame F, vectorMapPoint* vpMapPointMatches) { // 1. 获取关键帧的地图点 const vectorMapPoint* vpMapPointsKF pKF-GetMapPointMatches(); // 2. 初始化当前帧的匹配结果容器全部置空 vpMapPointMatches vectorMapPoint*(F.N, static_castMapPoint*(NULL)); // 3. 获取关键帧的特征向量FeatureVector const DBoW2::FeatureVector vFeatVecKF pKF-mFeatVec; int nmatches 0; // 4. 初始化方向直方图用于旋转一致性检验 vectorint rotHist[HISTO_LENGTH]; for(int i0; iHISTO_LENGTH; i) rotHist[i].reserve(500); // 5. 角度到直方图bin的转换因子 const float factor HISTO_LENGTH / 360.0f; // 6. 同步遍历两个特征向量只比较相同节点ID下的特征点 DBoW2::FeatureVector::const_iterator KFit vFeatVecKF.begin(); DBoW2::FeatureVector::const_iterator Fit F.mFeatVec.begin(); DBoW2::FeatureVector::const_iterator KFend vFeatVecKF.end(); DBoW2::FeatureVector::const_iterator Fend F.mFeatVec.end(); while(KFit ! KFend Fit ! Fend) { // 6.1 只处理属于同一节点的特征点 if(KFit-first Fit-first) { // 获取该节点下两帧的特征点索引列表 const vectorunsigned int vIndicesKF KFit-second; const vectorunsigned int vIndicesF Fit-second; // 6.2 遍历关键帧中该节点的所有特征点 for(size_t iKF0; iKFvIndicesKF.size(); iKF) { const unsigned int realIdxKF vIndicesKF[iKF]; // 获取该特征点对应的地图点 MapPoint* pMP vpMapPointsKF[realIdxKF]; if(!pMP || pMP-isBad()) continue; // 获取关键帧中该特征点的描述子 const cv::Mat dKF pKF-mDescriptors.row(realIdxKF); int bestDist1 256; // 最佳距离最小汉明距离 int bestIdxF -1; // 最佳匹配点在当前帧中的索引 int bestDist2 256; // 次佳距离 // 6.3 遍历当前帧中该节点的所有特征点寻找最佳匹配 for(size_t iF0; iFvIndicesF.size(); iF) { const unsigned int realIdxF vIndicesF[iF]; // 如果该点已经被匹配跳过 // 当前帧中的这个ORB特征点已经有匹配地图点了MapPoint if(vpMapPointMatches[realIdxF]) continue; const cv::Mat dF F.mDescriptors.row(realIdxF); const int dist DescriptorDistance(dKF, dF); // 更新最佳距离和次佳距离 if(dist bestDist1) { bestDist2 bestDist1; bestDist1 dist; bestIdxF realIdxF; } else if(dist bestDist2) { bestDist2 dist; } } // 6.4 双重检验距离阈值 最近邻比率 if(bestDist1 TH_LOW) // 阈值检验 { if(static_castfloat(bestDist1) mfNNratio * static_castfloat(bestDist2)) // 比率检验 { // 接受匹配当前帧的特征点 → 关键帧的地图点 vpMapPointMatches[bestIdxF] pMP; nmatches; // 6.5 计算旋转角度差存入直方图 if(mbCheckOrientation) { const cv::KeyPoint kp pKF-mvKeysUn[realIdxKF]; float rot kp.angle - F.mvKeys[bestIdxF].angle; if(rot 0.0) rot 360.0f; int bin round(rot * factor); if(bin HISTO_LENGTH) bin 0; assert(bin 0 bin HISTO_LENGTH); rotHist[bin].push_back(bestIdxF); } } } } KFit; Fit; } else if(KFit-first Fit-first) { // 对齐迭代器 KFit vFeatVecKF.lower_bound(Fit-first); } else { Fit F.mFeatVec.lower_bound(KFit-first); } } // 7. 旋转一致性检验剔除不符合主流旋转方向的匹配 if(mbCheckOrientation) { int ind1-1, ind2-1, ind3-1; ComputeThreeMaxima(rotHist, HISTO_LENGTH, ind1, ind2, ind3); for(int i0; iHISTO_LENGTH; i) { // 只保留数量最多的三个bin中的匹配 if(i ind1 || i ind2 || i ind3) continue; // 剔除其他bin中的匹配 for(size_t j0, jendrotHist[i].size(); jjend; j) { vpMapPointMatches[rotHist[i][j]] static_castMapPoint*(NULL); nmatches--; } } } return nmatches; } 详细解读 函数作用SearchByBoW利用词袋模型Bag-of-Words加速两帧关键帧与普通帧或两个关键帧之间的特征匹配。它只比较属于同一词汇树节点的特征点避免了全局暴力搜索大幅提升匹配效率。该函数广泛应用于跟踪参考关键帧、重定位和闭环检测等场景。 输入参数参数类型说明pKFKeyFrame*参考关键帧提供地图点FFrame当前帧待匹配的特征点vpMapPointMatchesvectorMapPoint*输出当前帧每个特征点匹配到的地图点 返回值返回成功匹配的数量int。⚙️ 核心原理五步匹配流程步骤1数据准备cppconst vectorMapPoint* vpMapPointsKF pKF-GetMapPointMatches(); vpMapPointMatches vectorMapPoint*(F.N, static_castMapPoint*(NULL)); const DBoW2::FeatureVector vFeatVecKF pKF-mFeatVec;获取关键帧中每个特征点对应的地图点初始化当前帧的匹配结果全部置空获取关键帧的特征向量mFeatVec—— 一个按节点ID索引特征点索引列表的映射表步骤2同步遍历 FeatureVectorcppDBoW2::FeatureVector::const_iterator KFit vFeatVecKF.begin(); DBoW2::FeatureVector::const_iterator Fit F.mFeatVec.begin(); while(KFit ! KFend Fit ! Fend) { if(KFit-first Fit-first) { /* 匹配 */ } else if(KFit-first Fit-first) { KFit vFeatVecKF.lower_bound(Fit-first); } else { Fit F.mFeatVec.lower_bound(KFit-first); } }FeatureVector的本质是std::mapNodeId, vectorunsigned intKey词汇树节点IDNodeIdValue属于该节点的特征点索引列表同步遍历确保只比较两帧中属于同一节点的特征点。这利用了词袋模型的核心思想属于同一节点的特征点在视觉上相似最可能产生正确匹配。步骤3节点内暴力匹配对于关键帧中一个有效特征点有对应地图点在当前帧同一节点的所有特征点中计算汉明距离找出最佳匹配最小距离和次佳匹配第二小距离。cppint bestDist1 256; // 最佳距离 int bestIdxF -1; int bestDist2 256; // 次佳距离 for(size_t iF0; iFvIndicesF.size(); iF) { const int dist DescriptorDistance(dKF, dF); // 更新 bestDist1 和 bestDist2 }步骤4双重检验接受匹配一个候选匹配必须同时满足两个条件检验条件作用距离阈值bestDist1 TH_LOW确保描述子足够相似最近邻比率bestDist1 mfNNratio * bestDist2确保匹配是独特的没有模糊候选mfNNratio默认值为0.6。比率检验能有效剔除因重复纹理导致的误匹配。步骤5方向直方图验证cppfloat rot kp.angle - F.mvKeys[bestIdxF].angle; if(rot 0.0) rot 360.0f; int bin round(rot * factor); rotHist[bin].push_back(bestIdxF);将所有匹配点的主方向角度差统计到30个bin的直方图中。匹配完成后只保留直方图中数量最多的三个bin中的匹配剔除其余匹配。这一步基于的物理约束是两帧图像之间的旋转是全局一致的。如果某个匹配的角度差与主流方向不一致它很可能是误匹配。 关键成员变量变量默认值说明mfNNratio0.6最近邻比率阈值mbCheckOrientationtrue是否进行旋转一致性检验TH_LOW50描述子距离低阈值HISTO_LENGTH30方向直方图的bin数量 应用场景场景调用位置用途跟踪参考关键帧Tracking::TrackReferenceKeyFrame()恒速模型失效时匹配当前帧与参考关键帧重定位Tracking::Relocalization()跟踪丢失后匹配当前帧与候选关键帧闭环检测LoopClosing::DetectLoop()匹配当前关键帧与闭环候选关键帧 总结SearchByBoW通过FeatureVector的同步遍历将匹配范围从全局所有特征点缩小到同一节点内的特征点再通过距离阈值 比率检验 方向一致性三重过滤保证匹配质量。它无需位姿信息即可完成匹配是ORB-SLAM3实现实时跟踪与闭环检测的关键基础函数。

相关新闻

F28377D Modbus RTU移植:硬件时序、寄存器映射与实时性硬核实践

F28377D Modbus RTU移植:硬件时序、寄存器映射与实时性硬核实践

1. 项目概述:为什么“半小时搞定”在嵌入式领域是个危险信号“跨平台移植modbus,从STM32到TMS320F28377D,kimi 2.6半小时搞定”——这个标题在嵌入式工程师朋友圈刷屏时,我正蹲在产线调试一台F28377D驱动的伺服控制器。第一反应不…

2026/7/7 6:39:48 阅读更多 →
BurpSuite乱码全解析:从编码原理到实战解决content-Encoding显示问题

BurpSuite乱码全解析:从编码原理到实战解决content-Encoding显示问题

1. 项目概述:当BurpSuite遇上乱码如果你是一名Web安全测试人员或者开发者,那么BurpSuite这个工具对你来说肯定不陌生。它几乎是渗透测试、接口调试和Web应用分析领域的“瑞士军刀”。但在日常使用中,一个看似简单却极其恼人的问题频繁出现&am…

2026/7/7 6:37:48 阅读更多 →
射频前端调试:阻抗匹配与PCB布局实战指南

射频前端调试:阻抗匹配与PCB布局实战指南

1. 射频前端调试的核心痛点解析在无线通信设备开发中,射频前端模块(RF Front-End)的调试历来是工程师最头疼的环节。我经手过的WiFi模块、4G模块项目中,约70%的后期问题都源于射频部分性能不达标。其中最常见的现象就是&#xff1…

2026/7/7 6:37:48 阅读更多 →

最新新闻

《HarmonyOS技术精讲-ArkGraphics 2D(方舟2D图形服务)》第五篇:色彩与风格——渐变、阴影与滤镜效果

《HarmonyOS技术精讲-ArkGraphics 2D(方舟2D图形服务)》第五篇:色彩与风格——渐变、阴影与滤镜效果

HarmonyOS技术精讲-ArkGraphics 2D(方舟2D图形服务)第五篇:色彩与风格——渐变、阴影与滤镜效果 开篇:别让画面太“素” HarmonyOS NEXT 开发中,画布 API 的渐变、阴影和滤镜能力,很多人只是简单用过。但…

2026/7/7 7:36:02 阅读更多 →
兴庆区口碑好的斜视训练的眼视光中心

兴庆区口碑好的斜视训练的眼视光中心

在兴庆区,寻找口碑好的斜视训练眼视光中心是许多有相关需求人士的目标。其中,宁夏银川市视光学研究中心是值得关注的一家机构。专业背景与实力宁夏银川市视光学研究中心始建于2003年,是宁夏本土深耕视光领域二十余年的非营利性专业视光机构&a…

2026/7/7 7:34:01 阅读更多 →
如何利用Wayback Machine浏览器扩展构建你的互联网时光机

如何利用Wayback Machine浏览器扩展构建你的互联网时光机

如何利用Wayback Machine浏览器扩展构建你的互联网时光机 【免费下载链接】wayback-machine-webextension A web browser extension for Chrome, Firefox, Edge, and Safari 14. 项目地址: https://gitcode.com/gh_mirrors/wa/wayback-machine-webextension 在互联网快速…

2026/7/7 7:30:01 阅读更多 →
YOLOv10模型改进-特定领域应用-第92篇:YOLOv10改进策略【特定领域应用】| YOLOv10在安防监控中的应用

YOLOv10模型改进-特定领域应用-第92篇:YOLOv10改进策略【特定领域应用】| YOLOv10在安防监控中的应用

一、本文介绍 本文记录的是YOLOv10在安防监控领域的应用。安防监控需要实时检测人员、车辆、异常行为等目标,YOLOv10凭借其高效的推理速度和准确的检测能力,成为安防监控领域的首选目标检测算法。 二、安防监控场景分析 2.1 检测目标 安防监控场景需要检测的目标包括: 人…

2026/7/7 7:26:00 阅读更多 →
Aimmy完整指南:如何用AI智能瞄准提升你的游戏体验

Aimmy完整指南:如何用AI智能瞄准提升你的游戏体验

Aimmy完整指南:如何用AI智能瞄准提升你的游戏体验 【免费下载链接】Aimmy Universal Second Eye for Gamers with Impairments (Universal AI Aim Aligner (AI Aimbot) - ONNX/YOLOv8 - C#) 项目地址: https://gitcode.com/gh_mirrors/ai/Aimmy 你是否曾在激…

2026/7/7 7:26:00 阅读更多 →
企业申报省级企业技术中心有哪些条件?企业技术中心申报要求详解

企业申报省级企业技术中心有哪些条件?企业技术中心申报要求详解

江苏省省级企业技术中心申报条件主要分为基本准入条件(一票否决项)、核心量化指标、评分与行业系数要求以及合规与前置条件四个维度。具体申报要求如下:一、基本准入条件1.主体资格:企业在江苏省境内注册,具有独立法人…

2026/7/7 7:26:00 阅读更多 →

日新闻

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

鸿蒙新特性:图片画廊与轮播导航——构建沉浸式图片浏览体验

图片浏览是移动应用中最高频的场景之一。从社交应用的照片流到电商平台的商品图集,从旅游应用的景点相册到摄影作品展示——用户对图片浏览的体验要求不断提高:流畅的切换动画、直观的缩略图导航、便捷的收藏操作、自动播放模式。HarmonyOS NEXT ArkUI 虽…

2026/7/7 0:05:16 阅读更多 →
24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V DC-DC降压芯片PW2312B/PW2815,SOT23-6到SOP8-EP方案对比

24V稳压芯片完整选型指南 PW8600 PW75XX PW2815 PW2312B LDODC/DC全方案 一、24V稳压方案概述 24V直流电源在工业自动化、门禁系统、电梯控制、汽车电子、LED驱动、监控设备等场景中应用极广,是最常见的中压直流母线电压。要将24V母线稳定降压至下游MCU、传感器…

2026/7/7 0:05:16 阅读更多 →
RAG+知识图谱混合检索与Graph RAG核心对比

RAG+知识图谱混合检索与Graph RAG核心对比

做企业RAG落地的团队,往往容易卡在一容易踩坑的选型难题: 当需求单纯靠向量RAG搞不定、单纯靠知识图谱也搞不定,必须同时依赖「文本语义理解 实体关系推理」时,到底是做「向量图谱混合检索」就够了,还是必须上「Grap…

2026/7/7 0:07:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻