ORB-SLAM(五)KeyFrame類-最小生成樹


KeyFrame中維護了一個map,保存了與當前幀共視的KeyFrame*與權重(共視MapPonits數量)。對關鍵幀之間關系是用加權有向圖來完成的,那么理解其spanning tree生成樹的原理就很有必要了。

KeyFrame中比較難理解的是SetBagFlag()函數,真實刪除當前關鍵幀之前,需要處理好父親和兒子關鍵幀關系,不然會造成整個關鍵幀維護的圖斷裂,或者混亂,不能夠為后端提供較好的初值。

理解起來就是父親掛了,兒子需要找新的父親,在候選父親里找,當前幀的父親(mpParent)肯定在候選父親中的;

1. 首先將當前幀的父親,放入候選父親中

sParentCandidates.insert(mpParent);

2. 遍歷當前幀的所有兒子,然后遍歷兒子A的每個共視幀,如果其中有候選父親,則將A的父親更新為該候選父親,並且將A放入候選父親中(因為這時候A已經將整個圖聯系起來了);如果沒有,break。如果遍歷一圈下來,發現有的兒子還沒有找到新父親,例如兒子B的共視幀不是候選父親里的任何一個。這種情況出現在,B和當前幀的父親不存在共視關系(速度太快,旋轉太急,匹配跟丟)。並且B與當前幀的兒子之間也沒有共視關系:當前幀不是一個好的關鍵幀,本來就沒有多少兒子;或者B本身是個例外,恩,反正B是個孤家寡人。。。那么直接將B的父親設置為當前幀的父親,交給爺爺去管。

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. 具體刪除一個關鍵幀的步驟是這樣的:

  1) 初始mbNotErase狀態是true,那么調用SetBadFlag后,將mbToBeErased狀態置為true,然后return,並沒有執行SetBadFlag()中后面的代碼。

  2) 然后調用SetErase(),這時首先要檢查mspLoopEdges是否是空的!因為如果當前幀維護了一個回環,刪了該關鍵幀回環就沒了。。。通常情況下是空的,那么把mbNotErase置為false,此時再在SetErase()中調用SetBagFlag時,就會真正去執行刪除該幀的代碼了。

總結一下就是,首先設置為壞幀,如果該幀不是回環幀,則可以真的刪掉;如果該幀是回環幀,怎么都刪不掉的。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM