• 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);  )。

  • 相关阅读:
    android 访问SD卡的方法
    android 用Achartengine 作图
    hello
    IIS 7.0 "确认文件是否存在"功能
    test
    收藏:如何在Web页面上直接打开、编辑、创建Office文档
    JavaScript面向对象技术
    正则表达式30分钟入门教程
    JWT有状态登陆与无状态登陆
    20条JavaScript代码简洁的写法
  • 原文地址:https://www.cnblogs.com/panda1/p/7001070.html
Copyright © 2020-2023  润新知