这篇博客旨在记录一下DBoW和KeyFrameDatabase的小细节,以防后面再忘掉。18年初的时候参考ORB slam做重定位和闭环检测挖过DBoW里的代码,没想到过了一年多很多代码细节就记不清了。这次干脆记下来吧。
文章目录
一、DBoW
1、模板定义
template<class TDescriptor, class F>
/// Generic Vocabulary
class TemplatedVocabulary
{
}
2、模板应用
ORB slam中定义了ORB描述子类型的字典
typedef DBoW2::TemplatedVocabulary<DBoW2::FORB::TDescriptor, DBoW2::FORB> ORBVocabulary;
其中TDescriptor
是cv::Mat
,FORB
是为ORB描述子定义的类,其中包含了计算描述子之间汉明距离以及计算描述子平均值的方法。
3、字典初始化
默认为10叉5层树状结构,L1_NROM距离和TF_IDF,加载txt字典时设置为6层。所说的6层是指除去根节点后中间节点及叶子节点占用的层数。
m_nodes包含了所有的节点,m_words只包含了叶子节点即最后的单词,m_words是一个vector<Node*>
数据,索引对应word的id,内容对应m_nodes中对应项的地址。
4、图像描述子向BowVector和FeatureVector转换
class BowVector: public std::map<WordId, WordValue>
{
//WordId是字典中word的id,不是nodeid
//WordValue是TF_IDF值
}
class FeatureVector: public std::map<NodeId, std::vector<unsigned int> >
{
//NodeId是levelup指定的那一层的对应的node的id
//vector<unsigned int>是一个feature在当前KeyFrame中的索引
}
BowVector实际上是图像的一种降维表达,一幅图像可以表示为 v = { ( w 0 , η 0 ) , ( w 1 , η 1 ) , . . . , ( w i , η i ) , . . . } v = \{(w_0,\eta_0),(w_1,\eta_1),...,(w_i,\eta_i),...\} v={ (w0,η0),(w1,η1),...,(wi,ηi),...}。其中 w i w_i wi是WordId, η i \eta_i ηi是单词 w i w_i wi的权重。 η i \eta_i