首页 > 其他分享 >ORB-SLAM2 ----- LocalMapping::ComputeF12和ORBmatcher::CheckDistEpipolarLine

ORB-SLAM2 ----- LocalMapping::ComputeF12和ORBmatcher::CheckDistEpipolarLine

时间:2024-11-30 19:57:46浏览次数:8  
标签:const 函数 ORBmatcher ComputeF12 矩阵 SLAM2 F12 cv Mat

文章目录

一、函数意义

这两个函数在LocalMapping::CreateNewMapPoints()被调用,之所以单独拿出来讲,是因为这两个函都是计算的函数,而且这里是可以用来优化ORB-SLAM2代码的部分,我们完全可以在这部分不用词袋来匹配,直接使用对极约束来进行匹配,匹配效果更好。

二、LocalMapping::ComputeF12()

1.函数讲解

本函数是计算F12矩阵的函数,这个矩阵描述的是从图像1到图像2的变换矩阵。原理是,获取图像1和图像2的旋转矩阵和平移矩阵,然后计算由图2坐标系到图1坐标系的旋转平移计算,这里比较难理解,因为代码直接给出了计算公式,没有给出推到过程,这里我将自己的推到过程放在下图。后续的计算中考虑到t12为31的向量,不好和旋转矩阵以及内参相乘,将其改造为33的矩阵t12x(构造情况见下图),最终的对极约束加入了相机的内参(最后一图的公式)。经三个图的讲解,大家应该能看懂代码为什么是这样的了。

请添加图片描述

2.函数代码

// 计算两个关键帧之间的基准矩阵
cv::Mat LocalMapping::ComputeF12(KeyFrame *&pKF1, KeyFrame *&pKF2)
{
    // 获取第一个关键帧的旋转矩阵和平移向量
    cv::Mat R1w = pKF1->GetRotation();
    cv::Mat t1w = pKF1->GetTranslation();

    // 获取第二个关键帧的旋转矩阵和平移向量
    cv::Mat R2w = pKF2->GetRotation();
    cv::Mat t2w = pKF2->GetTranslation();
    
    // 获取从相机2坐标系到相机1坐标系的旋转矩阵
    cv::Mat R12 = R1w*R2w.t();
    // 相机2坐标系到相机1坐标系的平移向量
    cv::Mat t12 = -R1w*R2w.t()*t2w+t1w;

    // 获取t12的反对称矩阵
    cv::Mat t12x = SkewSymmetricMatrix(t12);
    
    // 获取第一帧相机内参K1和第二帧内参K2
    const cv::Mat &K1 = pKF1->mK;
    const cv::Mat &K2 = pKF2->mK;

    // 返回两个关键帧之间的基础矩阵 F
    return K1.t().inv()*t12x*R12*K2.inv();
}

三、ORBmatcher::CheckDistEpipolarLine()

1.函数讲解

这个函数是用来判断匹配了的点是否符合对极约束的,是一种剔除误匹配点的判断条件,这里构造了一条直线,根据F12讲图2的点转换到图一中,按照理论来说,图一中点的应该在这条直线上(要满足约束),但实际情况是有噪声干扰的,几乎不可能那么准确的落在直线上,这时为了保证误差不太大,计算图1中匹配的点到这个直线的垂直距离,只要他在一定区域内就说明没有误匹配,只是噪声引起的误差,如果超出范围,我们认为是出现了误匹配。这个函数的原理不太难理解,相信大家看了我的讲解后对着代码可以看懂。这个函数最重要的点是,完全可以不用词袋匹配,直接使用对极约束匹配,每个点只找在对极约束内的点进行匹配,然后用直方图的方法来筛选误匹配的点,在修改代码后发现匹配的效果更好了。
请添加图片描述

2.函数代码

// 实现了一个用于检测两个特征点(关键点)是否满足对极几何约束的函数 CheckDistEpipolarLine
bool ORBmatcher::CheckDistEpipolarLine(const cv::KeyPoint &kp1,const cv::KeyPoint &kp2,const cv::Mat &F12,const KeyFrame* pKF2)
{
    // 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;

    const float dsqr = num*num/den;

    return dsqr<3.84*pKF2->mvLevelSigma2[kp2.octave];
}

四、总结

这两个函数在ORB-SLAM2中看起来不那么重要,只是一个判断条件,但是思想非常的好,为我们提供了一种新的匹配思路,这也是我在学中发现的可以优化的点之一。我认为学习看源码不应该只看别人怎么做的,还需要加入自己的思考,在学习源码的过程中优化源码,在学玩后可以讲代码进行改进。对这部分还有问题或者尤其问题都欢迎交流。

