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
- ORB_SLAM2修(Ru)仙(Keng)之路(一):重定位候选关键帧选取函数注释
- 编译 ORB_SLAM2 (一)
- ORB_SLAM2捋思路(3)
- ZOJ3549 Little Keng(快速幂)
- CVPR2016之A Key Volume Mining Deep Framework for Action Recognition论文阅读(视频关键帧选取)
- 中文分词之候选集的选取
- 编程实现计算FIRST集和FOLLOW集C++之(一)处理候选式:多个右部
- webrtc学习(一)之------关键帧请求
- ZOJ3549 Little Keng(java大数,快速幂)
- UVA——10189(keng die a)扫雷
- 定位关键代码(施工中)
- 《重构改善既有代码的设计》之重构列表--重新组织函数(一)
- Important Concepts(重要概念)之Candidates(候选)
- 什么是重定位?为什么需要重定位?(嵌入式下)
- uboot系列之-----代码重定位(源码)
- 连续分配方式之(可重定位分区分配 )
- 乌拉尔大学(URAL):http://acm.timus.ru/
- github基础操作命令集(ru'meng)
- 再生核Hilbert空间(RKHS)&SVM
- 插件原理
- 百步穿杨
- 程序员面试金典--判断直线相交
- 聊一聊啥都不会的我自学Linux系统的历程
- ORB_SLAM2修(Ru)仙(Keng)之路(一):重定位候选关键帧选取函数注释
- 拉格朗日乘子法和KKT条件
- java 上传附件到ftpServer 第三讲
- 程序员面试金典--面试34之加法运算替代
- gulp安装&less插件
- 正在蔓延的加密勒索病毒预防措施
- 循环结构
- hdu 1160 FatMouse's Speed
- JS的简单使用