6.0ORBSLAM3之几种特征匹配方式总结

0.总结

结合代码看,ORBSLAM3中的特征匹配从来不用整副图像的暴力匹配,一般都使用一些加速方法,综合的看大致分为以下几种:

  1. 基于网格注册信息的特征匹配加速
    涉及到3D-2D匹配,对于将3D地图点投影到图像帧寻找匹配点时一般使用特征点网格注册信息,在3D点投影位置的附近网格区域内寻找匹配点
  2. 基于词袋向量的特征匹配加速
    涉及到2D-2D匹配,特别的关键帧与关键帧,关键帧与普通帧之间的匹配,一般基于词袋向量加速匹配,只对属于同一节点下的特征点遍历寻找匹配
  3. 基于带状搜索的匹配方法
    双目相机左右目之间的匹配,这种情况比较特殊只适用于双目相机,因为双目相机两个目在安装时是基本水平的,所以可以根据左目特征点的所在行可以快速定位到相匹配的右目特征点在哪几行,然后再进行精确搜索。

1.跟踪运动模型中的投影匹配

函数声明:

/**
* @brief 将上一帧跟踪的地图点投影到当前帧,并且搜索匹配点。用于跟踪前一帧
* 步骤
* Step 1 建立旋转直方图,用于检测旋转一致性
* Step 2 计算当前帧和前一帧的平移向量
* Step 3 对于前一帧的每一个地图点,通过相机投影模型,得到投影到当前帧的像素坐标
* Step 4 根据相机的前后前进方向来判断搜索尺度范围
* Step 5 遍历候选匹配点,寻找距离最小的最佳匹配点 
* Step 6 计算匹配点旋转角度差所在的直方图
* Step 7 进行旋转一致检测,剔除不一致的匹配
* @param[in] CurrentFrame          当前帧
* @param[in] LastFrame             上一帧
* @param[in] th                    搜索范围阈值,默认单目为7,双目15
* @param[in] bMono                 是否为单目
* @return int                      成功匹配的数量
*/
int SearchByProjection(Frame &CurrentFrame, const Frame &LastFrame, const float th, const bool bMono);

在跟踪运动模型TrackWithMotionModel过程中使用的是投影匹配,将上一帧LastFrame中的3D地图点根据位姿和内参投影到当前帧图像上寻找匹配关系。

根据特征点的尺度信息确定在当前帧图像上的搜索半径,尺度越大搜索半径就越大,根据搜索半径可以确定该半径范围内所有的网格(在图像帧创建时给每个特征点都分配了网格),将对应尺度的对应网格中的特征点对应id取出,作为候选的匹配特征点

遍历所有候选特征点(根据id信息),计算每个特征点描述子和当前3D地图点描述子的距离,将最小距离对应的特征点作为最佳匹配,再进行旋转一致性检验得到最终的匹配关系

2.跟踪参考关键帧中的词袋向量搜索

函数声明:

/**
* @brief 通过词袋,对关键帧的特征点进行跟踪
* 
* @param[in] pKF               参考关键帧
* @param[in] F                 当前普通帧
* @param[in] vpMapPointMatches F中地图点对应的匹配,NULL表示未匹配
* @return int                  成功匹配的数量
*/
int SearchByBoW(KeyFrame *pKF, Frame &F, std::vector<MapPoint*> &vpMapPointMatches);

在跟踪参考关键帧时,会首先将当前图像中特征点的描述子转换为词袋向量。在转换过程中有一项输出mFeatVec,记录了当前帧中每个特征点在词袋树上对应的节点id,这种属性可以用于加速匹配,即在寻找匹配关系时只对属于同一节点的特征点进行匹配。

关键帧同样也具备一个词袋向量属性mFeatVec,它的基本元素是特征点索引和特征点所在的词袋树节点,这里的特征点索引和关键帧3D地图点的索引是一一对应的,对于KF中每一个node中的特征点根据当前帧词袋向量寻找和他相同node的特征点,然后再通过暴力匹配寻找匹配关系。

这样就将整副图像之间的暴力匹配转换为同一节点中特征点之间的暴力匹配,极大地缩小了匹配范围,进而提高匹配速度。

3.跟踪局部地图中的投影匹配

函数声明:

/**
* @brief 跟踪局部地图,将局部地图中的3D点投影到当前帧寻找匹配关系
* 
* @param F 当前帧
* @param vpMapPoints 局部地图中的Mappoints 
* @param th 和搜索半径相关的阈值
* @param bFarPoints 
* @param thFarPoints 
* @return int 
*/
int SearchByProjection(Frame &F, const std::vector<MapPoint*> &vpMapPoints, const float th=3, const bool bFarPoints = false, const float thFarPoints = 50.0f);

