ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于RGBD相机的视觉SLAM:从原理到实践实现三维重建与定位

基于RGBD相机的视觉SLAM:从原理到实践实现三维重建与定位 简介本资源是一套面向计算机视觉初学者与机器人方向开发者的RGB-D视觉里程计实践项目聚焦深度相机位姿估计、三维重建及SLAM基础流程适用于机器人自主导航、室内外环境建图与实时轨迹追踪等典型场景。压缩包共17个文件含4个核心C实现main.cpp等、3个Python工具脚本如数据集关联与下载、3个头文件hpp支撑模块化设计以及说明文档txt、技术概览PDF、README与LICENSE等整体仅218KB轻量易部署。已有121人学习下载适合希望从零理解RGB-D Odometry原理并动手复现关键环节的学习者。资源提供完整OpenCV实现框架涵盖点云配准、帧间位姿优化、多传感器数据融合思路及典型误差分析提示目录结构清晰分层include/src/tools便于按模块研读源码与调试验证。1. 项目概述从RGBD图像到三维世界的理解与重建最近在整理一个老项目是关于用RGBD相机做视觉里程计和三维重建的。这个项目最初是为了给一个室内移动机器人做自主导航系统而开发的核心目标就是让机器人只靠一个深度相机就能一边走一边知道自己在哪里同时把周围的环境给建出来。听起来是不是有点像我们手机上的AR应用原理上确实有相通之处但机器人对精度和实时性的要求要高得多毕竟它得靠这个“地图”来规划路径、避开障碍不能有半点马虎。这个项目完整地走了一遍视觉SLAMSimultaneous Localization and Mapping即时定位与地图构建的经典流程。简单来说SLAM就是解决“我在哪”和“周围是什么”这两个问题的。我们用的“眼睛”是RGBD相机比如Intel RealSense或者微软的Kinect它能同时提供彩色RGB图像和每个像素对应的深度D信息。有了深度我们就不用像传统单目视觉那样费劲地去猜物体的远近可以直接得到三维点云这大大简化了后续的位姿估计和地图构建。整个系统我用C和OpenCV库搭了起来涉及从图像预处理、特征提取与匹配、位姿估计、点云配准与优化到最终的地图构建和轨迹输出。下面我就把这个项目的核心思路、实现细节以及过程中踩过的坑和积累的经验系统地梳理一遍无论你是刚接触SLAM的学生还是想在实际项目中应用相关技术的工程师希望都能有所收获。2. 核心思路与系统架构设计2.1 为什么选择RGBD视觉里程计在机器人或者AR/VR领域知道自身的运动轨迹里程计是第一步。实现里程计的方法很多比如轮式编码器容易打滑、惯性测量单元IMU有漂移、激光雷达昂贵。视觉里程计Visual Odometry, VO的优势在于它被动感知、信息丰富、成本相对较低。而RGBD视觉里程计在单目VO和双目VO之间取得了很好的平衡。单目VO最大的问题是尺度不确定性因为它无法从单张图片中获得绝对深度。虽然可以通过三角化或者运动恢复结构SfM来估计深度但过程复杂初始化麻烦而且容易产生漂移。双目VO通过两个相机视差计算深度尺度是确定的但计算量大且依赖良好的特征匹配。RGBD相机直接提供了配准好的深度图相当于“开了挂”我们直接有了每个像素的三维坐标。这使得位姿估计变得非常直接和稳定尤其是在纹理较少的区域深度信息提供了至关重要的几何约束。当然RGBD相机也有其局限比如测量范围有限通常几米内效果最好、对光照和反射表面敏感、室外强光下可能失效。因此这个项目主要针对室内或结构化的室外环境。2.2 整体系统流程拆解我们的系统是一个典型的“前端-后端”架构这也是现代SLAM系统的标准范式。传感器数据输入系统从RGBD相机按帧读取彩色图像和深度图像。这里需要注意深度图像和彩色图像的时间同步与空间对齐通常相机出厂已校准好但使用前仍需验证。前端视觉里程计图像预处理对RGB图像进行去噪、直方图均衡化等操作提升特征质量。对深度图进行滤波去除无效值如0值或超大值和噪声。特征提取与匹配从连续两帧RGB图像中提取特征点如ORB, SIFT。然后根据描述子进行特征匹配找到两帧图像中对应的点。位姿估计利用匹配好的特征点对结合深度图提供的三维坐标通过求解一个3D-3D或3D-2D的变换问题计算出相机从上一帧到当前帧的运动旋转矩阵R和平移向量t。这就是视觉里程计的核心输出。后端优化与闭环检测局部优化仅仅依靠相邻两帧的位姿估计会累积误差。因此我们需要维护一个局部地图或关键帧集合通过图优化例如g2o, GTSAM库对一段时间内的相机位姿进行联合优化得到更一致的轨迹。闭环检测当机器人回到曾经到过的地方时系统需要能够识别出来。这通常通过词袋模型Bag of Words比较当前帧与历史关键帧的视觉外观来实现。一旦检测到闭环就会引入一个很强的位姿约束后端优化会利用这个约束大幅修正累积的漂移误差这是保证SLAM系统长期运行精度的关键。地图构建利用优化后的相机位姿将每一帧深度图转换成的点云变换到同一个世界坐标系下拼接起来就形成了稠密或半稠密的三维环境地图。这个地图可以用于机器人的路径规划、障碍物避让等任务。整个流程中前端追求速度与稳健后端追求精度与一致。我们的项目重点实现了前端的RGBD视觉里程计和后端的简单点云地图构建并预留了接入更复杂优化和闭环检测的接口。3. 环境搭建与核心工具链选型3.1 硬件与驱动准备工欲善其事必先利其器。首先得搞定硬件。我项目里主要用的是Intel RealSense D435i它除了RGBD还自带IMU可以做多传感器融合虽然我们这个版本没深入用IMU。选择它的原因是开源驱动和SDK支持好社区活跃。安装RealSense SDK 2.0 (librealsense)这是必须的。在Ubuntu上可以从源码编译安装这样能获得最新的功能和稳定性。编译时记得打开CUDA支持如果你有NVIDIA显卡这样一些深度处理算法可以GPU加速。# 示例性的安装步骤摘要 git clone https://github.com/IntelRealSense/librealsense.git cd librealsense mkdir build cd build cmake .. -DBUILD_EXAMPLEStrue -DCMAKE_BUILD_TYPERelease make -j$(nproc) sudo make install安装后插上相机运行realsense-viewer可以直观地检查数据流是否正常并调整深度图的质量如激光器功率、深度精度模式等。注意深度相机的标定非常重要。虽然出厂有标定但在长时间使用或磕碰后RGB和Depth传感器之间的外参变换关系可能会微变。librealsense提供了校准工具但对于高精度要求可能需要用棋盘格进行重新标定获取更准确的内参焦距、主点和外参矩阵。3.2 软件依赖与OpenCV配置核心的视觉处理库是OpenCV。我们需要的不仅是基础的图像处理模块还有特征提取、相机标定、点云处理相关的模块。安装OpenCV with Contrib ModulesOpenCV主库不包含一些最新的特征如SIFT, SURF在主库中已移至专利保护模块但仍在contrib中和SFM模块。建议从源码编译OpenCV OpenCV_contrib。# 下载OpenCV和contrib源码 git clone https://github.com/opencv/opencv.git git clone https://github.com/opencv/opencv_contrib.git # 创建构建目录并配置 cd opencv mkdir build cd build cmake -D CMAKE_BUILD_TYPERELEASE \ -D CMAKE_INSTALL_PREFIX/usr/local \ -D OPENCV_EXTRA_MODULES_PATH../../opencv_contrib/modules \ -D WITH_CUDAON \ # 如果使用CUDA -D BUILD_EXAMPLESOFF .. make -j$(nproc) sudo make install编译时间较长请耐心等待。安装后可以在C项目中通过find_package(OpenCV REQUIRED)来链接。点云处理库PCL (Point Cloud Library)虽然OpenCV有一些基本的点云支持但PCL是专门为点云处理设计的强大库用于滤波、配准、可视化等非常方便。同样建议从源码编译安装。sudo apt-get install libpcl-dev # 或者从源码编译最新版优化库可选但推荐对于后端优化可以预先安装好g2o或Ceres Solver。我们项目初期为了简化自己实现了简单的位姿图优化但用这些成熟的库会更稳健高效。3.3 项目工程结构设计一个清晰的代码结构能让开发和调试事半功倍。我的项目目录大致如下rgbd_vo_slam/ ├── CMakeLists.txt ├── include/ # 头文件 │ ├── camera.h # 相机模型、内参类 │ ├── frame.h # 帧类存储图像、特征、点云 │ ├── visual_odometry.h # 视觉里程计核心类 │ ├── map.h # 地图管理类 │ └── config.h # 参数配置文件 ├── src/ # 源文件 │ ├── camera.cpp │ ├── frame.cpp │ ├── visual_odometry.cpp │ ├── map.cpp │ └── main.cpp # 主程序入口 ├── data/ # 存放测试数据集如TUM RGB-D └── config/ # 配置文件.yaml使用CMake管理项目便于跨平台编译。将参数如特征数量、匹配阈值、相机内参写在YAML配置文件中这样不用重新编译就能调整系统行为非常方便调试。4. 核心算法实现从图像到位姿4.1 帧数据封装与预处理每一帧数据都是一个Frame对象它封装了时间戳、RGB图像、深度图以及从它们衍生出的信息。深度图的有效性检查与转换从相机获取的深度图通常是16位无符号整数单位是毫米。我们需要将其转换为以米为单位的浮点数深度值同时过滤掉无效数据深度值为0表示测距失败。// 伪代码示例 cv::Mat depth_raw ...; // 16UC1, 单位mm cv::Mat depth_meters(depth_raw.size(), CV_32FC1); for (int v 0; v depth_raw.rows; v) { for (int u 0; u depth_raw.cols; u) { unsigned short d depth_raw.atunsigned short(v, u); if (d 0) { depth_meters.atfloat(v, u) 0.0; // 无效点 } else { depth_meters.atfloat(v, u) d / 1000.0; // 转换为米 } } } // 使用中值滤波或双边滤波去除深度图的噪声 cv::medianBlur(depth_meters, depth_meters, 5);生成彩色点云利用相机内参可以将深度图反投影成三维点云。对于每个有效的像素点(u, v, d)其对应的三维点P(x, y, z)在相机坐标系下的计算公式为z d x (u - cx) * z / fx y (v - cy) * z / fy其中fx, fy是焦距cx, cy是光心。这个点云将用于后续的位姿估计。4.2 特征提取与匹配策略特征点是视觉里程计的“路标”。我们选择ORB特征因为它在速度和旋转/光照不变性之间取得了很好的平衡而且OpenCV对其有高度优化。提取ORB特征在RGB图像上提取。cv::Ptrcv::ORB orb cv::ORB::create(1000); // 设定提取的特征点数量 std::vectorcv::KeyPoint keypoints; cv::Mat descriptors; orb-detectAndCompute(rgb_image, cv::Mat(), keypoints, descriptors);这里有一个技巧可以结合深度信息只在前景物体深度值合理上提取特征避免在遥远的、深度不可靠的背景或墙壁上提取过多无用的特征。特征匹配使用汉明距离进行描述子匹配。OpenCV提供了BFMatcher暴力匹配和FlannBasedMatcher近似最近邻更快。cv::Ptrcv::DescriptorMatcher matcher cv::DescriptorMatcher::create(BruteForce-Hamming); std::vectorcv::DMatch raw_matches; matcher-match(descriptors_prev, descriptors_curr, raw_matches);得到的初始匹配包含很多错误外点。必须进行筛选。匹配点筛选与三维坐标关联距离比测试对于每个查询点计算其与最近邻和次近邻描述子的距离之比。如果这个比值小于一个阈值如0.8则认为匹配是好的。这是Lowes ratio test能有效剔除模糊匹配。交叉验证将当前帧与上一帧匹配再将上一帧与当前帧匹配只保留双向一致的匹配对。深度值检查确保匹配点对在两个帧中都有有效的深度值。三维坐标计算通过筛选后的像素坐标和对应的深度值计算出匹配点在上一帧相机坐标系下的3D坐标P_prev和当前帧下的3D坐标P_curr。现在我们得到了一个3D-3D的对应点集。4.3 基于SVD的3D-3D位姿估计ICP变种有了两组对应的3D点集{P_prev}和{P_curr}我们可以用迭代最近点ICP的思想来求解位姿变换。这里我们采用闭式解SVD分解它比迭代的ICP更快适用于运动较小、匹配较好的情况。目标是找到一个旋转矩阵R和平移向量t使得误差最小min ∑ || (R * P_prev_i t) - P_curr_i ||^2。求解步骤Umeyama算法去中心化计算两个点集的质心然后让每个点减去质心得到去中心化的点集。centroid_prev mean(P_prev), centroid_curr mean(P_curr) Q_prev_i P_prev_i - centroid_prev Q_curr_i P_curr_i - centroid_curr计算协方差矩阵H ∑ (Q_prev_i * Q_curr_i^T)SVD分解对H进行SVD分解H U * Σ * V^T计算旋转和平移R V * U^T // 确保R是右手系的旋转矩阵det(R) 1如果det(R) -1需要特殊处理 t centroid_curr - R * centroid_prev这样就得到了从上一帧到当前帧的相机运动T_prev_curr [R | t]。实操心得这个SVD方法非常高效但前提是匹配点对的质量要高且没有严重的误匹配。在实际应用中直接使用所有匹配点计算出的R, t可能仍然不准确因为误匹配外点的存在会严重影响SVD的结果。因此必须结合鲁棒估计方法如RANSAC随机采样一致性。RANSAC的基本思想是随机选取最小样本集3个点对计算一个位姿假设然后用这个假设去测试所有点对统计内点误差小于阈值的点的数量。重复这个过程很多次选择内点数量最多的那个位姿假设最后用所有内点重新计算一个更精确的位姿。OpenCV的solvePnPRansac函数就是干这个的针对3D-2D问题。对于我们的3D-3D问题可以自己实现一个基于SVD的RANSAC循环或者使用PCL中的SampleConsensusPrerejective等配准算法它们内置了鲁棒估计。4.4 运动变换的累积与轨迹生成得到了每一帧相对于上一帧的增量运动T_i_i1后我们需要将其累积到世界坐标系下得到相机在世界坐标系下的位姿T_w_i。假设第一帧为世界坐标系原点T_w_0 单位矩阵那么对于第k帧T_w_k T_w_0 * T_0_1 * T_1_2 * ... * T_{k-1}_k这里T_a_b表示从坐标系b到坐标系a的变换。注意矩阵乘法的顺序。累积的位姿序列{T_w_0, T_w_1, ..., T_w_n}就是视觉里程计估计出的相机运动轨迹。5. 点云地图构建与可视化5.1 点云拼接原理有了每一帧的相机位姿T_w_i和该帧对应的点云P_i在相机坐标系下我们可以将所有点云变换到世界坐标系下并拼接起来形成全局地图。 对于第i帧点云中的每一个点p_cam其世界坐标为p_world T_w_i * p_cam将所有帧变换后的点云添加到一个大的点云对象中就完成了初步的拼接。5.2 使用PCL进行点云处理与显示PCL库极大地简化了这部分工作。创建与合并点云#include pcl/point_cloud.h #include pcl/point_types.h #include pcl/common/transforms.h typedef pcl::PointXYZRGB PointT; // 带颜色的点类型 typedef pcl::PointCloudPointT PointCloudT; // 假设 frame.point_cloud 是当前帧的彩色点云相机坐标系 PointCloudT::Ptr cloud_cam(new PointCloudT); // ... 将cv::Mat格式的点云数据转换为pcl格式填入cloud_cam ... // 变换到世界坐标系 PointCloudT::Ptr cloud_world(new PointCloudT); Eigen::Matrix4f T_w_cam ...; // 从cv::Mat转换到Eigen::Matrix4f pcl::transformPointCloud(*cloud_cam, *cloud_world, T_w_cam); // 合并到全局地图 *global_map *cloud_world;点云滤波直接拼接的点云数据量巨大且包含大量噪声和离群点。需要进行下采样和滤波。体素网格滤波在三维空间创建均匀的小立方体体素用每个体素内所有点的重心来代表该体素。这能在保持形状的同时大幅减少点数量。pcl::VoxelGridPointT voxel_filter; voxel_filter.setLeafSize(0.01f, 0.01f, 0.01f); // 设置体素边长1cm voxel_filter.setInputCloud(global_map); voxel_filter.filter(*global_map_filtered);统计离群点去除分析每个点到其K个最近邻距离的分布移除距离均值过大的点噪声。pcl::StatisticalOutlierRemovalPointT sor_filter; sor_filter.setInputCloud(global_map_filtered); sor_filter.setMeanK(50); // 考察的邻域点数 sor_filter.setStddevMulThresh(1.0); // 标准差倍数阈值 sor_filter.filter(*global_map_clean);点云可视化PCL提供了简单的可视化工具方便调试。#include pcl/visualization/cloud_viewer.h pcl::visualization::PCLVisualizer viewer(3D Map Viewer); viewer.addPointCloud(global_map_clean, global_map); while (!viewer.wasStopped()) { viewer.spinOnce(100); }5.3 地图的存储与重用对于大型场景点云地图可能包含数百万甚至上千万个点全部放在内存中不现实。需要考虑增量式构建和外部存储。八叉树地图一种高效压缩和存储三维空间的数据结构。它递归地将空间划分为八个子立方体只存储被占据的体素。PCL提供了pcl::octree模块。八叉树地图不仅节省内存还便于进行碰撞检测、空间查询等操作。子地图将整个环境划分为多个子地图。当机器人离开一个子地图区域时可以将其压缩保存到磁盘只保留活跃的子地图在内存中。文件格式常用的点云存储格式有.pcd(PCL原生格式)、.ply、.obj等。PCL可以方便地读写这些格式。6. 系统集成、调试与性能优化实战6.1 主程序循环与数据流管理主程序的核心是一个循环不断从相机抓取新帧然后调用视觉里程计模块处理。int main() { // 1. 初始化相机、视觉里程计VO、地图 Camera cam; VisualOdometry vo(config); Map map; while (true) { // 2. 获取新帧 Frame::Ptr new_frame cam.grabFrame(); if (new_frame nullptr) break; // 3. 视觉里程计处理 bool success vo.addFrame(new_frame); if (!success) { LOG(WARNING) VO lost tracking!; // 处理跟踪丢失例如尝试重定位 continue; } // 4. 获取当前帧位姿世界坐标系 Sophus::SE3d T_w_c vo.getCurrentPose(); // 使用李群表示位姿更佳 // 5. 将当前帧点云加入地图 map.insertFrame(new_frame, T_w_c); // 6. 可选可视化显示轨迹、当前帧、地图 visualize(new_frame, vo.getTrajectory(), map.getGlobalMap()); // 7. 检查退出条件 if (stopSignalReceived()) break; } // 8. 保存轨迹和地图 saveTrajectory(vo.getTrajectory(), trajectory.txt); map.save(global_map.pcd); return 0; }这里需要注意线程安全。图像采集、VO计算、地图更新、可视化如果放在同一个线程可能会因为某些步骤如点云滤波耗时导致帧率下降。可以考虑使用生产者-消费者模型将采集、处理、显示放在不同线程用队列传递数据。6.2 关键参数调试经验系统性能很大程度上依赖于参数调优。以下是一些关键参数及其影响参数模块参数名典型值/范围影响与调试心得特征提取ORB特征数量500-2000数量太少匹配点不足容易丢失数量太多计算耗时增加。室内场景1000左右通常足够。可以动态调整在纹理丰富区域少提贫乏区域多提。特征匹配Lowe‘s Ratio Test 阈值0.6-0.8值越小匹配越严格内点率越高但可能过滤掉一些正确匹配。通常从0.75开始调试。RANSAC迭代次数1000-5000次数越多找到正确模型的概率越高但耗时增加。可以根据内点比例动态估算所需次数。内点距离阈值0.01-0.05 (米)判断一个点对是否支持当前位姿假设的阈值。取决于深度噪声和匹配精度。通常设为深度测量噪声的2-3倍。深度滤波中值滤波核大小3, 5, 7去除深度图的椒盐噪声。核越大越平滑但边缘越模糊。通常5x5是一个不错的起点。点云地图体素滤波叶子大小0.01-0.05 (米)控制地图的稠密程度和内存占用。1cm的叶子能保留大量细节5cm则非常稀疏。根据应用需求权衡。调试流程建议先用数据集跑通强烈建议使用公开数据集如著名的TUM RGB-D数据集进行初始开发和调试。数据集提供了真值轨迹可以定量评估误差。可视化中间结果实时显示特征点、匹配连线、估计的轨迹与真值对比。这能帮你快速定位问题是出在特征提取、匹配还是位姿估计上。逐模块验证先确保特征提取和匹配看起来是合理的然后单独测试位姿估计算法用已知的变换验证SVDRANSAC是否正确最后再整合。记录与分析日志记录每一帧的处理时间、匹配点数量、RANSAC内点数量、估计的平移和旋转量。如果某帧突然出现异常值如旋转角度巨大很可能这一帧跟踪失败了。6.3 常见问题与故障排查在实际运行中你肯定会遇到各种问题。下面是一些典型情况及其应对思路问题VO跟踪突然丢失轨迹跳变。可能原因1特征匹配质量骤降。场景纹理缺失如白墙、剧烈光照变化、快速运动导致模糊。排查查看当前帧提取的特征点数量和分布。如果特征点很少或集中在很小区域就需要改进特征提取策略如使用自适应阈值或结合边缘特征。解决引入更鲁棒的特征如SIFT速度慢或学习得到的特征。或者在纹理缺失时短暂依赖其他传感器如IMU进行运动预测。问题估计的轨迹整体发生漂移尤其是旋转漂移明显。可能原因累积误差。这是纯VO的固有缺陷没有闭环检测和全局优化误差会随着路径增长而累积。解决这是引入后端优化和闭环检测的强烈信号。需要实现或集成一个图优化后端如g2o并添加基于视觉词袋的闭环检测模块。一旦检测到闭环优化器会大幅修正漂移。问题深度图有大片空洞或噪声导致反投影的点云错误。可能原因相机对物体材质如玻璃、镜面、纯黑物体、光照条件强光、黑暗敏感。解决加强深度图预处理滤波。可以考虑使用RGB信息辅助例如利用彩色图像的边缘信息来引导深度图的修复图像修复算法。或者在点云拼接后进行更严格的空间滤波和离群点去除。问题系统运行速度慢无法达到实时如30Hz。瓶颈分析使用性能分析工具如gprof, Valgrind找出热点。通常是特征提取/匹配或点云处理部分。优化特征降低ORB特征数量在图像金字塔上层进行提取使用FAST角点 BRIEF描述子的组合可能比ORB更快。匹配使用FLANN匹配器而非暴力匹配对描述子进行PCA降维。点云不是每一帧都加入全局地图并滤波。可以每隔几帧加入一个关键帧。对点云的操作如体素滤波可以放到独立线程。代码级启用编译器优化-O2, -O3对关键循环使用SIMD指令或并行化OpenMP考虑将部分算法如光流、图像金字塔移植到GPU上计算。问题在大型场景中内存占用爆炸。解决必须使用增量式地图。采用八叉树结构存储地图实现子地图管理将非活跃区域交换到磁盘。7. 进阶方向与项目扩展思考实现一个基础的RGBD视觉里程计和地图构建系统只是一个起点。要让其真正成为一个鲁棒、可用的SLAM系统还有很多可以深入和改进的地方引入后端优化与闭环检测如前所述这是消除累积误差的关键。可以集成DBoW2库进行词袋模型闭环检测集成g2o或GTSAM进行位姿图优化。这会将系统从VO升级为一个完整的SLAM系统。多传感器融合RGBD相机在快速运动或弱纹理环境下容易失效。融合IMU数据可以提供高频的角速度和加速度测量弥补视觉的不足特别是在初始化、快速旋转和尺度估计方面。这就是视觉惯性里程计VIO例如著名的OKVIS、VINS-Mono等算法。稠密/半稠密建图我们目前构建的是基于特征点的稀疏地图。对于导航和避障稠密地图更有用。可以考虑使用KinectFusion系列的算法直接基于深度图进行稠密表面重建得到带纹理的网格模型。使用更现代的深度学习特征传统的手工特征如ORB, SIFT在极端条件下可能不稳定。可以尝试用深度学习提取的特征如SuperPoint和匹配器如SuperGlue, LoFTR它们对光照、视角变化具有更强的鲁棒性不过会牺牲一些速度。系统移植与部署将算法从开发机如高性能PC移植到嵌入式平台如Jetson AGX Orin, Raspberry Pi Intel RealSense上需要考虑计算资源的限制进行模型简化、算法裁剪和定点化等优化。这个项目就像搭积木基础模块VO搭建好后你可以根据具体应用需求选择性地添加优化、闭环、融合等高级模块。每一步的深入都能让你对SLAM这个迷人的领域有更深刻的理解。我自己的体会是动手实现一遍哪怕是最简单的版本也比读十篇论文收获更大。过程中遇到的每一个报错、每一次调试都是宝贵的经验。最后别忘了用公开数据集定量评估你的系统比如计算绝对轨迹误差ATE和相对位姿误差RPE这是衡量算法性能的客观标准。本文还有配套的精品资源点击获取
返回列表