【slam十四讲第二版】【课后习题】【第十一讲~回环检测】
- 0 前言
- 1 课后习题
-
- 1.1 请书写计算PR 曲线的小程序。用MATLAB 或Python 可能更加简便一些,因为它们擅长作图。
- 1.2 验证回环检测算法,需要有人工标记回环的数据集,例如[103]。然而人工标记回环是很不方便的,我们会考虑根据标准轨迹计算回环。即,如果轨迹中有两个帧的位姿非常相近,就认为它们是回环。请你根据TUM 数据集给出的标准轨迹,计算出一个数据集中的回环。这些回环的图像真的相似吗?
- 1.3 学习DBoW3 或DBoW2 库,自己寻找几张图片,看能否从中正确检测出回环。
- 1.4 调研相似性评分的常用度量方式,哪些比较常用?
- 1.5 Chow-Liu 树是什么原理?它是如何被用于构建字典和回环检测的?
- 1.6 阅读[118],除了词袋模型,还有哪些用于回环检测的方法?
0 前言
1 课后习题
1.1 请书写计算PR 曲线的小程序。用MATLAB 或Python 可能更加简便一些,因为它们擅长作图。
- 这题跳过,因为使用python的话还需要配环境,这里等需要的时候在进行学习,比如numpy等等,最基本的,虽然之前配过,但是担心和当下的环境冲突,就不多此一举了
- 参考
- python参考这个:视觉SLAM十四讲CH11代码解析及课后习题详解
- matlab参考这个:视觉SLAM十四讲(第二版)第11讲习题解答
1.2 验证回环检测算法,需要有人工标记回环的数据集,例如[103]。然而人工标记回环是很不方便的,我们会考虑根据标准轨迹计算回环。即,如果轨迹中有两个帧的位姿非常相近,就认为它们是回环。请你根据TUM 数据集给出的标准轨迹,计算出一个数据集中的回环。这些回环的图像真的相似吗?
- 参考:视觉SLAM十四讲CH11代码解析及课后习题详解,但是这里说运行不能通过
- 代码是没有问题的,确定自己的数据集的真是轨迹路径的,这是因为路径文件的问题,路径文件下载地址,或者网盘自取:链接,提取码: 472q ,直接下载下来的路径文件如下:
# 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
需要把前三行删去,因为代码没有过滤这部分,直接读取数据会读取不到正确的数据。为了保证所提供数据库链接的完整性,上述所提供的网盘链接还没有进行修改。
- 为了方便,我把真实路径文件放在了该工程下,整个工程自取:链接: https://pan.baidu.com/s/1_E82hwrcx-lnsB-snW2NsQ 提取码: fdwj
1.2.1 tum.cpp
#include <pangolin/pangolin.h>
#include <Eigen/Core>
#include <Eigen/Geometry>
#include <unistd.h>
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;
}
1.2.2 CMakeLists.txt
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})
1.2.3 输出
/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
1.3 学习DBoW3 或DBoW2 库,自己寻找几张图片,看能否从中正确检测出回环。
-
这里主要就是自己寻找数据集,然后再完整的把课本的内容实现一遍,首先选取图片训练词袋模型,然后依据得到的字典进行回环检测,使用的均是【slam十四讲第二版】【课本例题代码向】【第十一讲~回环检测】【DBoW3的安装】【创建字典】【相似度检测】【增加字典规模】里的例程。
-
然后,这部分我没有实现,具体的实现可以参考:视觉SLAM十四讲CH11代码解析及课后习题详解或者视觉SLAM十四讲(第二版)第11讲习题解答
-
即便给出较高的匹配分数,回环的判断仍存在一些错误,原因如下
- BoW方法的原理仅考虑Word(即物品)的有无,不考虑位置与个数。相反视角对同一场景的拍摄使得两组照片的多数Word相同,因此给出了较高的分数,但人类视角明显可以发现这是不构成回环。
- 使用的训练数据集样本太小(电脑不好,没用完整的数据集),正如书中所说“好模型敌不过烂数据”,笔者仅通过15张照片训练出的字典明显不够,通过多“喂”适当的数据可以提升分析的准确性。
- 但不可否认BoW这种方法的意义(原理简单但确实有效),后续提升的思路在书中也有提及:通过机器学习的方法可以改进BoW模型,甚至经过大量数据训练的神经网络在识别物体上可以超越BoW,希望以后能继续学习更加先进和有效的回环检测算法~
1.4 调研相似性评分的常用度量方式,哪些比较常用?
- 有许多种
欧式距离
曼哈顿距离
切比雪夫距离
闵可夫斯基距离
标准化欧氏距离
马氏距离
夹角余弦
汉明距离
杰卡德距离&杰卡德相似系数
相关系数&相关距离
信息熵 - 参考
- 机器学习中的相似性度量,概念讲述和matlab演示
- 数据科学中常见的9种距离度量方法,内含欧氏距离、切比雪夫距离等,主要是概念讲述
- 视觉SLAM十四讲CH11代码解析及课后习题详解,包含
欧式距离
、曼哈顿距离
、切比雪夫距离
、汉明距离
、标准化欧氏距离
、夹角余弦
、杰卡德距离&杰卡德相似系数
、相关系数&相关距离
的matlab演示示例。
1.5 Chow-Liu 树是什么原理?它是如何被用于构建字典和回环检测的?
1.6 阅读[118],除了词袋模型,还有哪些用于回环检测的方法?
- 参考:
- 参考文献[118]中提到了如下三种方法
- Map-to-map,通过比较两个子地图的外观和特征之间的相对位置关系实现回环检测,如GCBB(geometric compatibility branch and bound)算法;
- Image-to-image,对比先前和当前时刻的照片的特征实现回环检测,如词袋方法;
- Image-to-map,基于重定位的方法,先将当前帧的特征与地图匹配,然后通过RANSAC和三点法求解当前相机位姿从而实现重定位,进而实现回环检测。
- 另外,具体像在VSLAM中应用的随机蕨法(重定位)、基于深度学习的方法(图像的全局检索)等也是常见的回环检测方法,关于这些方法可以参考下面的文章
- 综述 | SLAM回环检测方法
这篇文章、简单介绍了词袋模型(Bag Of Words,BOW)
、随机蕨法(Random ferns)
、基于深度学习的方法(有监督的方法、无监督的方法)
的原理和源码