ORB-SLAM2应用练习:三维重建系统搭建 (4) [END]

本文详细介绍了使用ORB-SLAM2搭建三维重建系统的过程,包括系统设计、运行流程和总结。系统通过初始化、相机矫正、图片处理、立体匹配等步骤生成点云,并使用pangolin进行交互式显示。尽管存在一些待优化的问题,如点云去重和鲁棒性检查,但整体实现了基本的3D重建功能。附带了代码链接和运行指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系统设计


写了这么久,终于可以来到这一步了。按照我们最初的思路,我们已经准备好了跟踪轨迹的SLAM程序、读取图片的Camera类族(我喜欢这么称呼一大堆有血缘关系的类们),以及立体匹配算子的类族,现在开始构造系统的结构。

想想我们系统运作的流程,大概会是:

  • 系统的初始化
  • 相机的初始化与立体矫正中视差图到深度图映射矩阵的计算
  • 图片的读取与预处理
  • 立体匹配、计算视差、求深度图
  • 根据深度图和原图,在3D空间中打印点云

另外,我希望在点云窗口可以以任意角度观察点云的分布,因此该窗口需要有一些交互动作的监听,所以我们很自然地将绘图放在一个单独的线程中去。根据以上的设计,我们的系统类声明如下:

#pragma once
#include "StereoMatching.h"
#include "CameraFactory.h"
#include <string>
#include <mutex>
#include <vector>
using namespace std;

namespace scs
{
    class System
    {
    public:
        /**
         * @Title: System Constructor
         * @Description: 初始化系统参数,设置立体匹配使用的算法,设置相机类型,加载相机参数,启动画图线程。
         * @param: algorithm, 立体匹配算法名字
         * @param: cameraType, 相机类型
         * @param: dir, 相机参数文件路径(第[0]份存放相机之间的RT矩阵与SLAM要求的参数,第[1][2]份存放相机内参数)
         * @param: name, 相机参数对象在参数文件中的ID
        */
        System(StereoMatching::Type algorithm, CameraFactory::Type cameraType, const string dir[3], const string name[2]);

        ~System();

        /**
         * @Tiitle: run
         * @Description: 系统运行,读图、定位,并三维重建
         * @param: num, 设置处理的帧数量。该值为0时,则一直处理。
        */
        void run(int num = 0);

    private:
        /**
         * @Title: rectify
         * @Description: 相机矫正
        */
        void rectify();

        /**
         * @Title: draw
         * @Description: 绘画线程
        */
        void draw();

    private:
        StereoMatcher * matcher;
        Camera * cam[2];
        Mat R, T, Q, mapx[2], mapy[2];

        vector<Mat> xyz, color;
        mutex mutexPushData;
        float mViewpointF, mViewpointX, mViewpointY, mViewpointZ, mPointSize;

        // 用于系统析构时,正确结束画图进程.
        bool isFinish, finish;
        mutex mutexIsFinish, mutexFinish;
    };
}

我简要介绍一下该类的接口。首先它处于scs的命名空间下。构造该类时需要四个参数,我的注释说的很清楚了,其中dir包含了SLAM所要求的参数文件路径,而name指的是相机参数在参数文件中的名字,具体可以看[相机类的抽象]这一篇文章对参数对象的介绍。

在构造函数中,除了使用这些参数文件初始化相机和SLAM系统,我们还会调用该类的rectify功能,计算出矫正相机图片的参数以及最重要的立体矫正中视差图到深度图映射矩阵。除此之外,绘图进程也是在该函数中被启动。构造函数代码如下:

