【slam十四讲第二版】【课后习题】【第十一讲~回环检测】

0 前言

1 课后习题

1.1 请书写计算PR 曲线的小程序。用MATLAB 或Python 可能更加简便一些,因为它们擅长作图。

  • 这题跳过,因为使用python的话还需要配环境,这里等需要的时候在进行学习,比如numpy等等,最基本的,虽然之前配过,但是担心和当下的环境冲突,就不多此一举了
  • 参考
  1. python参考这个:视觉SLAM十四讲CH11代码解析及课后习题详解
  2. matlab参考这个:视觉SLAM十四讲(第二版)第11讲习题解答

1.2 验证回环检测算法,需要有人工标记回环的数据集,例如[103]。然而人工标记回环是很不方便的,我们会考虑根据标准轨迹计算回环。即,如果轨迹中有两个帧的位姿非常相近,就认为它们是回环。请你根据TUM 数据集给出的标准轨迹,计算出一个数据集中的回环。这些回环的图像真的相似吗?

# 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

需要把前三行删去,因为代码没有过滤这部分,直接读取数据会读取不到正确的数据。为了保证所提供数据库链接的完整性,上述所提供的网盘链接还没有进行修改。

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.36866820张照片的时间戳为
1305031529.6721122张照片的时间戳为
1305031539.8720
**************************************************60张照片与第88张照片构成回环
位姿误差为0.3668960张照片的时间戳为
1305031533.672188张照片的时间戳为
1305031536.4721
**************************************************130张照片与第140张照片构成回环
位姿误差为0.257195130张照片的时间戳为
1305031540.6720140张照片的时间戳为
1305031541.7820
**************************************************150张照片与第160张照片构成回环
位姿误差为0.357759150张照片的时间戳为
1305031542.7819160张照片的时间戳为
1305031543.7819
**************************************************190张照片与第200张照片构成回环
位姿误差为0.113252190张照片的时间戳为
1305031546.7823200张照片的时间戳为
1305031547.7827
**************************************************
Detection Finish!!!
**************************************************

进程已结束,退出代码0

1.3 学习DBoW3 或DBoW2 库,自己寻找几张图片,看能否从中正确检测出回环。

  1. BoW方法的原理仅考虑Word(即物品)的有无,不考虑位置与个数。相反视角对同一场景的拍摄使得两组照片的多数Word相同,因此给出了较高的分数,但人类视角明显可以发现这是不构成回环。
  2. 使用的训练数据集样本太小(电脑不好,没用完整的数据集),正如书中所说“好模型敌不过烂数据”,笔者仅通过15张照片训练出的字典明显不够,通过多“喂”适当的数据可以提升分析的准确性。
  • 但不可否认BoW这种方法的意义(原理简单但确实有效),后续提升的思路在书中也有提及:通过机器学习的方法可以改进BoW模型,甚至经过大量数据训练的神经网络在识别物体上可以超越BoW,希望以后能继续学习更加先进和有效的回环检测算法~

1.4 调研相似性评分的常用度量方式,哪些比较常用?

  • 有许多种
    欧式距离
    曼哈顿距离
    切比雪夫距离
    闵可夫斯基距离
    标准化欧氏距离
    马氏距离
    夹角余弦
    汉明距离
    杰卡德距离&杰卡德相似系数
    相关系数&相关距离
    信息熵
  • 参考
  1. 机器学习中的相似性度量,概念讲述和matlab演示
  2. 数据科学中常见的9种距离度量方法,内含欧氏距离、切比雪夫距离等,主要是概念讲述
  3. 视觉SLAM十四讲CH11代码解析及课后习题详解,包含欧式距离曼哈顿距离切比雪夫距离汉明距离标准化欧氏距离夹角余弦杰卡德距离&杰卡德相似系数相关系数&相关距离的matlab演示示例。

1.5 Chow-Liu 树是什么原理?它是如何被用于构建字典和回环检测的?

1.6 阅读[118],除了词袋模型,还有哪些用于回环检测的方法?

  • 参考:
  1. 参考文献[118]中提到了如下三种方法
  1. Map-to-map,通过比较两个子地图的外观和特征之间的相对位置关系实现回环检测,如GCBB(geometric compatibility branch and bound)算法;
  2. Image-to-image,对比先前和当前时刻的照片的特征实现回环检测,如词袋方法;
  3. Image-to-map,基于重定位的方法,先将当前帧的特征与地图匹配,然后通过RANSAC和三点法求解当前相机位姿从而实现重定位,进而实现回环检测。
  • 另外,具体像在VSLAM中应用的随机蕨法(重定位)、基于深度学习的方法(图像的全局检索)等也是常见的回环检测方法,关于这些方法可以参考下面的文章
  1. ​综述 | SLAM回环检测方法
    这篇文章、简单介绍了词袋模型(Bag Of Words,BOW)随机蕨法(Random ferns)基于深度学习的方法(有监督的方法、无监督的方法)的原理和源码

猜你喜欢

转载自blog.csdn.net/qq_45954434/article/details/126130578