讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析链接如下(本文内容来自计算机视觉life ORB-SLAM2 课程课件): (01)ORB-SLAM2源码无死角解析-(00)目录_最新无死角讲解:https://blog.csdn.net/weixin_43013761/article/details/123092196 文末正下方中心提供了本人 联系方式, 点击本人照片即可显示 W X → 官方认证 {\color{blue}{文末正下方中心}提供了本人 \color{red} 联系方式,\color{blue}点击本人照片即可显示WX→官方认证} 文末正下方中心提供了本人联系方式,点击本人照片即可显示WX→官方认证
一、前言前面两篇博客对 BoW 的构建,以及:BRIEF描述子转BoW向量进行了讲解。那么他有什么作用呢? 或者说,在什么地方可以得到应用。其实,利用到他的地方很多,比如跟踪线程中得关键帧特征点跟踪SearchByBoW()、局部建图线程中得搜索匹配三角化SearchForTriangulation。本来这个是后面进行讲解得内容,但是为了让大家了解源码是如何通过BoW加速匹配得。这里提前为大家分析这两个案例。这篇博客,就先来看看SearchByBoW()函数
二、源码流程
需要讲解的函数为: src/ORBmatcher.cc 文件中的 ORBmatcher::SearchByBoW(KeyFrame* pKF,Frame &F, vector &vpMapPointMatches)。该函数是为参考帧与普通帧之间的特征点匹配,还有另外一个重载函数,为关键帧与关键帧之间的特征匹配。两个重载函数的原理基本一致的,所以只讲解一个。
首先,需要明白该函数的目的: 输入一张关键帧 pKF,以及一张普通帧 F,然后获得匹配特征点对应的地图点vpMapPointMatches。
( 1 ) : \color{blue}{(1)}: (1): 获取关键帧的地图点(关键帧能够观测到的所有地图点)vpMapPointsKF;以及关键帧的词袋特征向量 vFeatVecKF,其存储多个元素,每个元素包含两个值,第一个值是所属节点id,以及该节点下所有特征点在图像中的索引。
( 2 ) : \color{blue}{(2)}: (2):构建角度差直方图,这个内容在前面的博客中已经进行过讲解 rotHist,主要是去除一些不符合主流方向的特征点,或者说异常点,也就是所谓的外点。
( 3 ) : \color{blue}{(3)}: (3):循环对关键帧 pKF,普通帧 F的特征所属节点,如果两个所属节点 id 相同。遍历该所属节点 pKF 的所有特征点,如果该特征点存在对应的地图点且不是坏点,则与该所属节点普通帧 F 的所有特征点进行匹配,即计算BRIEF描述子之间的汉明距离。
( 4 ) : \color{blue}{(4)}: (4):计算汉明距离的时候,会记录下最优距离以及次优距离,只有满足: ①最优距离小于指定阈值,②最佳匹配比次佳匹配明显要好。则两个条件,才认为是成功匹配。
( 5 ) : \color{blue}{(5)}: (5):成功匹配之后,把关键帧中与之对应的地图点赋值给 vpMapPointMatches。完成所有特征点点匹配之后,再通过角度差直方图,去除不符合主流方向的地图点,也就是设置为 NULL。返回成功匹配的地图点数目。
另外这里额外提及一些细节的东西: SearchByBoW 函数中存在代码如下:
if(f1it->first == f2it->first)
......
else if(f1it->first first)
f1it = vFeatVec1.lower_bound(f2it->first);
else
f2it = vFeatVec2.lower_bound(f1it->first);
因为 vFeatVec1,与 vFeatVec2 都是按照所属节点 id 从小到大排序的。如果 pKF1 中所属节点与 pKF2 中所属节点不匹配,则有两种情况: ①.f1it->first(pKF1所属节点id) 小于 f2it->first(pKF2所属节点id) →那么就把 f1it 的节点 id 增大,赋值成与 f2it 相同的节点,那么下一次循环,他们所属节点 id 就相同了。 ②.f1it->first(pKF1所属节点id) 大于 f2it->first(pKF2所属节点id) →那么就把 f2it 的节点 增大,赋值成与 f1it 相同的节点,那么下一次循环,他们所属节点 id 就相同了。
三、源码注释
/*
* @brief 通过词袋,对关键帧的特征点进行跟踪
* 步骤
* Step 1:分别取出属于同一node的ORB特征点(只有属于同一node,才有可能是匹配点)
* Step 2:遍历KF中属于该node的特征点
* Step 3:遍历F中属于该node的特征点,寻找最佳匹配点
* Step 4:根据阈值 和 角度投票剔除误匹配
* Step 5:根据方向剔除误匹配的点
* @param pKF 关键帧
* @param F 当前普通帧
* @param vpMapPointMatches F中地图点对应的匹配,NULL表示未匹配
* @return 成功匹配的数量
*/
int ORBmatcher::SearchByBoW(KeyFrame* pKF,Frame &F, vector &vpMapPointMatches)
{
// 获取该关键帧的地图点
const vector vpMapPointsKF = pKF->GetMapPointMatches();
// 和普通帧F特征点的索引一致
vpMapPointMatches = vector(F.N,static_cast(NULL));
// 取出关键帧的词袋特征向量
const DBoW2::FeatureVector &vFeatVecKF = pKF->mFeatVec;
int nmatches=0;
// 特征点角度旋转差统计用的直方图
vector rotHist[HISTO_LENGTH];
for(int i=0;ifirst == Fit->first)
{
// second 是该node内存储的feature index
const vector vIndicesKF = KFit->second;
const vector vIndicesF = Fit->second;
// Step 2:遍历KF中属于该node的特征点
for(size_t iKF=0; iKFisBad())
continue;
const cv::Mat &dKF= pKF->mDescriptors.row(realIdxKF); // 取出KF中该特征对应的描述子
int bestDist1=256; // 最好的距离(最小距离)
int bestIdxF =-1 ;
int bestDist2=256; // 次好距离(倒数第二小距离)
// Step 3:遍历F中属于该node的特征点,寻找最佳匹配点
for(size_t iF=0; iF
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?