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];
  }
}

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