ORB_SLAM2修(Ru)仙(Keng)之路(一):重定位候选关键帧选取函数注释

来源:互联网 发布:gta5女性捏脸数据可爱 编辑:程序博客网 时间:2024/04/30 15:00

自从入了ORB_SLAM的坑以来,深感,在室外使用VO导航的艰辛,ORB_SLAM代码前后看了有一个月了,现在逐渐把一些函数的代码注释记录在这里,希望能给后面入坑的同志们些借鉴吧,当然自己也还有很多不明白的地方,所以,如果注释有错的,还请指出。

代码块

/** * 函数功能:从关键帧库中找出与当前帧匹配得最好的候选关键帧序列 * 函数输入:当前帧 * 函数输出:关键帧库中与当前帧匹配较好的候选关键帧序列 * 几个变量含义:(1)mBowVec:BoW向量,里面存储的是从BoW词袋中查询到的“单词” * (2)mvInvertedFile:是一个向量,里面存放的是一个个单词,每个单词对应一个list链表,每个链表里存放的是拥有该单词的关键帧 * 即,每一个单词都对应着所有看到该单词的关键帧 * (3)pKFi->mnRelocWords:该关键帧与当前帧所共有的单词数 * */vector<KeyFrame*> KeyFrameDatabase::DetectRelocalizationCandidates(Frame *F){    list<KeyFrame*> lKFsSharingWords;//与当前帧具有公共单词的所有关键帧    {        ///遍历该帧看到的所有单词        unique_lock<mutex> lock(mMutex);        for(DBoW2::BowVector::const_iterator vit=F->mBowVec.begin(), vend=F->mBowVec.end(); vit != vend; vit++)        {            list<KeyFrame*> &lKFs =   mvInvertedFile[vit->first];//找到这个单词所对应的所有关键帧            ///遍历该单词的所有关键帧,并打上标签即:pKFi->mnRelocQuery=F->mnId,为了防止lKFsSharingWords中重复添加            for(list<KeyFrame*>::iterator lit=lKFs.begin(), lend= lKFs.end(); lit!=lend; lit++)            {                KeyFrame* pKFi=*lit;                if(pKFi->mnRelocQuery!=F->mnId)//为了不对同一个关键帧重复检测,这里打一个标签                {                    pKFi->mnRelocWords=0;                    pKFi->mnRelocQuery=F->mnId;                    lKFsSharingWords.push_back(pKFi);                }                pKFi->mnRelocWords++;//如果当前帧与该帧每共有一个单词,则加一            }        }    }    ///如果关键帧库里所有的关键帧与当前帧都没有公共单词,则返回空    if(lKFsSharingWords.empty())        return vector<KeyFrame*>();    int maxCommonWords=0;//最大共有单词数量    ///遍历所有与当前帧具有公共单词的关键帧,并找与当前帧具有的最大公共单词数    for(list<KeyFrame*>::iterator lit=lKFsSharingWords.begin(), lend= lKFsSharingWords.end(); lit!=lend; lit++)    {        if((*lit)->mnRelocWords>maxCommonWords)            maxCommonWords=(*lit)->mnRelocWords;    }    int minCommonWords = maxCommonWords*0.8f;//最小共有单词数取最大共有单词数的0.8倍    list<pair<float,KeyFrame*> > lScoreAndMatch;    int nscores=0;    ///找出共有单词数在minCommonWords与maxCommonWords之间的关键帧,作为“得分较高的关键帧”,    /// 并且计算当前帧与该关键帧的得分,将得分与该关键帧组成pair存到lScoreAndMatch中    for(list<KeyFrame*>::iterator lit=lKFsSharingWords.begin(), lend= lKFsSharingWords.end(); lit!=lend; lit++)    {        KeyFrame* pKFi = *lit;        if(pKFi->mnRelocWords>minCommonWords)        {            nscores++;            float si = mpVoc->score(F->mBowVec,pKFi->mBowVec);//比较两个vector向量的得分            pKFi->mRelocScore=si;            lScoreAndMatch.push_back(make_pair(si,pKFi));        }    }    ///这一个应该是不会发生的,因为至少有一个关键帧与当前帧的共有单词数符合上边的阈值范围,就是共有单词数最多的那个关键帧    if(lScoreAndMatch.empty())        return vector<KeyFrame*>();    list<pair<float,KeyFrame*> > lAccScoreAndMatch;    float bestAccScore = 0;    ///遍历得分较高的关键帧所对应的10个最佳共视关键帧,这样lScoreAndMatch序列中“被共视”的越多的关键帧将越有可能被选为候选关键帧    /// 注:这一块看的不是特别明白,如有错误请指出,谢谢    for(list<pair<float,KeyFrame*> >::iterator it=lScoreAndMatch.begin(), itend=lScoreAndMatch.end(); it!=itend; it++)    {        KeyFrame* pKFi = it->second;        vector<KeyFrame*> vpNeighs = pKFi->GetBestCovisibilityKeyFrames(10);//获取10个最佳共视关键帧        float bestScore = it->first;        float accScore = bestScore;        KeyFrame* pBestKF = pKFi;        ///遍历该帧对应的共视关键帧        for(vector<KeyFrame*>::iterator vit=vpNeighs.begin(), vend=vpNeighs.end(); vit!=vend; vit++)        {            KeyFrame* pKF2 = *vit;            if(pKF2==NULL)//add by yuxi                continue;            if(pKF2->mnRelocQuery!=F->mnId)//如果该帧不在lKFsSharingWords中,则无须再处理                continue;            accScore+=pKF2->mRelocScore;//将pKFi的得分与它的共视关键帧得分累加            if(pKF2->mRelocScore>bestScore)//如果共视关键帧的得分超过pKFi,则将pKFi替换掉            {                pBestKF=pKF2;                bestScore = pKF2->mRelocScore;            }        }        lAccScoreAndMatch.push_back(make_pair(accScore,pBestKF));        if(accScore>bestAccScore)            bestAccScore=accScore;    }    ///将lAccScoreAndMatch accScore中满足阈值的得分作为候选关键帧,返回    float minScoreToRetain = 0.75f*bestAccScore;    set<KeyFrame*> spAlreadyAddedKF;    vector<KeyFrame*> vpRelocCandidates;    vpRelocCandidates.reserve(lAccScoreAndMatch.size());    for(list<pair<float,KeyFrame*> >::iterator it=lAccScoreAndMatch.begin(), itend=lAccScoreAndMatch.end(); it!=itend; it++)    {        const float &si = it->first;        if(si>minScoreToRetain)        {            KeyFrame* pKFi = it->second;            if(!spAlreadyAddedKF.count(pKFi))            {                vpRelocCandidates.push_back(pKFi);                spAlreadyAddedKF.insert(pKFi);            }        }    }    return vpRelocCandidates;}
0 0
原创粉丝点击