scs::System::System(StereoMatching::Type algorithm, CameraFactory::Type cameraType, const string dir[3], const string name[2])
{
    matcher = StereoMatching::make(algorithm);
    for (int i = 0; i < 2; i++)
    {
        cam[i] = CameraFactory::make(cameraType);
        cam[i]->param.load(dir[i+1], name[i]);
        if (!cam[i]->open(i))
        {
            cerr << "CANNOT open camera " << i << endl;
            abort();
        }
    }

    // 需要考虑一些设置失败的情况.
    // TODO
    FileStorage fs(dir[0], FileStorage::READ);
    fs[
<think>好的,用户想了解如何从零开始实现ORB-SLAM算法,需要教程或代码解析。首先,我需要回忆ORB-SLAM的基本结构和关键组件。ORB-SLAM是一个基于特征点的视觉SLAM系统,主要包括特征提取、相机跟踪、局部建图、闭环检测等模块。 首先,用户可能需要了解ORB特征点的提取和匹配。这部分涉及到ORB算法本身,包括Oriented FAST关键点检测和BRIEF描述子。需要推荐相关的资源或教程,比如官方论文或者开源实现。 接下来是相机位姿估计,这涉及到对极几何和PnP问题。用户可能需要了解如何通过特征匹配计算基础矩阵或单应矩阵,然后使用RANSAC去除误匹配。参考引用中提到了八点法计算基础矩阵和卡方检验,这部分内容可能需要详细解释。 然后是局部地图构建和优化,这部分通常使用Bundle Adjustment(BA)来优化相机位姿和地图点的位置。可能需要介绍g2o或Ceres等优化库的使用方法,以及如何集成到系统中。 闭环检测和重定位也是ORB-SLAM的重要组成部分,涉及到词袋模型(Bag of Words)和场景识别。用户可能需要学习如何构建视觉词典,以及如何利用DBoW2库进行高效的回环检测。 另外,用户提到的引用[2]中的相机投影模型,涉及到相机内参矩阵K和相机外参[R|t]的相乘,这部分在实现相机投影和位姿估计时会用到。需要确保用户理解如何将三维点投影到图像平面,以及如何从匹配点中恢复相机运动。 考虑到用户希望从零开始实现,可能需要分步骤指导,比如先实现特征提取和匹配,再逐步添加跟踪、建图、闭环等模块。同时,推荐一些已有的开源项目作为参考,比如ORB-SLAM的官方代码,但用户可能需要更基础的教程。 可能还需要指出实现中的难点,比如多线程管理、实时性优化、数据关联的鲁棒性等。此外,测试数据集的选择和评估方法也是关键,比如使用TUM或KITTI数据集进行验证。 最后,生成相关问题时,需要覆盖算法原理、关键步骤、优化方法以及实际应用中的挑战,确保问题能帮助用户深入理解各个模块的实现细节。</think>### 从零实现 ORB-SLAM 的关键步骤与资源 #### 1. **理解 ORB-SLAM 核心组件** ORB-SLAM 包含以下核心模块: - **特征提取**:使用 ORB(Oriented FAST + Rotated BRIEF)算法检测关键点并生成描述子 - **相机跟踪**:通过特征匹配和运动估计(如 PnP)计算相机位姿[^2] - **局部建图**:通过局部 Bundle Adjustment 优化地图点和关键帧位姿 - **闭环检测**:基于词袋模型(Bag of Words)识别回环并优化全局地图 #### 2. **关键数学基础** - **相机投影模型**:理解引用[2]中的投影方程 $s \begin{bmatrix} u_i \\ v_i \\ 1 \end{bmatrix} = \boldsymbol{K} [\boldsymbol{R}|\boldsymbol{t}] \begin{bmatrix} x_i \\ y_i \\ z_i \\ 1 \end{bmatrix}$ - **对极几何**:利用八点法计算基础矩阵 $\boldsymbol{F}$(如引用[1]中的 `ComputeF21()`) - **非线性优化**:使用 g2o/Ceres 实现 Bundle Adjustment #### 3. **推荐学习资源** 1. **官方论文**: - [ORB-SLAM: A Versatile and Accurate Monocular SLAM System](https://arxiv.org/abs/1502.00956) - 包含算法框架和数学推导 2. **代码解析参考**: - [ORB-SLAM3 官方代码](https://github.com/UZ-SLAMLab/ORB_SLAM3) - 关键函数示例(特征点匹配): ```cpp void ORBmatcher::SearchByProjection(Frame &F, const vector<MapPoint*> &vpMapPoints) ``` 3. **实践教程**: - [SLAM 十四讲](https://github.com/gaoxiang12/slambook2)(高翔著) - 包含特征匹配、BA 优化等实现示例 #### 4. **实现路线图** 1. **环境搭建**:安装 OpenCV、Eigen、Pangolin、DBoW2 等依赖库 2. **特征子系统**: - 实现 ORB 特征提取(`cv::ORB`) - 构建词袋模型(使用 DBoW3 库) 3. **跟踪线程**: - 特征匹配(暴力匹配/FLANN) - 运动估计(PnP + RANSAC) 4. **建图线程**: - 三角化地图点(线性三角化) - 局部 BA 优化(g2o 实现) #### 5. **调试与优化技巧** - 使用 TUM 数据集验证轨迹精度 - 添加卡方检验(如引用[1]的 `CheckFundamental()`)过滤误匹配 - 多线程同步管理(关键帧队列、地图更新锁)
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值