ORB_SLAM2学习笔记(3)之 单目初始化(初始化地图)

ORB_SLAM2学习笔记(3)之 单目初始化(2)

初始化地图

//创建初始地图
void Tracking::CreateInitialMapMonocular()
{
    // Create KeyFrames
    //初始帧与当前帧都为关键帧
    KeyFrame* pKFini = new KeyFrame(mInitialFrame,mpMap,mpKeyFrameDB);
    KeyFrame* pKFcur = new KeyFrame(mCurrentFrame,mpMap,mpKeyFrameDB);

    //生成词袋向量
    pKFini->ComputeBoW();
    pKFcur->ComputeBoW();

    // Insert KFs in the map
    //把关键帧导入地图
    mpMap->AddKeyFrame(pKFini);
    mpMap->AddKeyFrame(pKFcur);

    // Create MapPoints and asscoiate to keyframes
    //遍历所有匹配点
    for(size_t i=0; i<mvIniMatches.size();i++)
    {
        //没有匹配的跳过 开始设置的 -1
        if(mvIniMatches[i]<0)
            continue;

        //Create MapPoint.
        //创建空间点:把三角化之后的3D点转化为构建地图的地图点
        cv::Mat worldPos(mvIniP3D[i]);
        //创建地图点 : 空间点, 当前帧, 地图
        MapPoint* pMP = new MapPoint(worldPos,pKFcur,mpMap);
        // 为该MapPoint添加属性:
        // a.观测到该MapPoint的关键帧
        // b.该MapPoint的描述子
        // c.该MapPoint的平均观测方向和深度范围
        //在初始帧与当前帧中加入空间点
        pKFini->AddMapPoint(pMP,i);
        pKFcur->AddMapPoint(pMP,mvIniMatches[i]);
        //加入可以观测到该空间点的 关键帧
        pMP->AddObservation(pKFini,i);
        pMP->AddObservation(pKFcur,mvIniMatches[i]);
        //计算能看见空间点关键帧的区分度最高的描述子
        pMP->ComputeDistinctiveDescriptors();
        //更新该MapPoint平均观测方向以及观测距离的范围
        pMP->UpdateNormalAndDepth();

        //Fill Current Frame structure
        //mvIniMatches下标i表示在初始化参考帧中的特征点的序号
        //将加入好地图点以及描述子深度等信息的地图 赋值 在当前帧的地图点上
        mCurrentFrame.mvpMapPoints[mvIniMatches[i]] = pMP;
        //外点不用管
        mCurrentFrame.mvbOutlier[mvIniMatches[i]] = false;

        //Add to Map
        //把转化好的地图点放地图上
        mpMap->AddMapPoint(pMP);
    }

    // Update Connections
    //更新关键帧间的连接关系
    //在关键帧与空间点之间建立联系,也就是建立一个边,每条边都有权重,也就是关键帧看到公共点的个数
    pKFini->UpdateConnections();
    pKFcur->UpdateConnections();

    // Bundle Adjustment
    cout << "New Map created with " << mpMap->MapPointsInMap() << " points" << endl;
    //后端进行局部优化
    Optimizer::GlobalBundleAdjustemnt(mpMap,20);

    // Set median depth to 1
    //得到初始帧所有特征点深度的中值
    float medianDepth = pKFini->ComputeSceneMedianDepth(2);
    //逆深度
    float invMedianDepth = 1.0f/medianDepth;
    //如果平均深度小于0或者初始化的地图点小于100 则重新初始化
    if(medianDepth<0 || pKFcur->TrackedMapPoints(1)<100)
    {
        cout << "Wrong initialization, reseting..." << endl;
        Reset();
        return;
    }
    //
    // Scale initial baseline
    //得到世界到相机的T
    cv::Mat Tc2w = pKFcur->GetPose();
    //得到空间坐标/中值
    //Tc2w.col(3).rowRange(0,3) 得到数组第4列的前3个值
    Tc2w.col(3).rowRange(0,3) = Tc2w.col(3).rowRange(0,3)*invMedianDepth;
    //放入当前帧位姿中
    pKFcur->SetPose(Tc2w);

    // Scale points
    //提取空间点,也对空间点进行和上面相同的尺度变换
    //提取已经匹配的空间点
    vector<MapPoint*> vpAllMapPoints = pKFini->GetMapPointMatches();
    //遍历所有空间点
    for(size_t iMP=0; iMP<vpAllMapPoints.size(); iMP++)
    {
        //如果存在则进行尺度变换(有的讲解说是归一化,但是源码写的invMedianDepth为所有深度的中位数)
        if(vpAllMapPoints[iMP])
        {
            MapPoint* pMP = vpAllMapPoints[iMP];
            pMP->SetWorldPos(pMP->GetWorldPos()*invMedianDepth);
        }
    }
    //在地图中插入关键帧
    mpLocalMapper->InsertKeyFrame(pKFini);
    mpLocalMapper->InsertKeyFrame(pKFcur);
    //当前帧建立位姿,索引,并把地图上当前帧赋值给上一帧
    mCurrentFrame.SetPose(pKFcur->GetPose());
    mnLastKeyFrameId=mCurrentFrame.mnId;
    mpLastKeyFrame = pKFcur;
    //当前帧和初始帧放入关键帧,存储地图空间点,把当前帧设为参考帧
    mvpLocalKeyFrames.push_back(pKFcur);
    mvpLocalKeyFrames.push_back(pKFini);
    mvpLocalMapPoints=mpMap->GetAllMapPoints();
    mpReferenceKF = pKFcur;
    mCurrentFrame.mpReferenceKF = pKFcur;
    //当前帧给上一帧
    mLastFrame = Frame(mCurrentFrame);
    //当前帧上的空间点成为参考点
    mpMap->SetReferenceMapPoints(mvpLocalMapPoints);
    //得到当前帧相机位姿
    mpMapDrawer->SetCurrentCameraPose(pKFcur->GetPose());
    //将初始帧放入地图
    mpMap->mvpKeyFrameOrigins.push_back(pKFini);

    mState=OK;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ORB_SLAM2单目的关键帧添加条件有四个判断。首先,根据当前帧的ID与上一个关键帧的ID的差值是否大于最大帧数来判断是否需要添加关键帧。其次,根据当前帧的ID与上一个关键帧的ID的差值是否大于最小帧数,并且局部地图更新空闲时才能添加关键帧。第三,对于非单目摄像头的情况下,如果匹配的内点数小于参考帧匹配内点数的25%或者需要插入临近帧,则可以添加关键帧。第四,如果当前帧的内点匹配数与参考帧的匹配内点数的比值大于阈值thRefRatio,并且当前帧的内点匹配数大于15,也可以添加关键帧。只有满足以上四个条件之一的情况下,才会执行添加关键帧的操作。 通过对ORB_SLAM2进行改进,关键帧的数量大大增加。例如,在使用相同的视频测试下,关键帧的数量从原来的355个增加到了698个。 然而,如果将ORB_SLAM2与Map2DFusion结合使用来进行无人机航拍视频建图,可能会发现效果不如Map2DFusion官方的效果好。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [ORB_SLAM2的单目SLAM提高关键帧的个数](https://blog.csdn.net/Jeff_zjf/article/details/117257051)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值