SLAM学习——建图问题(一)

本文探讨了在SLAM(Simultaneous Localization and Mapping)中构建稠密地图的方法,重点关注单目的实现。通过特征点匹配和三角测量估计像素深度,结合极线搜索和块匹配技术来解决匹配问题。最终,通过不断迭代更新,得到稠密深度地图。

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

1.单目稠密地图的构建

在上述中,我们讨论的是稀疏地图的构建,但是在实际的定位、导航和壁障过程中,我们需要有稠密地图。常见的单目稠密地图的构建思路有:
1.单目:通过运动,得出运动轨迹,计算出运动的关系,通过三角测量计算出像素深度。(同下)
2.双目:利用俩个相机的视差计算出像素的深度。(吃力不讨好,但是大型场合可能有比较好的效果。)
3.RGBD:自带深度图,可直接得到像素的深度。(比较好,但是不适合大型场合)

对于单目而言,即我们提到的第一种方法,通过单目建立稠密地图:
1.提取特征点,然后在很多图像中,进行特征点的匹配,跟踪特征点在各张图像的轨迹(经常用ORB特征提取)
2.然后通过三角测量估计每一个像素的深度。在这里,我们需要利用很多的三角测量使得某点的深度进行收敛,得到确切的深度信息。

在稠密深度地图中,无法对每个像素计算其描述子,所以在稠密估计问题中,匹配成为很重要的一环,我们用到了极线搜索和块匹配技术,极线搜索的原理如下图所示:

这里写图片描述

而块匹配技术就相当于把像素的比较换成了块的比较,我们直接上代码可得:

#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
#include <boost/timer.hpp>

// for sophus
#include <sophus/se3.h> //这里使用了sophus这个工具,使用SE3
using Sophus::SE3;

// for eigen
#include <Eigen/Core>
#include <Eigen/Geometry>
using namespace Eigen;

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace cv;
// ------------------------------------------------------------------
// parameters
const int boarder = 20;     // 边缘宽度
const int width = 640;      // 宽度
const int height = 480;     // 高度
const double fx = 481.2f;   // 相机内参
const double fy = -480.0f;
const double cx = 319.5f;
const double cy = 239.5f;
const int ncc_window_size = 2;  // NCC 取的窗口半宽度
const int ncc_area = (2*ncc_window_size+1)*(2*ncc_window_size+1); // NCC窗口面积
const double min_cov = 0.1; // 收敛判定:最小方差
const double max_cov = 10;  // 发散判定:最大方差

// ------------------------------------------------------------------
// 重要的函数
// 从 REMODE 数据集读取数据
bool readDatasetFiles(
    const string& path,
    vector<string>& color_image_files,
    vector<SE3>& poses
);
// 根据新的图像更新深度估计
bool update(
    const Mat& ref,
    const Mat& curr,
    const SE3& T_C_R,
    Mat& depth,
    Mat& depth_cov
);
// 极线搜索
bool epipolarSearch(
    const Mat& ref,
    const Mat& curr,
    const SE3& T_C_R,
    const Vector2d& pt_ref,
    const double& depth_mu,
    const double& depth_cov,
    Vector2d& pt_curr
);
// 更新深度滤波器
bool updateDepthFilter(
    const Vector2d& pt_ref,
    const Vector2d& pt_curr,
    const SE3& T_C_R,
    Mat& depth,
    Mat& depth_cov
);
// 计算 NCC 评分
double NCC( const Mat& ref, const Mat& curr, const Vector2d& pt_ref, const Vector2d& pt_curr );
// 双线性灰度插值
inline
### ORB SLAM3 联合教程和实现方法 ORB SLAM3 是种先进的多传感器融合SLAM系统,支持单目、双目、RGB-D相机以及IMU等多种输入设备。为了实现实时定位与地功能,该框架采用了多种优化策略和技术。 #### 初始化阶段 在纯视觉单目SLAM模式下,通过运动恢复结构(SfM)完成初始地[^4]。此过程会以较高频率插入关键帧,由于这些关键帧间时间间隔较短,使得基于IMU数据的预积分计算更加精确可靠。最终形成个包含约十个关键帧位置姿态及数百个特征点的地模型。值得注意的是,在这阶段所获得的地比例尺尚未确定。 #### 多线程架构下的局部流程 局部主要负责管理和优化当前活动区域内的三维几何关系。具体来说: - **关键帧管理**:当新像到来时,如果满足定条件,则将其作为新的关键帧加入到现有地中; - **地点维护**:对于每个被选为关键帧的画面,从中提取出足够数量的兴趣点,并尝试将它们三角化成世界坐标系中的真实空间点; - **闭环检测**:定期执行回环闭合操作来修正累积漂移误差; 上述工作是在独立于跟踪主线程之外的个专门子进程中完成的,从而保证了系统的实时性能[^2]。 #### 点云映射模块 针对稠密重需求,ORB SLAM3引入了个额外的任务——`PointCloudMapping`实例。这个组件不仅能够接收来自前端处理单元传递过来的关键帧信息,而且还可以启动专用绘进程(`viewerThread`)用于直观展示整个环境的空间布局情况[^3]。 #### 实现联合的具体步骤 要使不同类型的感知装置协同作业,需遵循如下原则: 1. 对每种模态的数据流分别立对应的处理器对象(如MonoInertialProcessor),并将各自获取的信息同步馈送到中央控制器处统调度; 2. 利用共视性约束机制寻找跨源观测间的对应关联,进而立起全局致性的拓扑连接网络; 3. 借助因子表示法表达各节点之间的相对变换参数及其不确定度分布特性,再借助非线性最小二乘求解器进行整体最优估计; 4. 完整运行次大规模束调整算法(Global BA),期间暂停切增量式的更新动作直至收敛结束为止[^5]。 ```cpp // 创并配置各类Sensor Processor... std::shared_ptr<SensorProcessor> monoProc(new MonoInertialProcessor()); monoProc->SetCalibration(calibFile); // 启动后台服务... mpSystem = new System(vocFile, settings); mpSystem->Start(); while (!bShutdown){ // 获取最新测量样本... cv::Mat img = GrabImage(); // 将其提交给相应处理器... mpSystem->Track(img); } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值