做视觉SLAM这一年多最大的感受是跑通一个开源SLAM系统只能算入门能把自己改的算法用数据说话才算真正会做SLAM。ORBSLAM是大家最熟悉的视觉SLAM开源方案之一但网上讲如何编译、如何跑通的教程很多真正把“数据集准备”和“evo评估工具”这条验证链路讲透的文章反而少。这篇文章以ORBSLAM为核心拧出数据、轨迹、误差这三个关键节点讲清楚TUM、KITTI、EuRoC数据集怎么选、怎么下、怎么喂给ORB-SLAM再手把手演示evo评估工具如何量化轨迹误差。适合刚把ORB-SLAM编译通过的初学者也适合准备系统评测SLAM算法、打算在论文里放误差图的进阶用户。1. 为什么SLAM离不开数据集又为什么非要给轨迹打分1.1 SLAM评测的本质一切算法最终都要落到数字上SLAM系统输出的直接结果是相机或机器人在空间中的运动轨迹以及随之构建的地图。地图质量很难定量衡量但轨迹是可以和真值一比一对比的。所谓真值就是由运动捕捉系统Vicon、激光跟踪仪Leica或高精度组合导航系统记录下来的高精度位姿序列。评测的核心思想并不复杂把SLAM估计出的轨迹和真值轨迹放在同一时间轴上逐帧对比算出误差。误差越小说明系统在“定位”这条主线上越可靠。这个思路来自里程计与SLAM领域多年的惯例而且已经被学术界和工业界广泛接受。现在如果你在论文里只说“轨迹看起来不错”基本没有任何说服力。评审和读者要看到的是RMSE、均值误差、最大误差这些量化指标以及对应的误差曲线图。没有数据集就没有可比性没有评估工具就没有可信度。两者是SLAM验证体系的左膀右臂。1.2 ORB-SLAM系列发展回顾从2015年的单目到2021年的紧耦合ORB-SLAM是西班牙萨拉戈萨大学Raúl Mur-Artal等人提出的开源视觉SLAM方案它最大的特点是把ORB特征贯穿整个系统前端跟踪、局部建图、回环检测都用同一套特征。这样做的好处很直接——特征提取与匹配的一致性高系统结构统一而且ORB特征的提取速度远快于SIFT或SURF普通CPU上就能实时运行。版本演进也体现了这个方向的脉络2015年单目版本发布后迅速成为领域标杆2017年ORB-SLAM2扩展到单目、双目和RGB-D三种传感器配置2021年ORB-SLAM3加入视觉惯性紧耦合双目IMU、单目IMU和多地图系统把视觉SLAM推到了新的高度。对大多数普通使用者来说ORB-SLAM2依然是最容易上手、文档最全、资料最多的版本ORB-SLAM3则在性能上限和传感器支持上更胜一筹。不管用哪个版本评测流程基本一致先跑数据集再输出轨迹文件最后用evo评估。1.3 evo在整个流程中的角色定位evo的全称是Python package for the evaluation of odometry and SLAM简单理解它就是一个专门用来评测里程计和SLAM轨迹的工具包。它支持TUM、KITTI、EuRoC三种主流格式的轨迹文件也支持从 CSV 等常见格式导入提供evo_traj、evo_ape、evo_rpe三个核心命令行工具。为什么推荐它来做ORBSLAM的轨迹评估第一开源免费安装就是pip一条命令第二社区用得多论文里的轨迹误差图大部分都是evo生成的输出风格已经是学术圈约定俗成的标准第三它不只是做数值计算还能画轨迹对比图、误差曲线图一键导出论文里需要的图片。我把整个验证链路总结成一个循环每次改完算法都可以按这个循环检查选数据集根据传感器和场景需求决定用TUM、KITTI还是EuRoC跑SLAM让ORB-SLAM在数据集序列上运行保存估计轨迹算误差用evo把估计轨迹和数据集自带的真值轨迹对齐、比较看结果分析误差指标和曲线决定是否需要调参或改算法。在这个循环里数据集提供“标准答案”ORB-SLAM提供“被试答案”evo负责“判卷”。三者缺一不可。2. 三个绕不开的公开数据集TUM、KITTI、EuRoC2.1 TUM RGB-D数据集室内视觉SLAM的入门必选TUM RGB-D数据集由慕尼黑工业大学计算机视觉组发布是RGB-D SLAM领域使用频率最高的数据集。它提供彩色图、深度图和运动捕捉系统采集的真值轨迹所有图像文件都以时间戳命名目录结构非常清晰。比如最经典的rgbd_dataset_freiburg1_desk解压后你会看到rgb/和depth/两个文件夹里面的命名格式类似1305031102.175304.png前面的数字就是采集时刻的时间戳单位是秒。TUM的groundtruth文件是一个文本文件每行格式为timestamp tx ty tz qx qy qz qw其中timestamp是时间戳tx ty tz是相机在世界坐标系下的位置单位是米qx qy qz qw是表示姿态的四元数。别小看这个格式后面用evo评估时它默认能直接识别。TUM的数据集分成fr1、fr2、fr3三个大系列。fr1是Kinect v1采集的场景相对小纹理丰富度一般跟踪难度比较大fr2是Kinect v1在更大房间里采集的适合验证系统在大场景下的鲁棒性fr3加入了更多纹理缺失、动态物体等退化场景比如fr3_walking_xyz这类序列就是专门测试动态环境下SLAM系统的抗干扰能力。如果你是刚接触ORB-SLAM我建议从fr1/xyz或fr1/desk开始这两个序列轨迹简单跑通整体链路比较快。2.2 KITTI数据集自动驾驶场景下的双目与激光雷达基准KITTI由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合发布原意是为自动驾驶的视觉感知任务提供平台但其中的视觉里程计Odometry基准已经成为双目视觉SLAM评测的事实标准。KITTI数据的采集车装有双目灰度相机、双目彩色相机、Velodyne激光雷达和GPS/IMU组合导航系统。以odometry基准为例它提供了00到10共11个序列其中00到08是训练集09和10是测试集。每个序列目录下包含image_0左灰度图、image_1右灰度图、image_2左彩色图、image_3右彩色图、velodyne点云和oxtsGPS/IMU数据。和TUM最大的不同在于KITTI的真值轨迹不是一行一个位置而是把所有位姿放在一个文件里每行是一个3x4的变换矩阵表示该帧相对于第0帧的位姿。ORB-SLAM2跑KITTI时不需要额外做数据关联因为它读取的是连续图像序列不需要时间戳匹配。这个数据集特别适合验证双目SLAM在室外大场景、高速运动下的性能如果你的课题方向是自动驾驶、移动机器人室外定位KITTI基本是首选。2.3 EuRoC MAV数据集视觉惯性SLAM的标准试验场EuRoC MAV数据集由苏黎世联邦理工学院发布采集平台是一架微型无人机搭载双目全局快门相机和惯性测量单元IMU。它最大的价值在于同时提供了高帧率的图像数据和IMU数据是视觉惯性SLAMVI-SLAM评测的标准数据集。ORB-SLAM3在论文里就是用EuRoC来验证视觉惯性紧耦合效果的。EuRoC数据集中每个序列解压后都是一个mav0目录里面包含cam0/data左目图像文件名是时间戳cam1/data右目图像imu0/data.csvIMU测量数据state_groundtruth_estimate0/data.csv真值轨迹由Vicon运动捕捉系统或Leica激光跟踪仪提供真值文件的格式是CSV列很多但核心就两大部分三轴位置p_RS_R_x [m]、p_RS_R_y [m]、p_RS_R_z [m]以及四元数姿态q_RS_w []、q_RS_x []、q_RS_y []、q_RS_z []。EuRoC的数据按难度分成Machine Hall和Vicon Room两大场景又按飞行速度、光照变化、纹理情况细分为MH_01_easy到V2_03_difficult等多个序列方便你做梯度测试。2.4 数据集选择与下载实操指南三个数据集覆盖了三种典型场景选哪个主要看你的传感器配置和研究目标。我自己常用的选择逻辑是这样数据集传感器类型典型场景适合验证什么TUM RGB-DRGB-D / 单目室内桌面、房间RGB-D SLAM、动态环境下鲁棒性KITTI双目 / 激光 GPS室外自动驾驶双目SLAM、大尺度场景定位EuRoC MAV双目 IMU无人机飞行视觉惯性SLAM、紧耦合算法下载时TUM的官网提供了.tgz压缩包直接点对应序列下载即可KITTI需要去odometry基准页面输入邮箱后获取下载链接注意它要求选择序列可以只勾自己需要的EuRoC则按序列逐个下载。由于这些数据集体量都不小TUM一个序列通常几百MB到几个GBKITTI单个完整序列可能达到几十GBEuRoC相对轻量下载时建议用支持断点续传的下载工具并留意官方提供的MD5校验值避免文件不完整导致后面运行报错。提示KITTI odometry的在线评测需要注册账号并遵守数据集许可协议如果你的工作不打算公开提交榜单只用本地评测也可以。3. 把追踪跑起来ORB-SLAM在数据集上的完整实操3.1 环境准备与源码编译在跑任何数据集之前先把ORB-SLAM环境搭建好。以ORB-SLAM2为例核心依赖有OpenCV、Eigen3、Pangolin以及仓库自带但需要编译的DBoW2和g2o。如果你还要用ROS接口还得装对应版本的ROS。编译过程主要是一句话cd ORB_SLAM2 ./build.sh但这句话想顺利跑完有几个前置条件先确认OpenCV版本要匹配。ORB-SLAM2发布时主要针对OpenCV 3.x如果你装的是OpenCV 4.x编译时经常会报CV_LOAD_IMAGE_UNCHANGED、CV_RGB2GRAY这类宏找不到的错误需要在源码里手动改成cv::IMREAD_UNCHANGED和cv::COLOR_RGB2GRAY。我踩过这个坑改起来虽然不复杂但第一次遇到容易慌。Pangolin版本不要用太新的。建议选0.6或相近版本太新的Pangolin也可能和ORB-SLAM2源码产生兼容问题。编译时出现内存不足导致g2o编译失败可以减少make -j的并行数例如./build.sh里有并行参数的话改成make -j2。确保Vocabulary/ORBvoc.txt存在。如果编译脚本执行过又没有报错这个文件一般生成在Vocabulary/目录下是后续所有运行命令都需要的词典文件。3.2 以TUM RGB-D序列为例的完整运行步骤环境准备好后先用TUM数据集打通全流程。假设你已经下载并解压了rgbd_dataset_freiburg1_desk.tgz路径是~/datasets/fr1_desk。第一步做数据关联。TUM的RGB图和深度图是分别独立采集的时间戳并不一一对应需要运行官方提供的一个Python脚本把彩色图和深度图按时间差阈值关联起来# associate.py 是TUM官方脚本原文可在数据集官网找到 # 核心逻辑两条时间戳序列贪心匹配最小时间差 # 运行方式 # python associate.py rgb.txt depth.txt associations.txt运行后会生成一个associations.txt每行包含四个值彩色图时间戳、彩色图路径、深度图时间戳、深度图路径。时间差阈值通常设置为0.02秒太大会引入明显不同步的数据太小又会减少匹配对。第二步跑ORB-SLAM2。以TUM1配置文件为例cd ORB_SLAM2 ./Examples/RGB-D/rgbd_tum \ Vocabulary/ORBvoc.txt \ Examples/RGB-D/TUM1.yaml \ ~/datasets/fr1_desk \ ./Examples/RGB-D/associations/fr1_desk.txt注意命令里的四个输入分别是词典文件、相机内参文件、数据集根目录、数据关联文件。程序启动后会弹出Pangolin的实时可视化窗口你会在窗口里看到相机轨迹增量式地构建出来。跑完后程序通常会在当前目录生成KeyFrameTrajectory.txt这个文件就是之后用evo评估的关键输入。3.3 KITTI与EuRoC序列的运行差异KITTI的运行方式和TUM有较大区别因为它本身就是连续图像序列不需要数据关联。以双目场景为例./Examples/Stereo/stereo_kitti \ Vocabulary/ORBvoc.txt \ Examples/Stereo/KITTI00-02.yaml \ ~/datasets/KITTI/sequences/00KITTI序列对应的相机参数在Examples/Stereo/下的yaml文件里写死了比如KITTI00-02.yaml适用于00、01、02序列因为这三段用的是同一套相机标定。如果你的数据是03及以后的序列记得换对应的配置文件否则内参不对初始化阶段就容易翻车。EuRoC的运行稍复杂。ORB-SLAM2原生没有直接喂EuRoC数据的可执行文件需要自己写数据读取器ORB-SLAM3则直接支持提供了类似stereo_euroc和stereo_inertial_euroc这样的可执行文件配合Examples/Stereo/EuRoC.yaml等配置就能跑。EuRoC序列里同时有图像和IMU数据用视觉惯性模式跑时程序会读取imu0/data.csv这一步对时间同步要求很高如果IMU时间戳和图像时间戳没有对齐到同一时间基准初始化会非常慢甚至一直不成功。注意跑完任何数据集都要养成保存轨迹的习惯。ORB-SLAM2默认在程序结束或用户按键时输出KeyFrameTrajectory.txt。如果你还需要完整帧轨迹可以修改源码把每一帧的位姿都写入文件后面做RPE逐帧评估时数据更充足。4. evo评估工具从安装到输出论文级图表4.1 安装、核心命令与文件格式evo的安装非常简单依赖Python环境推荐Python 3.8及以上pip install evo --upgrade --no-binary evo--no-binary是官方推荐写法避免直接下载预编译包造成兼容问题。安装完成后你可以在终端里看到三个核心命令evo_traj、evo_ape、evo_rpe。evo_traj展示轨迹可以一条或多条轨迹一起显示也可以做简单对比evo_ape计算绝对轨迹误差Absolute Pose Errorevo_rpe计算相对位姿误差Relative Pose Error。这三个命令都要求输入轨迹文件而文件格式必须被evo识别。ORB-SLAM输出的KeyFrameTrajectory.txt格式是timestamp tx ty tz qx qy qz qw这正好是TUM格式所以用evo_traj tum就能直接读。KITTI格式则是12个数的矩阵行EuRoC的CSV需要额外指定列但整体上evo都能处理。4.2 ATE与RPE两个指标从原理到代码绝对轨迹误差衡量的是估计轨迹和真值轨迹在全局意义上的一致性。对于每个时间戳先通过位姿变换把算法的估计轨迹与真值轨迹对齐然后计算每一帧位置或姿态的偏差。这个指标最直观地反映了SLAM系统“整体漂移有多大”论文里最常见的就是ATE曲线图和对应的RMSE。相对位姿误差则不同它计算的是在固定时间间隔内两帧之间的相对运动估计得准不准。给定一个时间步长delta它比较“从t时刻到tdelta时刻的估计相对变化”和“真值相对变化”之间的误差。RPE更关注局部漂移和短期一致性比如回环检测前和回环检测后短期内轨迹是否平滑。用evo计算这两个指标只需要三条命令evo_ape tum groundtruth.txt KeyFrameTrajectory.txt -va --plot --plot_mode xy evo_rpe tum groundtruth.txt KeyFrameTrajectory.txt -va --plot --plot_mode xy-v表示打印详细信息-a表示自动对齐Sim(3)--plot会弹出误差图窗口--plot_mode指定投影平面。对于RGB-D和双目SLAM尺度和真实世界一致通常用-a做SE(3)或Sim(3)对齐都行但如果是单目SLAM必须用-s或--correct_scale做尺度校正因为单目系统天然存在尺度不确定性。4.3 最常用的evo命令参数与典型用法我平常用得最多的参数组合基本固定可以照抄# 画一条轨迹并在图上显示起点终点 evo_traj tum KeyFrameTrajectory.txt -p --plot_mode xyz # 两条轨迹对比一真一估自动对齐后画图 evo_traj tum groundtruth.txt KeyFrameTrajectory.txt -a -p --plot_mode xy # 计算ATE保存结果为zip方便后面合并表格 evo_ape tum groundtruth.txt KeyFrameTrajectory.txt -va -a -s --plot --plot_mode xy --save_results result_ate.zip # 计算RPE时间间隔设置为1即逐帧计算 evo_rpe tum groundtruth.txt KeyFrameTrajectory.txt -va -a -s --plot --plot_mode xy --delta 1 --delta_unit m --save_results result_rpe.zip # 把多个评估结果汇总成表格 evo_res result_ate.zip result_rpe.zip -p这里特别说一下--align和--correct_scale的区别。--align做的是估计轨迹到真值轨迹的刚体变换对齐解决的是坐标系原点不同的问题--correct_scale是额外估计一个全局尺度因子解决的是单目SLAM尺度漂移的问题。对于双目和RGB-D一般不需要尺度校正对于单目缺了这个参数误差会大得离谱因为轨迹整体被缩放到一个未知比例。evo_res这个命令很多人忽略但它特别实用。当你跑完ATE和RPE各自得到一堆统计量evo_res可以把多个结果zip文件合并成一张表直接输出rmse、mean、median、std、min、max这些值。表格默认会打印在终端里也支持导出CSV放到论文附录里非常方便。4.4 一次完整的evo评估示例假设我用TUM的fr1_desk跑完ORB-SLAM2当前目录下有一个KeyFrameTrajectory.txt。我一般按照下面的顺序做一次完整评估# 第一步看轨迹长什么样 evo_traj tum KeyFrameTrajectory.txt -p # 第二步把真值轨迹和估计轨迹叠在一起看 evo_traj tum groundtruth.txt KeyFrameTrajectory.txt -p --plot_mode xy --align # 第三步算ATE并保存结果 evo_ape tum groundtruth.txt KeyFrameTrajectory.txt -va --align --correct_scale --plot --plot_mode xy --save_results ate.zip # 第四步算RPE并保存结果 evo_rpe tum groundtruth.txt KeyFrameTrajectory.txt -va --align --correct_scale --plot --plot_mode xy --delta 1 --delta_unit m --save_results rpe.zip # 第五步合并出表 evo_res ate.zip rpe.zip -p第二步的对比图很直观比如真值轨迹绕了一个矩形估计轨迹在矩形闭合处错开了一大截说明全局漂移明显回环检测没有完全纠正累积误差。第三步的ATE表里重点看rmse和maxrmse代表整体误差水平max代表极端情况下的最大偏差。第四步的RPE里delta设置为1表示每1米或每1帧计算一次相对误差具体单位由--delta_unit指定这里的--delta_unit m会导致程序按照轨迹移动1米为单位来分段计算比逐帧计算更符合“局部连贯性”的直觉。5. 常见问题与排查技巧实录5.1 时间戳与数据关联问题TUM数据集里最容易出错的就是数据关联。如果直接用所有RGB图像和深度图像不进行时间戳匹配ORB-SLAM运行时会因为RGB和深度对不齐生成的深度图噪声巨大甚至一开始初始化都无法完成。我自己排查的经验是如果程序在初始化阶段一直卡住先检查associations.txt是不是空的或者匹配对数是不是明显偏少。还有一个更隐蔽的问题TUM的groundtruth时间起点和数据序列时间起点可能不完全一致导致后面evo对齐时轨迹前段没有对应的真值图表前面出现一段空白。遇到这种情况可以用evo_traj先查看两条轨迹的时间范围再用--t_max或--t_min参数截取有效区间。5.2 编译与运行ORB-SLAM的经典坑ORB-SLAM的编译问题主要集中在OpenCV和Pangolin的版本兼容性上。OpenCV 4.x环境下源码里的CV_LOAD_IMAGE_UNCHANGED和CV_RGB2GRAY会直接编译失败这是最常见的报错。解决办法是打开报错文件把CV_LOAD_IMAGE_UNCHANGED改成cv::IMREAD_UNCHANGEDCV_RGB2GRAY改成cv::COLOR_RGB2GRAY同时在CMakeLists里确认OpenCV的链接库路径别配错。Pangolin如果版本太新可能出现glGenVertexArrays链接错误建议切换到0.6版本重装。运行时还会遇到一个容易被忽略的问题TUM的yaml配置文件参数必须和数据集序列对应。TUM1.yaml对应fr1系列TUM2.yaml对应fr2系列TUM3.yaml对应fr3系列。如果拿TUM2的内参去跑fr1图像焦距偏差会造成特征点位置计算错误特征跟踪质量大幅下降表现为初始化成功后没跑多远就开始丢跟踪。5.3 evo结果不合理时怎么排查拿到evo的误差结果先别急着相信先问自己三个问题轨迹文件格式对吗尺度有没有校正对齐方式选对了吗如果ATE大得离谱比如几米甚至几十米而可视化轨迹看起来又和真值形状相似十有八九是尺度问题。单目SLAM输出的是归一化尺度下的轨迹和真实尺度之间相差一个未知比例因子必须加--correct_scale。如果不加RMSE会放大很多倍。如果轨迹形状都对、尺度也对但误差还是偏大检查一下--align到底用的什么变换。RGB-D和双目SLAM理论上不需要尺度校正但坐标系原点和方向可能需要刚体变换对齐一般用-a做Sim(3)对齐是安全的。如果你加了--align_origin它只对齐原点但不对齐方向适合某些特殊场景但默认不要用。还有一个单位坑部分CSV格式的轨迹位置可能不是米而是毫米。EuRoC真值文件明确标注单位是米但你自己生成的数据就不一定。如果误差值整体偏大1000倍检查一下单位是不是毫米。提示evo支持把轨迹文件转换为统一格式比如evo_traj tum KeyFrameTrajectory.txt --save_as_kitti这样你可以在不同格式之间来回转换方便和别人的结果对比。多转换几次你对各种轨迹格式的理解会更深。5.4 实战避坑清单整理一张我在跑ORBSLAM和evo时反复用到的检查表检查项典型症状解决方法TUM RGB与深度时间戳未关联初始化失败、深度噪声大运行associate.py重新生成关联文件单目轨迹未做尺度校正ATE/RMSE巨大加-s或--correct_scaleOpenCV版本不兼容编译报CV_LOAD_IMAGE手动改为cv::IMREAD_UNCHANGEDyaml内参与数据不匹配跟踪易丢、初始化久按fr1/fr2/fr3选择对应配置轨迹单位不是米误差整体偏大千倍检查数据来源统一单位为米真值轨迹与估计轨迹时间范围不一致图表前后出现空白用--t_min和--t_max截取有效区间这张表不一定覆盖所有场景但最常见的坑基本都在里面了。我每次换新数据集跑评测都会先按这张表过一遍能省下很多排查时间。最后再分享一个我在实际使用中的体会ORB-SLAM和evo这套组合真正教会我的不是某个命令怎么敲而是“先定义判决标准再改算法”的工作习惯。数据集的真值轨迹就是你的裁判evo的RMSE就是你的成绩单ORM-SLAM每改动一个参数、一个特征提取策略都能通过同一套流程快速看到量化反馈。这样做研究的效率比只凭肉眼观察可视化窗口高太多了。如果你刚开始接触这套流程建议不要贪多先把TUM的fr1/desk跑通再用evo把ATE和RPE的图表完整出一次这个闭环一旦打通后面换KITTI、EuRoC或者换成别的SLAM算法都只是换数据和换命令的问题。