视觉slam闭环检测之-DBoW2 -视觉词袋构建
需要准备的知识点:http://www.cnblogs.com/zjiaxing/p/5616653.html
http://www.cnblogs.com/zjiaxing/p/5616664.html
http://www.cnblogs.com/zjiaxing/p/5616670.html
http://www.cnblogs.com/zjiaxing/p/5616679.html
#include <iostream>
#include <vector> // DBoW2
#include "DBoW2.h" // defines Surf64Vocabulary and Surf64Database #include <DUtils/DUtils.h>
#include <DVision/DVision.h> // OpenCV
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp> using namespace DBoW2;
using namespace DUtils;
using namespace std; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void loadFeatures(vector<vector<vector<float> > > &features);
void changeStructure(const vector<float> &plain, vector<vector<float> > &out,
int L);
void testVocCreation(const vector<vector<vector<float> > > &features);
void testDatabase(const vector<vector<vector<float> > > &features); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // number of training images
const int NIMAGES = ; // extended surf gives 128-dimensional vectors
const bool EXTENDED_SURF = false; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void wait()
{
cout << endl << "Press enter to continue" << endl;
getchar();
} // ---------------------------------------------------------------------------- int main()
{
vector<vector<vector<float> > > features;
loadFeatures(features);
testVocCreation(features);
wait(); testDatabase(features); return ;
} // ---------------------------------------------------------------------------- void loadFeatures(vector<vector<vector<float> > > &features)
{
features.clear();
features.reserve(NIMAGES);
cv::Ptr<cv::xfeatures2d::SURF> surf = cv::xfeatures2d::SURF::create(, , , EXTENDED_SURF);
cout << "Extracting SURF features..." << endl;
for(int i = ; i < NIMAGES; ++i)
{
stringstream ss;
ss << "images/image" << i << ".png";
cv::Mat image = cv::imread(ss.str(), );
cv::Mat mask;
vector<cv::KeyPoint> keypoints;
vector<float> descriptors; surf->detectAndCompute(image, mask, keypoints, descriptors); features.push_back(vector<vector<float> >());
changeStructure(descriptors, features.back(), surf->descriptorSize());
}
} // ---------------------------------------------------------------------------- void changeStructure(const vector<float> &plain, vector<vector<float> > &out,
int L)
{
out.resize(plain.size() / L);
unsigned int j = ;
for(unsigned int i = ; i < plain.size(); i += L, ++j)
{
out[j].resize(L);
std::copy(plain.begin() + i, plain.begin() + i + L, out[j].begin());
}
} // ---------------------------------------------------------------------------- void testVocCreation(const vector<vector<vector<float> > > &features)
{
// Creates a vocabulary from the training features, setting the branching
factor and the depth levels of the tree and the weighting and scoring
schemes * Creates k clusters from the given descriptors with some seeding algorithm. const int k = ;
const int L = ;
const WeightingType weight = TF_IDF;
const ScoringType score = L1_NORM; Surf64Vocabulary voc(k, L, weight, score); cout << "Creating a small " << k << "^" << L << " vocabulary..." << endl;
voc.create(features);
cout << "... done!" << endl; cout << "Vocabulary information: " << endl
<< voc << endl << endl; // lets do something with this vocabulary
cout << "Matching images against themselves (0 low, 1 high): " << endl;
BowVector v1, v2;
for(int i = ; i < NIMAGES; i++)
{
//Transforms a set of descriptores into a bow vector
voc.transform(features[i], v1);
for(int j = ; j < NIMAGES; j++)
{
voc.transform(features[j], v2); double score = voc.score(v1, v2);
cout << "Image " << i << " vs Image " << j << ": " << score << endl;
}
} // save the vocabulary to disk
cout << endl << "Saving vocabulary..." << endl;
voc.save("small_voc.yml.gz");
cout << "Done" << endl;
} // ---------------------------------------------------------------------------- void testDatabase(const vector<vector<vector<float> > > &features)
{
cout << "Creating a small database..." << endl; // load the vocabulary from disk
Surf64Vocabulary voc("small_voc.yml.gz"); Surf64Database db(voc, false, ); // false = do not use direct index
// (so ignore the last param)
// The direct index is useful if we want to retrieve the features that
// belong to some vocabulary node.
// db creates a copy of the vocabulary, we may get rid of "voc" now // add images to the database
for(int i = ; i < NIMAGES; i++)
{
db.add(features[i]);
} cout << "... done!" << endl; cout << "Database information: " << endl << db << endl; // and query the database
cout << "Querying the database: " << endl; QueryResults ret;
for(int i = ; i < NIMAGES; i++)
{
db.query(features[i], ret, ); // ret[0] is always the same image in this case, because we added it to the
// database. ret[1] is the second best match. cout << "Searching for Image " << i << ". " << ret << endl;
} cout << endl; // we can save the database. The created file includes the vocabulary
// and the entries added
cout << "Saving database..." << endl;
db.save("small_db.yml.gz");
cout << "... done!" << endl; // once saved, we can load it again
cout << "Retrieving database once again..." << endl;
Surf64Database db2("small_db.yml.gz");
cout << "... done! This is: " << endl << db2 << endl;
}
视觉slam闭环检测之-DBoW2 -视觉词袋构建的更多相关文章
- 《视觉SLAM十四讲》第2讲
目录 一 视觉SLAM中的传感器 二 经典视觉SLAM框架 三 SLAM问题的数学表述 注:原创不易,转载请务必注明原作者和出处,感谢支持! 本讲主要内容: (1) 视觉SLAM中的传感器 (2) 经 ...
- 视觉SLAM之词袋(bag of words) 模型与K-means聚类算法浅析
原文地址:http://www.cnblogs.com/zjiaxing/p/5548265.html 在目前实际的视觉SLAM中,闭环检测多采用DBOW2模型https://github.com/d ...
- 视觉SLAM之词袋(bag of words) 模型与K-means聚类算法浅析(1)
在目前实际的视觉SLAM中,闭环检测多采用DBOW2模型https://github.com/dorian3d/DBoW2,而bag of words 又运用了数据挖掘的K-means聚类算法,笔者只 ...
- (转) SLAM系统的研究点介绍 与 Kinect视觉SLAM技术介绍
首页 视界智尚 算法技术 每日技术 来打我呀 注册 SLAM系统的研究点介绍 本文主要谈谈SLAM中的各个研究点,为研究生们(应该是博客的多数读者吧)作一个提纲挈领的摘要.然后,我 ...
- 视觉SLAM漫谈 (三): 研究点介绍
1. 前言 读者朋友们大家好!(很久很久)之前,我们为大家介绍了SLAM的基本概念和方法.相信大家对SLAM,应该有了基本的认识.在忙完一堆写论文.博士开题的事情之后,我准备回来继续填坑:为大家介绍S ...
- 视觉SLAM关键方法总结
点"计算机视觉life"关注,置顶更快接收消息! 最近在做基于激光信息的机器人行人跟踪发现如果单独利用激光信息很难完成机器人对行人的识别.跟踪等功能,因此考虑与视觉融合的方法,这样 ...
- 视觉SLAM的主要功能模块分析
视觉SLAM的主要功能模块分析 一.基本概念 SLAM (simultaneous localization and mapping),也称为CML (Concurrent Mapping and L ...
- 高翔《视觉SLAM十四讲》从理论到实践
目录 第1讲 前言:本书讲什么:如何使用本书: 第2讲 初始SLAM:引子-小萝卜的例子:经典视觉SLAM框架:SLAM问题的数学表述:实践-编程基础: 第3讲 三维空间刚体运动 旋转矩阵:实践-Ei ...
- 视觉SLAM漫淡
视觉SLAM漫谈 1. 前言 开始做SLAM(机器人同时定位与建图)研究已经近一年了.从一年级开始对这个方向产生兴趣,到现在为止,也算是对这个领域有了大致的了解.然而越了解,越觉得这个方向难度很 ...
随机推荐
- Android常用异步任务执行方法
Handler原理及基本概念 Message 意为消息,发送到Handler进行处理的对象,携带描述信息和任意数据. MessageQueue 意为消息队列,Message的集合. Looper 有着 ...
- axios [æk'si:əʊs] 及 axios 请求配置
特征 比Jquery轻量,但处理请求不多的时候,可以使用 基于Promise语法标准 支持nodejs 自动转换JSON数据 用法 get // Make a request for a user w ...
- 回顾 git 常用命令
git init 在本地新建一个repo,进入一个项目目录,执行git init,会初始化一个repo,并在当前文件夹下创建一个.git文件夹. git clone 获取一个u ...
- Exception sending context initialized event to listener instance of class ssm.blog.listener.InitBloggerData java.lang.NullPointerException at ssm.blog.listener.InitBloggerData.c
spring注入是分两部分执行的 首先是 先把需要注入的对象加载到spring容器 然后在把对象注入到具体需要注入的对象里面 这种就是配置和注解的注入 getbean方式其 ...
- Linux命令-网络命令:setup
setup 进入设置网络信息的界面 上图中选“网络配置”进入设置网络信息 上图中选“设备配置”进行配置IP地址,下图显示网卡信息 上图中,选择“eth0”回车进入设置eth0网卡信息界面 上图中选择“ ...
- 区别原生chrome 和以chrome为内核的360浏览器
function isChrome360() { if( navigator.userAgent.toLowerCase().indexOf('chrome') > -1 ) { var des ...
- 自定义asp.net mvc Filter 过滤器
1新建一个mvc项目:如图 2.主要创建下面一些类文件 1.utility目录 放置自定义的过滤器 using System; using System.Collections.Generic; us ...
- Incorrect integer value: '' for column 'mid' at row 11366Incorrect integer value: '' for column 'mid' at row 1,自增字段为空,添加记录时出错
在本地机器做测试时,数据可以正常添加,但是将代码放置到服务器上时,提示:Incorrect integer value: '' for column 'mid' at row 11366Incorre ...
- laydate 和 Vue 奇怪的清空问题
laydate的input,会自动被清空,当别的input修改的时候.改成这样既可解决 <td><input type="text" id="retur ...
- Spring Boot(二):@SpringBootApplication注解理解
@SpringBootApplication包含三个有用的注解,包括 @SpringBootConfiguration:看源码其实就是@Configuration,表示当前类是一个配置类,就像xml配 ...