ORB-SLAM2代码笔记(三):KeyFrame

KeyFrame

由于KeyFrame中一部分数据会被多个线程访问修改,因此需要在这些成员中加线程锁,保证同一时间只有一个线程有访问权。涉及线程安全的有:

关键帧位姿的设置(lock(mMutexPose));

关键帧间连接关系的设置(lock(mMutexConnections));

关键帧对应地图点的操作(lock(mMutexFeatures)),

  • void KeyFrame::SetPose(const cv::Mat &Tcw_)
    设置当前关键帧的位姿

  • KeyFrame::UpdateConnections()更新图的连接

    • 首先获得该关键帧的所有MapPoint点,统计观测到这些3d点的每个关键与其它所有关键帧之间的共视程度,对每一个找到的关键帧,建立一条边,边的权重是该关键帧与当前关键帧公共3d点的个数。
    for(vector<MapPoint*>::iterator vit=vpMP.begin(), vend=vpMP.end(); vit!=vend; vit++)//遍历3D点
    {
        MapPoint* pMP = *vit;
        if(!pMP)
            continue;
        if(pMP->isBad())
            continue;
        // 对于每一个MapPoint点,observations记录了可以观测到该MapPoint的所有关键帧
        map<KeyFrame*,size_t> observations = pMP->GetObservations();
        for(map<KeyFrame*,size_t>::iterator mit=observations.begin(), mend=observations.end(); mit!=mend; mit++)
        {
            // 除去自身,自己与自己不算共视
            if(mit->first->mnId==mnId)
                continue;
            KFcounter[mit->first]++;
        }
    }
    
    • 权重必须大于一个阈值,如果没有超过该阈值的权重,那么就只保留权重最大的边(与其它关键帧的共视程度比较高)
        // 对于一个和当前关键帧具有共视关系的关键帧
    for(map<KeyFrame*,int>::iterator mit=KFcounter.begin(), mend=KFcounter.end(); mit!=mend; mit++)
    {
        if(mit->second>nmax)
        {
            nmax=mit->second;
            // 找到对应权重最大的关键帧(共视程度最高的关键帧)
            pKFmax=mit->first;
        }
        if(mit->second>=th)
        {
            // 对应权重需要大于阈值,对这些关键帧建立连接
            vPairs.push_back(make_pair(mit->second,mit->first));
            (mit->first)->AddConnection(this,mit->second);
        }
    }
    // 如果没有超过阈值的权重,则对权重最大的关键帧建立连接
    if(vPairs.empty())
    {
        mConnectedKeyFrameWeights
        // 这是对之前th这个阈值可能过高的一个补丁
        vPairs.push_back(make_pair(nmax,pKFmax));
        pKFmax->AddConnection(this,nmax);
    }
    
    • 对这些连接按照权重从大到小进行排序,以方便将来的处理更新完covisibility图之后,如果没有初始化过,则初始化为连接权重最大的边(与其它关键帧共视程度最高的那个关键帧),类似于最大生成树
  • void KeyFrame::UpdateBestCovisibles()按照权重对连接的关键帧进行排序
    这里声明了一个变量vector <pair<int,KeyFrame*> > vPairs
    和mConnectedKeyFrameWeights的区别是吧int放在前面,方便排序

  • set<KeyFrame*> KeyFrame::GetConnectedKeyFrames()得到与该关键帧连接的关键帧,这里直接遍历mConnectedKeyFrameWeights,把关键帧提出来

  • vector<KeyFrame*> KeyFrame::GetVectorCovisibleKeyFrames()
    得到与该关键帧连接的关键帧(已按权值排序)
    直接return mvpOrderedConnectedKeyFrames;这一变量在UpdateBestCovisibles()算好了

  • vector<KeyFrame> KeyFrame::GetBestCovisibilityKeyFrames(const int &N)
    得到与该关键帧连接的前N个关键帧(已按权值排序)
    vector<KeyFrame
    > KeyFrame::GetCovisiblesByWeight(const int &w)
    权重大于等于w的关键帧

  • set<MapPoint*> KeyFrame::GetMapPoints()获取当前关键帧中的所有地图点
    直接遍历mvpMapPoints就好了

  • int KeyFrame::TrackedMapPoints(const int &minObs)关键帧中,大于等于最少观测数目minObs的MapPoints的数量.这些特征点被认为追踪到了

  • 还有添加子关键帧,删除子关键帧,改变当前关键帧的父关键帧,获取当前关键帧的子关键帧和父关键帧等

  • void KeyFrame::SetBadFlag() 删除关键帧

    • 要删除其他KeyFrame和自己的联系,删除地图点和自己的联系。
    • 这个函数中比较复杂的是 给子关键帧选择父关键帧:

如果这个关键帧有自己的孩子关键帧,告诉这些子关键帧,它们的父关键帧不行了,赶紧找新的父关键帧。
1. 遍历每一个子关键帧,让它们更新它们指向的父关键帧
2. 子关键帧遍历每一个与它相连的关键帧(共视关键帧)
3. 如果子节点找到了可以作为其新父关键帧的帧,则更换父节点
4. 如果没找到,直接把父节点的父节点作为自己的父节点

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容