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

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息