ORB-SLAM2学习2 KeyFrame.h

1.公有函数:

1 KeyFrame(Frame &F, Map* pMap, KeyFrameDatabase* pKFDB);

构造函数:输入进来一帧,该帧作为关键帧。将该帧传入地图、关键帧的集合。

  2 void SetPose(const cv::Mat &Tcw);
    cv::Mat GetPose();
    cv::Mat GetPoseInverse();
    cv::Mat GetCameraCenter();
    cv::Mat GetStereoCenter();
    cv::Mat GetRotation();
    cv::Mat GetTranslation();

  根据给的量设置公有变量,和获得公有量。

  3  void ComputeBoW();

  计算词袋,mBowVec,mFeatVec。上一篇讲过了,只是注意mFeatVec指定了层数。

 4  void AddConnection(KeyFrame* pKF, const int &weight);

  当前帧与传入的pKF(输入)有共视的时候,增加连接关系。weight(输入)。表示的是当前帧和pKF共同看到了多少个关键点。 这个函数改变的是公共变量:   std::map<KeyFrame*,int> mConnectedKeyFrameWeights;

5 void EraseConnection(KeyFrame* pKF);

  删除当前帧与关键帧pKF的连接关系,也是操作这个公共变量std::map<KeyFrame*,int> mConnectedKeyFrameWeights;完了之后记得跟新下,UpdayeBestCovisible.

6 void UpdateConnections();

主要是跟新,该帧与其他关键帧的连接关系。

  第一步,找出这个关键帧里面的每一个地图点,并且找出其他同样也能看到这个地图点的关键帧们,跟新一下当前帧与其他关键帧的共视权重。直到找完当前帧的所有地图点。我们将结果放到一个容器里面   map<KeyFrame*,int> KFcounter;第一个表示当前帧与哪个关键帧有共视关系,第二个参数表示共视点的个数(权重)。

   第二步:挑选出那些共视权重大于等于15的那些,放入容器vector<pair<int,KeyFrame*> > vPairs; 然后把vPair从大小进行排序。

   第三:更新最小生成树(将权重最大的那帧最为当前帧的父节点)

最后得到的结果:  

1.得到公有变量mConnectedKeyFrameWeights,所有与当前帧有共视关系的关键帧及其权重。

2.得到公共变量:mvpOrderedConnectedKeyFrames :权重大于15的关键帧 按权重排列vector向量。

3.得到公共变量:mvOrderedWeights :权重(大于15)从大到小排列的vector向量。

4.最小生成树的连接关系。(与当前帧有最大权重的最为该帧的父亲,该帧最为孩子)。

7 void UpdateBestCovisibles();

这个改变的是mvpOrderedConnectedKeyFrames,mvOrderedWeights容器里面的值顺序,就是保证这里的值是从大到小排列的。

 8  //得到与该关键帧有共视的关键帧set集合。
    std::set<KeyFrame *> GetConnectedKeyFrames();
    
    //得到与该关键帧有共视(    权重大于15)的关键帧的有序vector集合
    std::vector<KeyFrame* > GetVectorCovisibleKeyFrames();
9   //返回  最好的共视向量集合    有<=N个关键帧
    std::vector<KeyFrame*> GetBestCovisibilityKeyFrames(const int &N);
    //返回的是大于该权重w的 所有共视关键帧
    std::vector<KeyFrame*> GetCovisiblesByWeight(const int &w);
    //得到pKF与当前帧的权重
    int GetWeight(KeyFrame* pKF);
 10 // Spanning tree functions
    void AddChild(KeyFrame* pKF);
    void EraseChild(KeyFrame* pKF);
    void ChangeParent(KeyFrame* pKF);
    //得到最小生成树,该帧的所有孩子。
    std::set<KeyFrame*> GetChilds();
    KeyFrame* GetParent();
    bool hasChild(KeyFrame* pKF);

跟最小生成树有关系,都很简单。

 11 //可能检查到很多回环关键帧
    void AddLoopEdge(KeyFrame* pKF);     
    //返回这些可能是回环的关键帧
    std::set<KeyFrame*> GetLoopEdges(); 

改变的是公共变量spLoopEdges;

12// MapPoint observation functions   都是对vector<MapPoint* > mvpMapPoints做的操作。
    //增加地图点,
    void AddMapPoint(MapPoint* pMP, const size_t &idx);
    void EraseMapPointMatch(const size_t &idx);
    void EraseMapPointMatch(MapPoint* pMP);
    void ReplaceMapPointMatch(const size_t &idx, MapPoint* pMP);
    
    //得到map point不是bad 的mappoint 集合
    std::set<MapPoint*> GetMapPoints();
    std::vector<MapPoint*> GetMapPointMatches();
    
    //返回该关键帧里面,被跟踪的关键点的个数
    int TrackedMapPoints(const int &minObs);
    MapPoint* GetMapPoint(const size_t &idx);

其他的函数也实现也十分简单,这里最后写下一个,很重要的函数。

13 void SetBadFlag();

该函数将该帧变成bad,mbToBeErased变成true,就是代表”删除了“。删除了该帧:

  第一要改变该帧其连接帧的连接关系,删除该帧对地图点的额观测。第二改变最小生成树改变最小生成树的具体实现具体实现看代码。主要思路:

  因为删除了当前帧,所有当前帧下面的孩子们(n个孩子)的父节点都要改变。我们就循环n次,重新为这n个孩子找父节点,父节点出现在与这些孩子节点有最多的共视权重的帧,并且在父节点候选容器(ParentCandidates)中里面的帧。选好了父亲点之后,把这个孩子节点加入剩下的孩子节点的父亲候选节点(sParentCandidates.insert(pC);),删除这个孩子节点(   mspChildrens.erase(pC);  )。

原文地址:https://www.cnblogs.com/panda1/p/7001070.html