ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

ORB-SLAM3与Euroc数据集实战:从环境配置到精度评估全流程指南

ORB-SLAM3与Euroc数据集实战:从环境配置到精度评估全流程指南 做视觉SLAM的同学十有八九都绕不开ORB-SLAM3这个名字而Euroc数据集基本算得上是跑SLAM算法绕不开的“标准考卷”。刚接触ORB-SLAM3那会儿我一度以为下载源码、编个build.sh就能顺利跑出轨迹结果光是在环境配置和数据准备上就折腾了两天。这期间踩过的坑、搜过的帖子、翻过的Issue汇总起来其实比官方Readme里写的那几行命令值钱得多。这篇文章就围绕“ORB-SLAM3的Euroc数据集测试”这条主线把从源码准备、依赖安装、数据集下载到单目、双目、双目惯性三种模式跑通再到用evo评估精度的完整流程全部拆开揉碎讲一遍。不管你是刚入门的SLAM萌新还是想快速用ORB-SLAM3做对比实验的研究党都能从这里找到可以直接照抄的操作步骤和避坑方案。1. 项目解读为什么用ORB-SLAM3跑Euroc是入门必修课1.1 ORB-SLAM3到底是个什么东西ORB-SLAM3是西班牙萨拉戈萨大学University of Zaragoza的Tardos团队在2020年前后开源的一套视觉SLAM系统。它最大的特点是一个系统通吃单目、双目、RGB-D三种传感器模式并且可以无缝切换视觉与视觉惯性VI两种工作方式。相比ORB-SLAM2它加入了基于多子地图Multi-Map的视觉惯性紧耦合、基于最大后验概率MAP的IMU初始化以及场景重识别和后端图优化的全套闭环机制。通俗点讲ORB-SLAM2更像是一个只能帮你在“连续运动”中定位建图的工具一旦跟踪丢失就得重新来ORB-SLAM3则多了一套“记忆”系统能识别出之前来过的地方并把多个子地图合并成一个完整轨迹。这个特性在多楼层、往返运动、长时间大范围场景里优势非常明显。也正因为这套架构的通用性强ORB-SLAM3在学术界和工业界都被广泛用来做算法对比的baseline。1.2 为什么偏偏选Euroc数据集来验证Euroc数据集EuRoC MAV Dataset是苏黎世联邦理工ETH发布的一组无人机MAV视觉惯性数据集采集设备是双目相机加MEMS IMU场景是室内厂房和室外小范围环境。它提供同步好的双目图像流、IMU采样数据还有运动捕捉系统提供的6自由度真值轨迹ground truth。对于SLAM算法评测来说它有三个不可替代的优势。一是传感器配置主流双目加IMU恰好匹配ORB-SLAM3最引以为傲的视觉惯性紧耦合能力。二是数据采集时包含了快速旋转、剧烈抖动、光照变化、低纹理墙面等真实挑战能充分暴露算法的弱点。三是真值精度高由Vicon运动捕捉系统提供精度在毫米到厘米级拿来做量化误差分析非常可靠。相比之下TUM RGB-D数据集某些序列没有IMU真值KITTI偏向车载场景Euroc则是室内小型无人机场景里最标准、最容易复现的评测集。1.3 这套组合能解决什么问题把ORB-SLAM3和Euroc放到一起本质上是做一次完整的算法验证闭环。对新手来说跑通这个流程意味着你理解了SLAM系统的运行流程图像输入、特征提取与匹配、初始化、局部建图、回环检测、图优化以及视觉和IMU数据怎么融合。对做研究的人来说Euroc给了你一个公平的擂台你可以对比不同模式、不同序列下的ATE绝对轨迹误差和RPE相对位姿误差用数据说话。我在实际测试中最大的体会是Euroc虽然只有11个短序列但每个序列的难度层次分明从MH01到MH05、V1、V2系列覆盖了从平坦缓慢到剧烈快速的各种运动梯度。跑完这套流程你对ORB-SLAM3的参数感知、传感器标定理解都会比单纯看论文深刻得多。2. 环境准备与源码编译实录2.1 依赖库版本选择与安装细节在动手编译ORB-SLAM3之前先把环境摸清楚。我推荐Ubuntu 18.04或20.04这两个系统下的依赖兼容性问题最少。核心依赖有这几个PangolinUI和可视化、OpenCV图像处理、Eigen3线性代数、DBoW2和g2oORB-SLAM3自带在Thirdparty目录下、Sophus也是自带的。如果要用Python绑定的评估工具后面还会用到evo。这里有个关键点ORB-SLAM3官方默认的OpenCV视觉特征模块依赖需要opencv-contrib的支持。如果你装的是OpenCV 4.x纯基础的libopencv-dev包会缺xfeatures2d模块编译时会直接报opencv2/xfeatures2d.hpp: No such file or directory。最省事的方案是装OpenCV 3.4.x或者用官方提供的opencv-contrib一起编译。我自己在Ubuntu 20.04上用OpenCV 4.2也能通过但需要在CMakeLists里手动指定OpenCV_INCLUDE_DIRS对新手不太友好。建议按稳妥路线来。依赖安装命令整理如下# 基础编译工具 sudo apt-get install -y build-essential cmake git pkg-config # Pangolin依赖 sudo apt-get install -y libglew-dev libpython3-dev libxi-dev libxinerama-dev \ libx11-dev libwayland-dev libxkbcommon-dev wayland-protocols \ libegl-dev libglvnd-dev # Eigen3 sudo apt-get install -y libeigen3-dev # OpenCV 3.4.x二选一推荐用apt安装省事 sudo apt-get install -y libopencv-dev # 如果上面的opencv版本不带contrib建议源码编译OpenCV 3.4.16我把Pangolin单独拎出来说因为它的版本坑最折磨人。老版本的Pangolin0.5/0.6和新版本在视窗初始化接口上有明显变化直接git clone最新版反而容易和ORB-SLAM3里的旧接口冲突。实操中我建议用如下版本组合Pangolin 0.6、OpenCV 3.4.16、Eigen 3.3.7。这套组合几乎可以零报错编译通过。2.2 编译流程与命令依赖装好之后进入ORB-SLAM3源码目录直接编译就好git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git cd ORB_SLAM3 chmod x build.sh ./build.shbuild.sh内部会依次编译Thirdparty里的DBoW2、g2o、Sophus然后编译ORB-SLAM3主体。整个过程在配置好依赖的情况下5到10分钟就能完成。如果你的机器有多核可以把build.sh里的make -j参数调高一点比如改成make -j8能快不少。编译完成后在Examples目录下会生成几个可执行文件比如mono_euroc、stereo_euroc、stereo_inertial_euroc、mono_inertial_euroc等。这几个就是我们一会儿要用的核心程序。2.3 编译阶段最容易踩的几个坑第一个坑是CUDA报错。ORB-SLAM3早期版本的部分分支在编译时会尝试启用CUDA模块如果机器上装了CUDA但版本不匹配或者没装CUDA但某些头文件路径残留会直接编译失败。遇到这种问题打开CMakeLists.txt把跟CUDA相关的判断注释掉或者明确设置为OFF即可。第二个坑是Eigen版本过高。Ubuntu 22.04仓库里的Eigen是3.4某些接口变了g2o编译时容易报错。解决方法就是手动安装Eigen 3.3.7这个版本最稳。第三个坑是内存不够。ORB-SLAM3编译时g2o部分非常吃内存如果编译过程中卡死或者报internal compiler error可以检查一下机器的swap分区和可用内存至少留出4GB以上。提示编译前最好把build文件夹里的旧编译缓存删干净尤其是反复切换OpenCV版本之后。我遇到过几次改了OpenCV路径后还是报旧版本错误删掉build目录重新编译就好了。3. Euroc数据集下载、解压与文件结构详解3.1 序列选择与下载策略Euroc数据集官方托管在ETH的服务器上包含MH01到MH05五个机器大厅序列以及V1、V2两个厂房序列各三个难度版本一共11个有效序列。每个序列一个压缩包大小从几百MB到1GB不等。下载时优先选择MH01到MH05这五个序列运动轨迹更平滑跑出来的轨迹图也更直观。下载地址是官方页面 http://robotics.ethz.ch/~asl-datasets/ijrr_euroc_mav_dataset/ 如果官网下载速度不理想可以找国内高校或社区分享的镜像链接。值得注意的是数据集分为两个版本带bag的ROS包版本和纯数据的ASL数据集格式版本。我们这里只需要不带bag的machine hall序列文件夹文件名一般是MH_01_easy.zip这样的格式。每个序列解压后会有一个mav0文件夹这个文件夹就是ORB-SLAM3直接读取的目录。建议把11个序列全部下下来因为后面做对比实验时MH和V系列运动特性差异很大能横评出算法在不同场景下的鲁棒性。3.2 mav0目录结构逐层拆解解压完成后进入mav0目录你会看到下面几个子目录和CSV文件mav0/ ├── cam0/ │ ├── data/ │ │ └── 1403636579763555584.png │ └── sensor.yaml ├── cam1/ │ ├── data/ │ │ └── 1403636579763555584.png │ └── sensor.yaml ├── imu0/ │ ├── data.csv │ └── sensor.yaml ├── state_groundtruth_estimate0/ │ ├── data.csv │ └── sensor.yaml ├── leica0/ │ └── ... └── ...cam0和cam1分别是左右目的图像数据sensor.yaml里记录了相机内参、畸变模型、图像分辨率等标定参数。imu0/data.csv是IMU采样数据每行包含时间戳、角速度和加速度。state_groundtruth_estimate0/data.csv是运动捕捉系统给出的真值轨迹用于精度评估。这里要特别提醒ORB-SLAM3自带的EuRoC.yaml配置文件里有些参数需要和你下载的具体序列的sensor.yaml匹配。比如相机内参fx、fy、cx、cy以及IMU的噪声密度、随机游走参数。官方给的示例配置虽然是综合了几个序列的平均值但不同序列之间差异不大直接默认用问题也不大。如果你追求更高精度可以把配置文件改成对应序列sensor.yaml里的精确值。3.3 时间戳文件和话题名的对应关系ORB-SLAM3的Examples目录下有个EuRoC_TimeStamps文件夹里面存放了每个序列的图像时间戳文件比如MH01.txt、V101.txt等。运行程序时你需要把这个txt文件的路径作为参数传给可执行文件。它的作用就是告诉ORB-SLAM3“哪张图片对应哪个时间点”方便系统按时间序列处理数据。很多第一次跑的人容易在这里蒙圈分不清时间戳到底对应的是cam0还是cam1。其实ORB-SLAM3对于EuRoC数据集的单目和双目模式都是使用cam0的图像流和对应时间戳。只有在双目惯性模式里时间戳参数才会同时涉及cam0、cam1和imu0三个文件。后面讲到运行命令时我会把它们的对应关系单独说明。4. 正式跑通单目、双目、双目惯性模式命令详解4.1 单目模式下的运行命令与注意事项单目模式是ORB-SLAM3里最简化、也最能看明白算法流程的模式。先确保数据集路径和时间戳路径都放在一个方便引用的位置然后执行./Examples/Monocular/mono_euroc \ ./Vocabulary/ORBvoc.txt \ ./Examples/Monocular/EuRoC.yaml \ /path/to/MH01/mav0/cam0/data \ ./Examples/Monocular/EuRoC_TimeStamps/MH01.txt这里第一个参数是词袋模型文件第二个是相机和ORB特征参数配置第三个是cam0图像目录第四个是时间戳文件。跑起来之后你会看到Pangolin窗口弹出左侧是当前帧的ORB特征点可视化右侧是相机轨迹和地图点的实时构建。这个过程非常直观你能看到特征点像星星一样在图像上闪烁地图点逐渐铺满画面。单目模式存在尺度的不可观测性所以轨迹的绝对尺度是不知道的轨迹看起来会比实际偏小或偏大这在后面评估时需要注意。单目模式最容易出问题的地方是初始化阶段。如果序列开头有大范围的旋转或者低纹理区域初始化可能失败表现为Pangolin窗口里迟迟没有地图点出现。遇到这种情况直接换MH01这类从平滑运动开始的序列即可或者增加EuRoC.yaml中的特征点数量比如把ORBextractor.nFeatures从默认值调高。4.2 双目与双目惯性模式传感器融合的魅力双目模式下ORB-SLAM3可以恢复绝对尺度轨迹精度会有明显提升。执行命令./Examples/Stereo/stereo_euroc \ ./Vocabulary/ORBvoc.txt \ ./Examples/Stereo/EuRoC.yaml \ /path/to/MH01/mav0/cam0/data \ /path/to/MH01/mav0/cam1/data \ ./Examples/Stereo/EuRoC_TimeStamps/MH01.txt注意双目模式时左右目的时间戳是相同的ORB-SLAM3内部会按左右目时间戳配对图像帧。如果数据集中左右目图像不是严格同步的ORB-SLAM3会做时间戳最近邻匹配所以轻微的时间偏差问题不大。双目惯性模式是ORB-SLAM3的“完全体”同时输入双目图像和IMU数据。执行命令会稍微复杂一些./Examples/Stereo-Inertial/stereo_inertial_euroc \ ./Vocabulary/ORBvoc.txt \ ./Examples/Stereo-Inertial/EuRoC.yaml \ /path/to/MH01/mav0 \ ./Examples/Stereo-Inertial/EuRoC_TimeStamps/MH01.txt \ ./Examples/Stereo-Inertial/EuRoC_TimeStamps/MH01.txt \ ./Examples/Stereo-Inertial/EuRoC_TimeStamps/MH01.txt这里第一个时间戳对应cam0图像第二个对应imu0 IMU数据第三个对应地面真值用于对齐。实际使用中这三个文件的内容略有差异因为图像、IMU、真值的采样频率和时间段不完全一致。ORB-SLAM3源码里默认读取同一序列的这几个文件文件名通常一样但内容不同。双目惯性模式下系统会先利用IMU数据进行视觉惯性初始化这个过程通常在数秒内完成。IMU的加速度计和陀螺仪偏置会被在线估计并持续优化所以整个轨迹在快速旋转和剧烈加速阶段依然能保持稳定的姿态估计。我第一次跑到V2_03复杂序列时视觉跟踪差点丢失但IMU数据“续命”成功了这种融合的稳定感是纯视觉方案给不了的。4.3 结果输出与文件解读ORB-SLAM3正常跑完一个序列后会在终端打印System: Saving trajectory to...类似的提示然后自动把轨迹保存到两个文件KeyFrameTrajectory.txt只包含关键帧的轨迹CameraTrajectory.txt包含每一帧相机位姿的轨迹这两个文件每行格式都是时间戳 tx ty tz qx qy qz qw时间戳单位为秒位置单位通常为米四元数表示姿态。需要注意的是只有在程序正常退出比如按CtrlC或者在Pangolin窗口按ESC关闭时保存动作才会触发。如果你用kill -9强制杀掉进程轨迹文件可能没来得及写入最后得到的是空文件或半个文件。所以跑完一个序列最好等Pangolin窗口关闭后再确认一下文件大小是否正常。5. 轨迹精度评估用evo对比真值与ORB-SLAM3输出5.1 evo安装和基本用法光有轨迹还不算完评测SLAM算法最关键的环节是量化误差。这里推荐用evo这个Python工具它专门处理SLAM轨迹评估支持TUM、KITTI、EuRoC等多种格式。安装非常简单pip install evo --upgrade --no-binary evo如果系统里没有pip先装一下python3-pip和python3-tk因为evo绘图需要tkinter。evo的核心命令有两个evo_ape用于算绝对位姿误差evo_rpe用于算相对位姿误差。ATE反映的是整条轨迹的全局一致性RP E反映的是局部运动误差。对SLAM系统来说这两个指标缺一不可。5.2 对齐方式与评估命令评估Euroc数据时真值文件路径是mav0/state_groundtruth_estimate0/data.csv估计文件是ORB-SLAM3输出的KeyFrameTrajectory.txt。但直接拿这两个文件比较是不公平的因为估计值的坐标原点、朝向、甚至尺度单目情况下都和真值坐标系不一致。所以必须先做坐标对齐。对于双目和双目惯性模式尺度接近1只需要做Sim(3)或SE(3)对齐。evo命令中加上-a参数会自动计算最优的Sim(3)变换把估计轨迹对齐到真值轨迹。典型的ATE评估命令如下evo_ape euroc \ /path/to/MH01/mav0/state_groundtruth_estimate0/data.csv \ ./KeyFrameTrajectory.txt \ -va --plot --plot_mode xz-v表示显示详细信息-a表示自动对齐--plot会生成一个可视化的误差轨迹图--plot_mode xz则把轨迹投影到x-z平面展示机器人通常在这个平面运动看起来最直观。如果跑的是单目模式由于尺度未知必须使用Sim(3)对齐同时评估结果中会多出一个尺度因子scale指标。evo足够聪明会自动处理但你要知道这个尺度因子存在它是单目SLAM固有的尺度模糊性的体现。5.3 评估结果怎么读评估完成后终端会打印RMSE、mean、median、std等统计指标。对这些数值的理解我给出几个实用参考RMSE均方根误差是最常用的综合误差指标单位是米。Euroc序列上双目惯性模式MH序列的ATE RMSE通常在0.05到0.15米之间纯双目会稍差一点单目如果做了良好初始化也能到0.2米以下。如果你的结果远超这些参考值先别急检查一下时间戳文件、IMU参数、以及是否做了坐标对齐出问题的概率远大于算法本身。另外评估结果里会给一个“max”误差这个代表轨迹中最差的一个点。如果max特别大说明中间某段跟踪丢失或漂移严重可以配合绘图查看是哪段出的问题。evoi生成的图里轨迹线越粗或颜色越红的地方误差越大。这能帮你定位到具体是哪个时间段或哪个空间位置出现了大的漂移对调试算法参数相当有帮助。6. 高频报错与避坑清单6.1 编译阶段典型故障报错信息原因解决方法opencv2/xfeatures2d.hpp: No such file or directoryOpenCV缺少contrib模块安装opencv-contrib或改用OpenCV 3.4.xg2o: symbol lookup errorEigen版本冲突降级Eigen到3.3.xcuda_runtime.h: No such file编译了CUDA模块但CUDA环境异常在CMakeLists中禁用CUDAGLIBCXX_3.4.29 not foundgcc/g版本过旧升级gcc到9以上Pangolin: undefined referencePangolin版本不匹配切换到0.6版本6.2 运行阶段高频问题症状可能原因排查顺序程序启动后秒退数据集路径或时间戳路径不存在检查参数路径确认mav0目录结构初始化失败序列开头缺少纹理或运动过猛换用MH01序列或增大ORB特征数量轨迹坡度/尺度异常相机内参和IMU参数与实际序列不匹配对照sensor.yaml修正EuRoC.yamlCtrlC后无轨迹文件进程被强制杀死未触发保存回调等待正常退出或手动在代码中加入保存逻辑跑得很慢实时性差CPU占用过高Pangolin渲染开销大关闭系统特效或用headless模式运行6.3 我的几个独家排查技巧最后一个建议如果你不是专门研究特征点法SLAM理论第一次跑ORB-SLAM3时不要试图改算法参数。先用默认配置把三个模式全部跑通再逐步观察差异。默认配置是作者在多个序列上调出来的甜点参数对新数据集未必最优但对Euroc来说已经足够稳定。另外我强烈建议在跑每一个序列之前先用evo把真值轨迹画出来看一眼。MH序列和V序列的运动范围、运动速度差别非常大提前了解真值轨迹的形状后面再对比ORB-SLAM3输出的轨迹一眼就能看出哪段漂移离谱。踩过几次坑之后我最深刻的体会是ORB-SLAM3跑Euroc这套组合真正难的并不是运行本身而是环境配置和数据准备阶段的这种“小折磨”。但只要把这套流程完整走通一遍你对SLAM系统如何读取传感器数据、如何组织特征和关键帧、如何输出并评估轨迹都会建立起一个非常扎实的整体框架。所以遇到报错千万别烦躁每一步调试都是在帮你理解系统内部的工作原理。
返回列表