建立DBow離線詞典用於ORB SLAM2

weixin_33807284發表於2018-03-25

前言

無論是DBow2,還是DBow3,它們建立的字典檔案的都是.yml格式,不能直接應用於ORB SLAM2。檔案如下:

vocabulary:
   k: 10  #詞典樹的分枝因子,即kmeas的K族
   L: 5   #樹的深度
   scoringType: 0  #相似度
   weightingType: 0   #權重
   nodes: #節點,以下分別是節點id,父節點id,權重
      - { nodeId:1, parentId:0, weight:0.,  
          descriptor:"63 127 236 133 254 19 222 248 83 238 156 239 73 108 215 135 127 229 247 231 237 243 237 206 62 95 239 183 111 255 122 213 " }
      - { nodeId:2, parentId:0, weight:0.,
    ...
    words:
      - { wordId:0, nodeId:23 }
      - { wordId:1, nodeId:31 }
    ...

ORB SLAM2中的ORBvoc.txt

SLAM中字典檔案是作者他們用巨大的圖片庫生成的,對室內,戶外都有很好的效果,有時候自己生成的字典,效果沒它好,格式如下

10 6  0 0 #表示上面的k,L,s,w
0 0 252 188 188 242 169 109 85 143 187 191 164 25 222 255 72 27 129 215 237 16 58 111 219 51 219 211 85 127 192 112 134 34  0
...
# 0表示節點的父節點;0表示是否是葉節點,是的話為1,否則為0;252-34表示orb特徵;最後一位是權重

修改DBow2

因為ORB SLAM2用的是DBow2,還是直接改DBow2,讓它支援生成如ORBvoc.txt的檔案。
之前找了好多資料,都沒有很好的實現,如https://github.com/jonas-/myStuff,我總是編譯不成功。但在這上面看到一個函式saveToTextFile,它就是生成txt檔案的函式。
DBow2中是沒有的,但我看了ORB SLAM中DBow2,發現是有的,是作者加的。其實這樣的還有很多,比如ORB SLAM2中ORB特徵提取,不是直接用Opencv的,但大體相似,只做了少許改動。所以..

直接開抄
template<class TDescriptor, class F>
void TemplatedVocabulary<TDescriptor,F>::saveToTextFile(const std::string &filename) const
{
    fstream f;
    f.open(filename.c_str(),ios_base::out);
    f << m_k << " " << m_L << " " << " " << m_scoring << " " << m_weighting << endl;

    for(size_t i=1; i<m_nodes.size();i++)
    {
        const Node& node = m_nodes[i];
        f << node.parent << " ";
        if(node.isLeaf())
            f << 1 << " ";
        else
            f << 0 << " ";
        f << F::toString(node.descriptor) << " " << (double)node.weight << endl;
    }
    f.close();
}

把上面的程式碼放到TemplatedVocabulary.h中,前面加宣告,還有using namespace std;,然後在demo.cpp中呼叫此函式,重新編譯一下,OK。
也可以直接用我的程式碼:https://github.com/itswcg/DBow

其他說明

我用10張圖片,生成一個字典檔案,再用我標定的相機做測試,發現效果不是很理想,要等好久才能檢測出角點,沒有預設的快。可能是圖片少的原因,等下測試個幾百張先。

相關文章