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

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

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 double getBilinearInterpolatedValue( const Mat
### SLAM技术原理 SLAM(Simultaneous Localization and Mapping),即同步定位与地,是种让移动机器人在未知环境中运动时能够边创边更新自身位置的技术。对于基于TurtleBot3平台的SLAM应用而言,在启动过程中通过指定`gmapping`作为算法来完成这过程[^1]。 具体来说,当执行命令`export TURTLEBOT3_MODEL=waffle_pi roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping`之后,系统会利用激光雷达数据并结合里程计信息来进行环境感知和自我定位估计。随着机器人的不断探索,逐渐形成张完整的二维栅格地。 ### 实现方法概述 为了更好地理解如何实现SLAM,可以从以下几个方面入手: #### 数据采集 通常情况下,SLAM依赖于传感器获取周围环境的信息。常见的传感器包括但不限于激光测距仪(LIDAR),摄像头等光学设备以及惯性测量单元(IMU)[^2]。这些传感器提供了关于外部世界的观测值,构成了后续处理的基础。 #### 特征提取与匹配 针对不同类型的输入源,需要采用相应的特征检测算法识别出具有代表性的地标或者结构化元素。例如,在视觉SLAM中可能会运用SIFT、SURF这样的像特征描述子;而在Lidar SLAM里,则更多涉及到线段、平面之类的几何特性分析[^2]。 #### 同步优化 由于存在不可避免的各种误差累积效应,因此必须定期调整姿态参数以保持全局致性。这步骤往往借助非线性最小二乘法或者其他先进的数值求解策略来最小化预测轨迹同实际观察之间的差异。 #### 地表达形式 根据应用场景的不同可以选择适合的地表示方式。比如前述提到过的稠密重更适合那些追求精细度的任务场合,而稀疏模型则更侧重效率考量,适用于快速路径规划等领域。 ```bash # 开启SLAM功能, 使用gmapping算法进行 export TURTLEBOT3_MODEL=waffle_pi roslaunch turtlebot3_slam turtlebot3_slam.launch slam_methods:=gmapping ``` 除了上述介绍外,《机器人SLAM导航核心技术与实战》书也详细讲述了有关google-cartographer在内的多种主流框架及其实践案例,可供进学习参考[^3]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值