23局部地图跟踪创建局部关键帧与地图点

ORBSLAM2


@[TOC](23局部地图跟踪创建局部关键帧与地图点)

代码

前面几部分是基于关键帧跟踪、重定位跟踪、基于恒速模型跟踪,只用到当前帧或几个关键帧,比较粗糙。而局部地图跟踪比较准确,它的前提是必须知道当前帧的位姿与地图点,让位姿更准确(有点后端的味道)。

void Tracking::UpdateLocalMap()
{
    // This is for visualization
    mpMap->SetReferenceMapPoints(mvpLocalMapPoints);//绘制参考参考地图点,用于显示局部地图点(红色)

    // Update
    UpdateLocalKeyFrames();//更新局部关键帧
    UpdateLocalPoints();//更新局部地图点
}
void Tracking::UpdateLocalKeyFrames()
{
    // Each map point vote for the keyframes in which it has been observed
    map<KeyFrame*,int> keyframeCounter;
    for(int i=0; i<mCurrentFrame.N; i++)//遍历当前特征点数
    {
        if(mCurrentFrame.mvpMapPoints[i])//如果当前帧有地图点
        {
            MapPoint* pMP = mCurrentFrame.mvpMapPoints[i];//取出当前帧的地图点
            if(!pMP->isBad())//如果地图点是好的话
            {
                const map<KeyFrame*,size_t> observations = pMP->GetObservations();//得到当前观测到此地图点的关键帧以及其索引
                for(map<KeyFrame*,size_t>::const_iterator it=observations.begin(), itend=observations.end(); it!=itend; it++)//遍历观测关键帧
                    keyframeCounter[it->first]++;//这边对关键帧进行了投票,也就是keyframeCounter是一个map,里面的first是关键帧,second是一个int,取出it所对应的关键帧(能观测到此地图点的关键帧)存到keyframeCounter中,并使得其value=1,如果新进来的it所对应的关键帧在keypoint中存在,那么其所对应的value进行自增,如果没有就创建这一个map,这个的作用主要是用来表示这个关键帧能看到多少个地图点,也就是表示共视程度
            }
            else
            {
                mCurrentFrame.mvpMapPoints[i]=NULL;
            }
        }
    }

    if(keyframeCounter.empty())//没有观测就返回
        return;

    int max=0;
    KeyFrame* pKFmax= static_cast<KeyFrame*>(NULL);//存贮具有最多观测次数的关键帧

    mvpLocalKeyFrames.clear();//清空局部关键帧
    mvpLocalKeyFrames.reserve(3*keyframeCounter.size());//申请三倍内存

    // All keyframes that observe a map point are included in the local map. Also check which keyframe shares most points
    for(map<KeyFrame*,int>::const_iterator it=keyframeCounter.begin(), itEnd=keyframeCounter.end(); it!=itEnd; it++)//开始遍历局部关键帧
    {
        KeyFrame* pKF = it->first;//取出局部关键帧

        if(pKF->isBad())//如果是bad则进行continue
            continue;

        if(it->second>max)//如果它观测到的地图点大于max
        {
            max=it->second;//就把他的值赋给max
            pKFmax=pKF;//并且将此关键帧赋给pkFmax,表示它是观测次数最多的关键帧
        }

        mvpLocalKeyFrames.push_back(it->first);//然后将此关键帧pushback到mvpLocalKeyFrames,添加到局部关键帧的列表中
        pKF->mnTrackReferenceForFrame = mCurrentFrame.mnId;//表示此关键帧已经是局部关键帧,并且将其ID进行添加,防止重复添加,一级局部关键帧
    }


    // Include also some not-already-included keyframes that are neighbors to already-included keyframes
    for(vector<KeyFrame*>::const_iterator itKF=mvpLocalKeyFrames.begin(), itEndKF=mvpLocalKeyFrames.end(); itKF!=itEndKF; itKF++)//遍历一级局部关键帧
    {
        // Limit the number of keyframes
        if(mvpLocalKeyFrames.size()>80)//如果它的size大于80的话就break
            break;

        KeyFrame* pKF = *itKF;//取出一级局部关键帧

        const vector<KeyFrame*> vNeighs = pKF->GetBestCovisibilityKeyFrames(10);//取出与一级局部关键帧共视的10个关键帧,

        for(vector<KeyFrame*>::const_iterator itNeighKF=vNeighs.begin(), itEndNeighKF=vNeighs.end(); itNeighKF!=itEndNeighKF; itNeighKF++)//然后遍历这10个关键帧
        {
            KeyFrame* pNeighKF = *itNeighKF;//取出这些关键帧
            if(!pNeighKF->isBad())//如果不坏
            {
                if(pNeighKF->mnTrackReferenceForFrame!=mCurrentFrame.mnId)//判断是不是重复添加
                {
                    mvpLocalKeyFrames.push_back(pNeighKF);//就把它放到局部关键帧中
                    pNeighKF->mnTrackReferenceForFrame=mCurrentFrame.mnId;
                    break;
                }
            }
        }

        const set<KeyFrame*> spChilds = pKF->GetChilds();//获取关键帧的子关键帧
        for(set<KeyFrame*>::const_iterator sit=spChilds.begin(), send=spChilds.end(); sit!=send; sit++)//遍历子关键帧
        {
            KeyFrame* pChildKF = *sit;//取出子关键帧
            if(!pChildKF->isBad())
            {
                if(pChildKF->mnTrackReferenceForFrame!=mCurrentFrame.mnId)
                {
                    mvpLocalKeyFrames.push_back(pChildKF);
                    pChildKF->mnTrackReferenceForFrame=mCurrentFrame.mnId;
                    break;
                }
            }
        }

        KeyFrame* pParent = pKF->GetParent();//父关键帧。
        if(pParent)
        {
            if(pParent->mnTrackReferenceForFrame!=mCurrentFrame.mnId)
            {
                mvpLocalKeyFrames.push_back(pParent);
                pParent->mnTrackReferenceForFrame=mCurrentFrame.mnId;
                break;
            }
        }

    }

    if(pKFmax)//更新当前帧的参考关键帧
    {
        mpReferenceKF = pKFmax;
        mCurrentFrame.mpReferenceKF = mpReferenceKF;
    }
}
void Tracking::UpdateLocalPoints()
{
    mvpLocalMapPoints.clear();//清空局部地图点

    for(vector<KeyFrame*>::const_iterator itKF=mvpLocalKeyFrames.begin(), itEndKF=mvpLocalKeyFrames.end(); itKF!=itEndKF; itKF++)//遍历局部关键帧
    {
        KeyFrame* pKF = *itKF;//取出局部关键帧
        const vector<MapPoint*> vpMPs = pKF->GetMapPointMatches();//取出局部关键帧中匹配好的地图点

        for(vector<MapPoint*>::const_iterator itMP=vpMPs.begin(), itEndMP=vpMPs.end(); itMP!=itEndMP; itMP++)//迭代每个地图点
        {
            MapPoint* pMP = *itMP;
            if(!pMP)
                continue;
            if(pMP->mnTrackReferenceForFrame==mCurrentFrame.mnId)//避免重复添加地图点
                continue;
            if(!pMP->isBad())
            {
                mvpLocalMapPoints.push_back(pMP);
                pMP->mnTrackReferenceForFrame=mCurrentFrame.mnId;
            }
        }
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值