前言

无论是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张图片,生成一个字典文件,再用我标定的相机做测试,发现效果不是很理想,要等好久才能检测出角点,没有默认的快。可能是图片少的原因,等下测试个几百张先。