标签:const,函数,ORBmatcher,ComputeF12,矩阵,SLAM2,F12,cv,Mat
From: https://blog.csdn.net/uzi_ccc/article/details/144153289

相关文章

  • ORB-SLAM2源码学习:MapPoint.cc:MapPoint::ComputeDistinctiveDescriptors()计算地图点
    前言地图点在投影匹配时只能对应一个特征描述子,选择具有代表性的描述子是必要的。1.函数声明/*由于一个地图点会被许多相机观测到,因此在插入关键帧后,需要判断是否更新代表当前点的描述子先获得当前点的所有描述子,然后计算描述子之间的两两距离,最好的描述子与其他描述子......
  • ORB-SLAM2源码学习:LocalMapping.cc: LocalMapping::MapPointCulling剔除不合格的地图
    前言新增地图点需要经过比较严苛的筛选才能留下,只有这样才能提高定位和建图的准确性、控制地图建图规模、降低计算量。新增地图点主要来自a.双目相机和RGB-D相机模式下的跟踪线程产生的地图点b.局部建图线程中关键帧之间生成的新的地图点。 函数声明voidLocalMapping::M......
  • ORB-SLAM2 ---- LocalMapping::MapPointCulling()和LocalMapping::CreateNewMapPoints
    文章目录一、函数意义二、LocalMapping::MapPointCulling()1.函数讲解2.函数代码三、LocalMapping::CreateNewMapPoints()1.函数讲解2.函数代码四、总结一、函数意义这两个函数是局部见图的核心函数之二,作用是删除不好的地图点,为创造新的地图点。学习局部建图......
  • ORB-SLAM2源码学习:ORBmatcher.cc:ORBmatcher::SearchByProjection通过地图点投影进行特
    前言在ORB-SALM2中,使用最多的匹配方式就是投影匹配的方式SearchByProjection(),根据参数列表的不同可以有不同的函数重载。1.原理:1.投影地图点的来源:1.恒速模型追踪时,地图点来自前一个普通的帧。2.局部地图跟踪时,地图点来自所有的局部地图点。3.重定位时,地图点来自所有的候......
  • ORB-SLAM2 ---- ORBextractor::ComputeKeyPointsOctTree
    文章目录一、函数作用二、源码及注释三、函数的讲解1.遍历金字塔的每一层,将其分成30*30的网格单元,并给每一层添加图像边界2.遍历每个单元格,提取特征点3.调用DistributeOctTree()函数分配特征点4.计算所有保留下来的特征点的方向信息一、函数作用ORB-SLAM2----......
  • ORB-SLAM2源码学习:ORBextractor.cc 逻辑梳理
    前言 温馨提示:请在看过源代码的情况下看此文章学习效果更好。ORBextractor.cc这个源文件定义函数众多,要是按照源码的顺序进行学习会抓不住重点,下面是我梳理的四个核心函数。一、主入口函数:operator()说明:主入口函数直接调用了ComputePyramid()、ComputeKeyPointsOctTree()、......
  • Ubuntu20.04 部署 ORB SLAM2 并运行
    安装基础库sudoaptupdatesudoaptinstallcmakegccg++gitsudoaptinstallpkg-config创建源码目录在home目录下新建repos文件夹用于存放源码。cd~mkdirrepos安装eigen33.2.10安装eigen3.2.10版本。cd~/reposgitclonehttps://gitlab.com/libeige......
  • ORB_SLAM2中的Sim3优化
     https://www.guyuehome.com/356791.单目尺度漂移单目SLAM的尺度漂移,简单来说就是单目获得的单张图片无法知道拍摄物体到相机的距离,必须通过对极几何求的两张图片的位姿,然后三角化出来尺度信息。而这些都依赖的是两帧图像之间的逆深度求解。任选两张图(设为第0帧和第1帧),先提......
  • 使用ORBSLAM2进行kineticV2稠密建图,实时转octomap建图以及导航
    决定总结最近一个月的工作,这个月在orbslam2的基础上,使用kineticV2完成了稠密点云地图的重建,实现了点云的回环,并使用octomap转换成实时的八叉树地图,导航部分已经有了思路,打算下个月所一个基于octomap的航迹生成能用在视觉的导航上。一、传感器和依赖包安装PC性能:Dellxps13内存16GB......
  • ORBSLAM2编译出现的问题
    ORBSLAM也编译了好多次了,因为后来出现别的算法使用的opencv的版本不同,总会出现问题。因此记录一下。首先一定要注意OpenCV的版本,我这里使用的是3.4.16的版本,然后要和Cmake......