ORB-SLAM(五)KeyFrame类-最小生成树

KeyFrame中维护了一个map,保存了与当前帧共视的KeyFrame*与权重(共视MapPonits数量)。对关键帧之间关系是用加权有向图来完成的,那么理解其spanning tree生成树的原理就颇有必要了。后端

KeyFrame中比较难理解的是SetBagFlag()函数,真实删除当前关键帧以前,须要处理好父亲和儿子关键帧关系,否则会形成整个关键帧维护的图断裂,或者混乱,不可以为后端提供较好的初值。函数

理解起来就是父亲挂了,儿子须要找新的父亲,在候选父亲里找,当前帧的父亲(mpParent)确定在候选父亲中的;oop

1. 首先将当前帧的父亲,放入候选父亲中spa

sParentCandidates.insert(mpParent);

2. 遍历当前帧的全部儿子,而后遍历儿子A的每一个共视帧,若是其中有候选父亲,则将A的父亲更新为该候选父亲,而且将A放入候选父亲中(由于这时候A已经将整个图联系起来了);若是没有,break。若是遍历一圈下来,发现有的儿子尚未找到新父亲,例如儿子B的共视帧不是候选父亲里的任何一个。这种状况出如今,B和当前帧的父亲不存在共视关系(速度太快,旋转太急,匹配跟丢)。而且B与当前帧的儿子之间也没有共视关系:当前帧不是一个好的关键帧,原本就没有多少儿子;或者B自己是个例外,恩,反正B是个孤家寡人。。。那么直接将B的父亲设置为当前帧的父亲,交给爷爷去管。code

while(!mspChildrens.empty())
{
  bool bContinue = false;

  int max = -1;
  KeyFrame* pC;
  KeyFrame* pP;

  for(set<KeyFrame*>::iterator sit=mspChildrens.begin(), send=mspChildrens.end(); sit!=send; sit++)
  {
    KeyFrame* pKF = *sit;
    if(pKF->isBad())
      continue;

    // Check if a parent candidate is connected to the keyframe
    vector<KeyFrame*> vpConnected = pKF->GetVectorCovisibleKeyFrames();
    for(size_t i=0, iend=vpConnected.size(); i<iend; i++)
    {
      for(set<KeyFrame*>::iterator spcit=sParentCandidates.begin(), spcend=sParentCandidates.end(); spcit!=spcend; spcit++)
      {
      if(vpConnected[i]->mnId == (*spcit)->mnId)
      {
        int w = pKF->GetWeight(vpConnected[i]);
        if(w>max)
        {
          pC = pKF;
          pP = vpConnected[i];
          max = w;
          bContinue = true;
        }
      }
      }
    }
  }
}

if(bContinue)
{
  pC->ChangeParent(pP);
  sParentCandidates.insert(pC);
  mspChildrens.erase(pC);
}
else
  break;
}

if(!mspChildrens.empty())
  for(set<KeyFrame*>::iterator sit=mspChildrens.begin(); sit!=mspChildrens.end(); sit++)
  {
    (*sit)->ChangeParent(mpParent);
  }

 3. 具体删除一个关键帧的步骤是这样的:blog

  1) 初始mbNotErase状态是true,那么调用SetBadFlag后,将mbToBeErased状态置为true,而后return,并无执行SetBadFlag()中后面的代码。ci

  2) 而后调用SetErase(),这时首先要检查mspLoopEdges是不是空的!由于若是当前帧维护了一个回环,删了该关键帧回环就没了。。。一般状况下是空的,那么把mbNotErase置为false,此时再在SetErase()中调用SetBagFlag时,就会真正去执行删除该帧的代码了。it

总结一下就是,首先设置为坏帧,若是该帧不是回环帧,则能够真的删掉;若是该帧是回环帧,怎么都删不掉的。。。class

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息