和跟踪运动模型中的投影匹配类似,同样使用3D地图点的描述子和当前帧特征点进行描述子计算来寻找匹配关系,不同的是这里使用的是局部地图中的3D空间点,使用了网格注册信息进行了匹配加速。

4.局部建图线程中通过极线约束快速寻找两个关键帧之间的匹配关系

函数声明:

int SearchForTriangulation(KeyFrame *pKF1, KeyFrame* pKF2,
                                   std::vector<pair<size_t, size_t> > &vMatchedPairs, const bool bOnlyStereo, const bool bCoarse = false);

大致过程是先通过bow词袋向量加快特征匹配的搜索,如果描述子距离小于一定阈值,则通过对极约束校验该匹配是否合理,即通过当前帧特征点在参考帧图像上的特征点,到参考帧极线的距离是否小于一定阈值(理想情况下这个距离是0)

5.局部建图线程中融合地图点中通过特征点的网格注册信息加速匹配

函数声明:

int Fuse(KeyFrame *pKF, const vector<MapPoint *> &vpMapPoints, const float th, const bool bRight);

该函数同样使用了特征匹配加速策略,根据特征点网格注册信息,对于某个Mappoint根据位姿投影到共视关键帧中得到投影点,加速策略就是只在投影点附近的网格中寻找Mappoint的匹配点,缩小了匹配范围。

6.回环检测线程之检测共视区域之几何相似性验证

LoopClosing->NewDetectCommonRegions()->DetectCommonRegionsFromBoW()中通过bow词袋向量搜索寻找当前关键帧候选关键帧之间的匹配。分别取出两个关键帧的bow词袋向量,通过只对属于同一节点的特征点进行匹配加速特征匹配速度。

7.回环检测线程-共视区域检测-几何相似性验证-通过重投影获取更多的匹配

核心思想是将当前关键帧中的3D地图点投影到每个候选关键帧,基于网格注册信息加速特征匹配过程,通过计算地图点描述子和关键帧特征点描述子距离得到匹配关系

int numProjMatches = matcher.SearchByProjection(mpCurrentKF, mScw, vpMapPoints, vpKeyFrames, vpMatchedMP, vpMatchedKF, 8, 1.5);

8.回环检测线程的几何相似性验证

同样的,基于网格加速匹配

/**
* @brief 回环检测线程-检测是否存在共视区域-几何校验函数
* 通过将当前关键帧共视帧中的地图点使用之前得到的相似变换矩阵,投影到候选关键帧上寻找匹配点,如果匹配点数量大于阈值则认为几何验证成功
* @param pKF 当前关键帧共视关键帧(验证组之一)
* @param Scw mScw表示验证组关键帧与候选关键帧之间的相似变换,由当前帧与候选帧之间的相似变换和当前帧与验证组关键帧之间的运动得到
* @param vpPoints 候选关键帧以及共视帧的地图点
* @param vpMatched 输出,匹配结果
* @param th 网格搜索半径
* @param ratioHamming 描述子匹配阈值
* @return int 
*/
int ORBmatcher::SearchByProjection(KeyFrame* pKF, Sophus::Sim3f &Scw, const vector<MapPoint*> &vpPoints,
                                vector<MapPoint*> &vpMatched, int th, float ratioHamming)

9.特殊的匹配:双目相机之间的特征匹配

  1. 为左目每个特征点建立带状区域搜索表,限定搜索区域。
    在右目图像为左目特征点进行匹配搜索的时候,不仅仅是在一条横线上搜索,而是在一条横向搜索带上搜索。简而言之,原本每个特征点的纵坐标为1个像素大小,这里把特征点体积放大,假定纵坐标占好几行

  2. 对左目相机每个特征点,通过描述子在右目带状搜索区域找到匹配点

  3. 通过SAD滑窗得到匹配修正量bestincR
    简单来说就是基于匹配得到的右目图像中特征点的坐标,计算左右目图像相互匹配特征点周围像素块(11×11)的灰度差值,然后移动右目图像中的像素块滑窗,当灰度差最小时会得到一个特征点的偏移量。(有点像直接法)

然后又因为滑窗的步长是1个像素,所以又做了一次抛物线拟合,求抛物线谷底对应的坐标值(极小值即谷底一定在两个较小值中间),最终得到亚像素级别的坐标精度。

详细过程见博客《基于SAD滑窗的双目特征匹配》

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值