详谈ORB-SLAM2的单目初始化器Initializer

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

单目初始化器Initializer类这个类只用于单目初始化因为这是ORB-SLAM里遗留的一个类也是祖传代码双目和RGBD相机只需要一帧就能初始化因为双目和RGBD相机拍到的点都是有信息的但是单目相机就不一定了单目相机必须至少有两副图像才能初始化对单目初始化器来说有两个帧一个是参考帧另一个是当前帧这是连续的两帧。

文章目录

一、各成员变量/函数

成员变量名中1代表参考帧(reference frame)中特征点编号,2代表当前帧(current frame)中特征点编号
在这里插入图片描述

各成员函数/变量访问控制意义
vectorcv::KeyPoint mvKeys1private参考帧(reference frame)中的特征点
vectorcv::KeyPoint mvKeys2private当前帧(current frame)中的特征点
vector<pair<int,int>> mvMatches12private从参考帧到当前帧的匹配特征点对
vector mvbMatched1private参考帧特征点是否在当前帧存在匹配特征点
cv::Mat mKprivate相机内参
float mSigma, mSigma2private重投影误差阈值及其平方
int mMaxIterationsprivateRANSAC迭代次数
vector<vector<size_t>> mvSetsprivate二维容器N✖8
每一层保存RANSAC计算H和F矩阵所需的八对点

二、初始化函数: Initialize()

在参考帧创建Initializer对象并且把创建参考的帧在当前帧就是参考帧临近的下一帧在这个帧里调用Initialize这个函数就是把当前两个帧之间进行特征点匹配然后计算f矩阵和h矩阵。单目相机初始化有两种方法单应矩阵和基础矩阵。
在这里插入图片描述
首先设置RANSAC算法用到的点对单目相机初始化有两种途径而实际上在初始化成功之前那个矩阵演算出来的结果是准确的所以使用暴力算法把两个矩阵都解算出来对两个矩阵根据冲突点误差计算得分哪个矩阵的冲突点误差较小得分比较高就是用其恢复运动如果恢复的特征点数目足够多视差角足够大就算初始化成功实际上如果恢复100个特征点视差角在比较可靠的情况下认为是恢复成功的。

bool Initializer::Initialize(const Frame &CurrentFrame,
                             const vector<int> &vMatches12,
                             cv::Mat &R21, cv::Mat &t21,
                             vector<cv::Point3f> &vP3D,
                             vector<bool> &vbTriangulated) {

    // 初始化器Initializer对象创建时就已指定mvKeys1,调用本函数只需指定mvKeys2即可
    mvKeys2 = CurrentFrame.mvKeysUn;		// current frame中的特征点
    mvMatches12.reserve(mvKeys2.size());
    mvbMatched1.resize(mvKeys1.size());

    // step1. 将vMatches12拷贝到mvMatches12,mvMatches12只保存匹配上的特征点对
    for (size_t i = 0, iend = vMatches12.size(); i < iend; i++) {
        if (vMatches12[i] >= 0) {
            mvMatches12.push_back(make_pair(i, vMatches12[i]));
            mvbMatched1[i] = true;
        } else
            mvbMatched1[i] = false;
    }

	// step2. 准备RANSAC运算中需要的特征点对
    const int N = mvMatches12.size();
    vector<size_t> vAllIndices;
    for (int i = 0; i < N; i++) {
        vAllIndices.push_back(i);
    }
    mvSets = vector<vector<size_t> >(mMaxIterations, vector<size_t>(8, 0));
    for (int it = 0; it < mMaxIterations; it++) {
    	vector<size_t> vAvailableIndices = vAllIndices;
        for (size_t j = 0; j < 8; j++) {
            int randi = DUtils::Random::RandomInt(0, vAvailableIndices.size() - 1);
            int idx = vAvailableIndices[randi];
            mvSets[it][j] = idx;
            vAvailableIndices[randi] = vAvailableIndices.back();
            vAvailableIndices.pop_back();
        }
    }

	// step3. 计算F矩阵和H矩阵及其置信程度
    vector<bool> vbMatchesInliersH, vbMatchesInliersF;
    float SH, SF;
    cv::Mat H, F;

    thread threadH(&Initializer::FindHomography, this, ref(vbMatchesInliersH), ref(SH), ref(H));
    thread threadF(&Initializer::FindFundamental, this, ref(vbMatchesInliersF), ref(SF), ref(F));
    threadH.join();
    threadF.join();

	// step4. 根据比分计算使用哪个矩阵恢复运动
    float RH = SH / (SH + SF); 
    if (RH > 0.40)
        return ReconstructH(vbMatchesInliersH, H, mK, R21, t21, vP3D, vbTriangulated, 1.0, 50);
    else
        return ReconstructF(vbMatchesInliersF, F, mK, R21, t21, vP3D, vbTriangulated, 1.0, 50);
}

此博客参考ncepu_Chen的《5小时让你假装大概看懂ORB-SLAM2源码》

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6