# ground truth trajectory
# file: 'rgbd_dataset_freiburg1_desk2.bag'
# timestamp tx ty tz qx qy qz qw
1305031523.0922 1.2905 0.0005 1.5678 0.7317 0.5466 -0.3131 -0.2604
1305031523.1022 1.2910 0.0001 1.5699 0.7320 0.5480 -0.3139 -0.2556
1305031523.1123 1.2917 -0.0002 1.5724 0.7321 0.5493 -0.3141 -0.2523
需要把前三行删去,因为代码没有过滤这部分,直接读取数据会读取不到正确的数据。为了保证所提供数据库链接的完整性,上述所提供的网盘链接还没有进行修改。
#include
#include
#include
#include
using namespace std;
using namespace Eigen;
// /home/bupo/my_study/slam14/slam14_my/cap11/rgbd_dataset_freiburg1_desk2/rgb
// path to groundtruth file
//string groundtruth_file = "/home/liqiang/slambook2/ch11/rgbd_dataset_freiburg2_rpy/groundtruth.txt";
//string groundtruth_file = "/home/bupo/my_study/slam14/slam14_my/cap11/rgbd_dataset_freiburg1_desk2/groundtruth_tum.txt";
string groundtruth_file = "../groundtruth_tum.txt";
// 设置检测的间隔,使得检测具有稀疏性的同时覆盖整个环境
int delta = 10;
// 齐次变换矩阵差的范数
// 小于该值时认为位姿非常接近
double threshold = 0.4;
int main(int argc, char **argv) {
vector<Isometry3d, Eigen::aligned_allocator<Isometry3d>> poses;
vector<string> times;
ifstream fin(groundtruth_file);
if (!fin) {
cout << "cannot find trajectory file at " << groundtruth_file << endl;
return 1;
}
int num = 0;
while (!fin.eof())
{
string time_s;
double tx, ty, tz, qx, qy, qz, qw;
fin >> time_s >> tx >> ty >> tz >> qx >> qy >> qz >> qw;
Isometry3d Twr(Quaterniond(qw, qx, qy, qz));
Twr.pretranslate(Vector3d(tx, ty, tz));
// 相当于从第150个位姿开始,这是因为标准轨迹的记录早于照片拍摄(前120个位姿均无对应照片)
if (num > 400 && num % delta == 0){
//cout << time_s << endl;
times.push_back(time_s);
poses.push_back(Twr);
}
num++;
}
cout << "read total " << num << " pose entries" << endl;
cout << "selected total " << poses.size() << " pose entries" << endl;
//设置检测到回环后重新开始检测图片间隔数量
cout << "**************************************************" << endl;
cout << "Detection Start!!!" << endl;
cout << "**************************************************" << endl;
for (size_t i = 0 ; i < poses.size() - delta; i += delta){
for (size_t j = i + delta ; j < poses.size() ; j++){
Matrix4d Error = (poses[i].inverse() * poses[j]).matrix() - Matrix4d::Identity();
if (Error.norm() < threshold){
cout << "第" << i << "张照片与第" << j << "张照片构成回环" << endl;
cout << "位姿误差为" << Error.norm() << endl;
cout << "第" << i << "张照片的时间戳为" << endl << times[i] << endl;
cout << "第" << j << "张照片的时间戳为" << endl << times[j] << endl;
cout << "**************************************************" << endl;
break;
}
}
}
cout << "Detection Finish!!!" << endl;
cout << "**************************************************" << endl;
return 0;
}
cmake_minimum_required(VERSION 2.8)
project(tum)
include_directories("/usr/include/eigen3")
find_package(Pangolin REQUIRED)
include_directories(${Pangolin_INCLUDE_DIRS})
add_executable(tum src/tum.cpp)
target_link_libraries(tum ${Pangolin_LIBRARIES})
/home/bupo/my_study/slam14/slam14_my/cap11/TUM_11_2/cmake-build-debug/tum
read total 2429 pose entries
selected total 202 pose entries
**************************************************
Detection Start!!!
**************************************************
第20张照片与第122张照片构成回环
位姿误差为0.368668
第20张照片的时间戳为
1305031529.6721
第122张照片的时间戳为
1305031539.8720
**************************************************
第60张照片与第88张照片构成回环
位姿误差为0.36689
第60张照片的时间戳为
1305031533.6721
第88张照片的时间戳为
1305031536.4721
**************************************************
第130张照片与第140张照片构成回环
位姿误差为0.257195
第130张照片的时间戳为
1305031540.6720
第140张照片的时间戳为
1305031541.7820
**************************************************
第150张照片与第160张照片构成回环
位姿误差为0.357759
第150张照片的时间戳为
1305031542.7819
第160张照片的时间戳为
1305031543.7819
**************************************************
第190张照片与第200张照片构成回环
位姿误差为0.113252
第190张照片的时间戳为
1305031546.7823
第200张照片的时间戳为
1305031547.7827
**************************************************
Detection Finish!!!
**************************************************
进程已结束,退出代码0
这里主要就是自己寻找数据集,然后再完整的把课本的内容实现一遍,首先选取图片训练词袋模型,然后依据得到的字典进行回环检测,使用的均是【slam十四讲第二版】【课本例题代码向】【第十一讲~回环检测】【DBoW3的安装】【创建字典】【相似度检测】【增加字典规模】里的例程。
然后,这部分我没有实现,具体的实现可以参考:视觉SLAM十四讲CH11代码解析及课后习题详解或者视觉SLAM十四讲(第二版)第11讲习题解答
即便给出较高的匹配分数,回环的判断仍存在一些错误,原因如下
欧式距离
、曼哈顿距离
、切比雪夫距离
、汉明距离
、标准化欧氏距离
、夹角余弦
、杰卡德距离&杰卡德相似系数
、相关系数&相关距离
的matlab演示示例。
- Map-to-map,通过比较两个子地图的外观和特征之间的相对位置关系实现回环检测,如GCBB(geometric compatibility branch and bound)算法;
- Image-to-image,对比先前和当前时刻的照片的特征实现回环检测,如词袋方法;
- Image-to-map,基于重定位的方法,先将当前帧的特征与地图匹配,然后通过RANSAC和三点法求解当前相机位姿从而实现重定位,进而实现回环检测。
词袋模型(Bag Of Words,BOW)
、随机蕨法(Random ferns)
、基于深度学习的方法(有监督的方法、无监督的方法)
的原理和源码