VINS-mono 解析 生成用于回环检测的字典文件

VINS回环检测使用的是FAST(Features from Accelerated Segment Test)特征点检测,并利用BRIEF描述子存储特征。挑选了两个实时性较好的检测和描述。BRIEF提供了一种计算二值串的捷径,而并不需要去计算一个类似于SIFT的特征描述子。采用这样的组合,是因为基于处理器和内存的限制,为保证实时性要求。

常见的字典库主要有DBoW2 DBoW3 fBoW等。写程序的过程中发现使用DBoW3库时加载.bin文件不能初始化词汇,如下编译运行总是出现opencv错误。

DBoW3::Vocabulary voc("./brief_k10L6.bin");

这个词汇文件应该来自dorian3d的DLoopDetector “./resources/brief_k10L6.voc.gz”.

生成词汇.bin的文件见[email protected]:......./extracvoc.git

值得一提的是原本的DBoW2不支持读取bin文件,而VINS-mono中的DBoW专为Brief特征写了读取.bin文件的加载函数。添加了头文件

#include "../VocabularyBinary.hpp"
#include <boost/dynamic_bitset.hpp>

初始化函数改成了使用bin文件初始化

template<class TDescriptor, class F>
TemplatedVocabulary<TDescriptor,F>::TemplatedVocabulary
  (const std::string &filename): m_scoring_object(NULL)
{
    //m_scoring = KL;
    // Changed by VINS [[[
    //printf("loop start load bin\n");
    loadBin(filename);
    // Changed by VINS ]]]
}

loadBin定义如下

template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::loadBin(const std::string &filename) {
    
  m_words.clear();
  m_nodes.clear();
  //printf("loop load bin\n");
  std::ifstream ifStream(filename);
  VINSLoop::Vocabulary voc;
  voc.deserialize(ifStream);
  ifStream.close();
  
  m_k = voc.k;
  m_L = voc.L;
  m_scoring = (ScoringType)voc.scoringType;
  m_weighting = (WeightingType)voc.weightingType;
  
  createScoringObject();

  m_nodes.resize(voc.nNodes + 1); // +1 to include root
  m_nodes[0].id = 0;

  for(unsigned int i = 0; i < voc.nNodes; ++i)
  {
    NodeId nid = voc.nodes[i].nodeId;
    NodeId pid = voc.nodes[i].parentId;
    WordValue weight = voc.nodes[i].weight;
      
    m_nodes[nid].id = nid;
    m_nodes[nid].parent = pid;
    m_nodes[nid].weight = weight;
    m_nodes[pid].children.push_back(nid);
      
    // Sorry to break template here
    m_nodes[nid].descriptor = boost::dynamic_bitset<>(voc.nodes[i].descriptor, voc.nodes[i].descriptor + 4);
    
    if (i < 5) {
      std::string test;
      boost::to_string(m_nodes[nid].descriptor, test);
      //cout << "descriptor[" << i << "] = " << test << endl;
    }
  }
  
  // words
  m_words.resize(voc.nWords);

  for(unsigned int i = 0; i < voc.nWords; ++i)
  {
    NodeId wid = (int)voc.words[i].wordId;
    NodeId nid = (int)voc.words[i].nodeId;
    
    m_nodes[nid].word_id = wid;
    m_words[wid] = &m_nodes[nid];
  }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章