
1. 项目概述这套组合到底解决什么问题做视觉SLAM的人无论是刚入门的研究生还是在公司调算法的工程师大概率都会遇到同一个问题算法写出来了跑起来了但怎么证明它“行”你自己在数据集上跑一遍看着画面里特征点稳定跟踪觉得效果不错可老板、审稿人或者客户一句“精度多少”你拿不出数字就尴尬了。ORB-SLAM作为基于特征点法的代表性开源系统大家都很熟悉但真正要把它的性能量化、可复现、可比较就绕不开两样东西公开数据集和评估工具。这个项目就是围绕“ORB-SLAM 数据集 evo评估”这一整套评测链路展开的。先说数据集。做SLAM评测不能拿自己录的数据自说自话因为场景、传感器标定、运动轨迹都不透明别人也没法复现。主流的公开数据集比如TUM RGB-D、KITTI、EuRoC MAV都提供了传感器数据图像、IMU等和高精度的真值轨迹Ground Truth你在同一份数据上跑结果才有横向对比的说服力。再说评估工具。evo是当前用得最顺手的轨迹评估工具之一它能把你SLAM输出的轨迹和数据集提供的真值轨迹加载进来做时间戳对齐、轨迹对齐然后算出ATE绝对轨迹误差、RPE相对位姿误差等核心指标还能直接画图省去自己写脚本的麻烦。这篇内容适合谁我认为有三类人最需要一是刚接触SLAM、想把ORB-SLAM在公开数据集上跑通并量化结果的新手二是准备发论文、需要给方法做对比实验的研究生三是在实际项目中想快速评估自己改动效果的工程师。下面我会从数据集选型、evo工具原理、完整实操流程到常见坑位把这条评测链路一次性讲清楚。整套流程我实测过多次照着走基本不会有卡壳的地方。2. 常用SLAM公开数据集选型与特点2.1 TUM RGB-D室内视觉SLAM的入门标配TUM RGB-D数据集是慕尼黑工业大学TU Munich发布的全称是TUM RGB-D Benchmark。它用微软Kinect一代传感器在室内场景下录制了几十个序列覆盖桌面、办公室、客厅等不同环境。这个数据集最核心的价值在于提供了非常丰富的传感器轨迹和真值除了RGB图像和深度图像还有用运动捕捉系统Vicon或高精度运动追踪系统测得的相机轨迹频率达到100Hz以上精度在毫米级别。为什么说它是入门标配因为TUM数据集的序列划分非常细每个序列都有明确的场景特征和运动特性例如fr1/desk是桌面场景相机在桌面上方缓慢移动适合验证基本跟踪稳定性fr2/xyz是纯平移运动适合验证尺度一致性fr3/structure_texture_far则是有大量无纹理墙面的场景专门用来考验特征点法在弱纹理环境下的表现。对于ORB-SLAM这种基于ORB特征点的系统TUM数据能非常直观地暴露算法在不同场景下的弱点。TUM还支持RGB-D和单目两种评测模式你既可以输入RGB-D序列验证稠密或半稠密建图也可以只用RGB图像走单目SLAM流程。它提供的groundtruth.txt是标准TUM格式每行内容包括时间戳、平移量以及四元数表示的旋转这个格式同时也是evo工具默认支持的格式之一所以拿来就能直接评估不需要额外转换。2.2 KITTI自动驾驶场景的里程计基准KITTI数据集是德国卡尔斯鲁厄理工学院KIT和丰田美国技术研究院联合发布的自动驾驶场景数据集涵盖双目图像、激光雷达点云、GPS/IMU数据以及高精度真值。它的视觉里程计基准KITTI Odometry提供了从城市道路到乡村公路的22个序列00到21前11个序列公开了真值轨迹用于评估单目、双目以及激光SLAM/里程计系统的定位精度。KITTI和TUM最大的区别在于场景尺度和载体特性。TUM是室内手持相机运动范围小、视场受限KITTI是车载摄像头场景是开阔的室外道路光照变化大、动态物体多车辆、行人运动方式以车辆前进和转向为主。这些特性决定了KITTI更适合评估SLAM系统在真实自动驾驶场景下的长距离定位能力尤其是累积漂移的控制情况。ORB-SLAM在KITTI上跑tracking线程对车辆快速转向和遮挡的鲁棒性会得到充分考验。KITTI数据格式上需要注意它没有直接提供单目的TUM格式轨迹文件而是以位姿矩阵序列的形式存储。每帧的位姿是一个3x4的变换矩阵展平后占一行12个数字6自由度位姿。这个格式evo同样原生支持KITTI格式但如果你用的是KITTI的单目序列因为没有尺度信息输出轨迹要和真值对齐时需要做Sim(3)变换稍后我会在evo原理部分详细说明。2.3 EuRoC MAV无人机视觉惯性里程计的经典测试EuRoC MAV数据集是苏黎世联邦理工学院ETH发布的微型无人机MAV数据集用双目相机加IMU录制包含机器大厅Machine Hall和普通房间Vicon Room两种室内环境共11个序列。它的独到之处在于把场景难度按“光照条件、纹理丰富度、运动速度、IMU激励程度”分成了Easy、Medium、Difficult三个等级评测时可以直接用难度梯度来衡量算法鲁棒性。EuRoC提供了100Hz的双目图像全局快门、200Hz的IMU数据以及Vicon运动捕捉系统得到的6自由度真值。如果你在调ORB-SLAM3这种带IMU融合的版本EuRoC几乎是必测的数据集。因为它的运动包含快速旋转、急加速、剧烈振动可以充分验证视觉惯性融合是否能有效抑制纯视觉在快速运动下容易丢失的问题。EuRoC的真值文件格式是timestamp、position的三轴坐标加四元数与TUM格式略有差别数据顺序是qw qx qy qzevo同样支持直接读取。需要注意EuRoC数据集官方还提供了带时间戳的轨迹真值并区分了全局坐标系和机体坐标系用的时候要确认你评估时载入的是哪一套坐标避免因为坐标系选错而得出错误结论。2.4 其他常用数据集一览除了上述三大主流数据集根据应用场景不同你还会遇到一些特定方向的数据集我在这里简单列一下方便大家根据需求选型数据集场景传感器典型用途ICL-NUIM室内合成场景RGB-D无真实传感器噪声方便做算法消融实验ETH3D室内外混合双目、多视角高分辨率图像适合鲁棒视觉定位和重建TUM VI室内手持/无人机双目IMU视觉惯性里程计评估时间戳标定严格NCLT校园室外长时双目、激光、IMU长时SLAM、光照季节变化鲁棒性OpenLORIS室内生活场景RGB-D、IMU生活机器人长期自定位主打动态环境选数据集没有绝对的对错核心原则是你的算法目标场景和数据集采集场景要尽量匹配。比如你做室内服务机器人硬要在KITTI上刷精度意义就不大反过来你做自动驾驶定位非要在TUM这种桌面数据上评估也难以说明在真实道路场景的适用性。3. evo评估工具安装、核心命令与原理3.1 evo能做什么为什么大家都用evo是一个用Python写的SLAM轨迹评估工具作者是Michael Grupp目前在GitHub上开源维护社区非常活跃。它支持多种输入格式TUM、KITTI、EuRoC、ROS bag等能够计算两个轨迹之间的绝对误差ATE和相对误差RPE并且自带可视化功能可以直接输出误差曲线和轨迹对比图。在evo出现之前大家评估SLAM基本是拿到数据集官方提供的Matlab评估脚本或者自己写Python代码处理轨迹对齐和误差计算。自己写的问题在于轨迹对齐算法容易出错、时间戳对齐要处理插值、误差统计口径不统一最后跑出来的结果跟别人对不上。evo把这些问题都封装好了命令行一条指令就能得到规范化的指标这也让它成了当前SLAM领域事实上的标准评估工具。另一个关键点是evo“可复现”。它会把评估过程中的关键参数如对齐方式、误差类型、时间戳偏移量全部打印出来你写论文时直接引用即可评审和读者可以照着你的参数重新跑一遍保证结果一致性。这一点在学术交流中非常加分。3.2 安装与环境配置evo的安装很简单因为它是纯Python项目直接用pip安装即可。不过你在装之前最好先确认Python环境。官方推荐Python3.8以上版本我是直接用Anaconda建了一个单独的环境避免跟系统Python打架。conda create -n evo_env python3.8 conda activate evo_env pip install evo --upgrade --no-binary evo这里的--no-binary evo参数建议保留因为evo的二进制wheel包有时候会缺依赖从源码编译安装更稳妥。安装完成后验证一下evo --version正常情况下会输出evo的版本号同时还会列出evo_ape、evo_rpe、evo_traj等子命令。如果提示找不到命令检查一下Anaconda环境的bin目录是否在PATH里或者直接运行python -m evo来调用。安装过程中最容易踩的坑是numpy版本冲突。evo底层依赖numpy和matplotlib如果你环境里numpy版本过新比如1.24以上的某些版本evo在绘制误差图时可能报错此时可以指定降级安装pip install numpy1.23.5这个版本组合我实测下来稳定不报错。3.3 核心命令evo_ape、evo_rpe、evo_trajevo最常用的三个命令是evo_ape、evo_rpe和evo_traj我逐个说明它们的用途。evo_ape是计算绝对轨迹误差Absolute Trajectory Error的命令。ATE衡量的是整条轨迹的全局一致性即估计轨迹和真值轨迹在整体上相差多少。对于回环检测是否有效、长时间运行是否漂移这类问题ATE是最直接的指标。基本用法如下evo_ape tum groundtruth.txt estimated.txt -a这里的-a参数让evo在计算误差前自动进行轨迹对齐。对于单目SLAM因为没有尺度信息还需要加上-s进行尺度校正此时对应的是Sim(3)变换对齐命令为evo_ape tum groundtruth.txt estimated.txt -a -sevo_rpe则是计算相对位姿误差Relative Pose Error它衡量的是固定时间间隔比如每1米或者每1秒内位姿增量的误差。相对误差在评估里程计局部精度时更有意义因为它剔除了全局累计漂移的影响。基本用法evo_rpe tum groundtruth.txt estimated.txt -r trans_part -d 1其中-r指定计算误差的部位常用选项包括trans_part平移部分、rot_part旋转部分、full全部-d指定相对误差的时间间隔单位是秒。如果你需要评估平移、旋转分别的表现可以组合这些参数分别出指标。evo_traj用于加载一个或多个轨迹文件进行可视化或者将不同格式的数据转换成你需要的格式。例如查看轨迹evo_traj tum estimated.txt -p把KITTI格式的位姿文件转成TUM格式evo_traj kitti kitti_poses.txt --save_as_tum-p参数会弹出matplotlib窗口把轨迹画在平面上配合--ref参数还可以同时画出真值轨迹做对比据说这个功能在调试时很实用一眼就能看出轨迹整体是否偏离。每次评估完evo会输出一组统计量通常包括RMSE均方根误差、MAE平均绝对误差、Median中位数、Std标准差和Max最大误差。不同论文里常用RMSE作为最终汇报指标但实际写报告时建议把中位数和最大误差也一并给出因为RMSE对异常值比较敏感最大误差能反映算法最坏情况下的表现。3.4 轨迹对齐与误差计算原理很多人第一次用evo时会困惑为什么我的轨迹明明和真值画出来差得很远加了-a之后指标立刻变得很好原因在于SLAM系统输出的轨迹坐标系和数据集真值轨迹坐标系通常不是同一个两者之间存在一个刚体变换旋转平移单目SLAM还额外存在尺度因子。如果不先对齐坐标系就直接算误差数值会大得离谱也没有实际意义。evo默认用的是Umeyama算法它可以在已知两个轨迹对应点的情况下求解出最优的相似变换Sim(3)使估计轨迹在最小二乘意义下最接近真值轨迹。这个变换包含旋转、平移和缩放三个分量。双目或RGB-D SLAM的输出一般不存在尺度问题用刚体变换SE(3)对齐就够了单目SLAM则必须用Sim(3)对齐把尺度因子也求解出来。这也是你为什么会在很多论文里看到“monocular results are aligned with 7-DoF similarity transformation”的原因。对齐完成之后ATE的计算过程是把两轨迹对应位姿的平移向量之差取范数然后统计RMSE等误差指标。RPE则是对相邻位姿增量做类似计算得到的是局部误差的时间序列。理解了这个原理你就能明白为什么同一个算法在不同数据集上的指标必须注明对齐方式否则数值之间根本不具备可比性。4. 实操ORB-SLAM2跑通TUM数据并用evo评估4.1 下载数据集与ORB-SLAM2编译准备这里我以ORB-SLAM2在TUM RGB-D数据集上的评测为例走一遍完整流程。这套流程是室内RGB-D SLAM最经典的验证路径跑通之后再迁移到KITTI、EuRoC就顺手很多。先下载TUM数据集的fr1/desk序列。在TUM官网找到下载链接文件是一个压缩包包含RGB图像、深度图像和groundtruth.txt。解压后建议把目录名改简单一点比如fr1_desk方便后续命令行操作。同时还需要TUM官方提供的一个RGB-D数据对齐脚本associate.py因为RGB图像、深度图像和真值轨迹的时间戳不是一一对应的需要根据时间差做匹配。ORB-SLAM2的编译依赖项有Pangolin、OpenCV、Eigen、DBoW2和g2o。Pangolin用于可视化窗口OpenCV做图像处理Eigen做矩阵运算DBoW2和g2o是ORB-SLAM内部集成的词袋和优化库。如果你在Ubuntu 18.04或20.04上操作官方README里的命令基本能一路顺畅编译过。编译时容易出问题的是OpenCV版本ORB-SLAM2的代码比较早对OpenCV3兼容最好如果你装的是OpenCV4.2以上版本大概率会遇到一些函数接口变动导致的编译错误需要手动改几处源代码比如ORBextractor.cc里的CV_LOAD_IMAGE_GRAYSCALE改成cv::IMREAD_GRAYSCALE。建议先用opencv_version确认你机器上的OpenCV版本若装的是4系就提前做好改代码的准备。4.2 运行ORB-SLAM2生成轨迹编译完成后运行ORB-SLAM2调用RGB-D模式需要三个参数词袋文件路径、相机参数文件路径和数据集序列路径。以fr1/desk为例./Examples/RGB-D/rgbd_tum \ Vocabulary/ORBvoc.txt \ Examples/RGB-D/TUM1.yaml \ /path/to/fr1_desk执行后程序会加载数据集图像并进行实时跟踪和建图同时可视化窗口会显示当前相机位姿和地图点。当所有图像处理完毕后ORB-SLAM2会在当前目录下生成一个CameraTrajectory.txt文件每行是时间戳、平移三轴和四元数这个文件就是我们要拿来评估的估计轨迹。还有一个可选参数associate.py生成的匹配文件。如果你的数据集图像和真值时间戳偏差较大直接运行时系统可能因时间戳错配找不到对应帧。此时要先跑一遍时间戳匹配生成一个associations.txt文件然后把它作为第三个参数传给程序例如python associate.py rgb.txt depth.txt associations.txt ./Examples/RGB-D/rgbd_tum \ Vocabulary/ORBvoc.txt \ Examples/RGB-D/TUM1.yaml \ /path/to/fr1_desk \ /path/to/associations.txt跑完后再看一眼CameraTrajectory.txt的文件大小如果只有几行说明跟踪出现大面积丢失需要检查关联文件和相机参数是否正确配置。4.3 evo评估与结果解读得到估计轨迹文件后先用evo_traj可视化对比估计轨迹和真值轨迹的整体形状evo_traj tum CameraTrajectory.txt --ref groundtruth.txt -a -p这里--ref指定真值轨迹-a做对齐-p可视化。如果估计轨迹和真值轨迹在整体形态上高度重合说明算法运行正常。如果两条轨迹在起点一致但后续逐渐发散一般就是累积漂移导致属于SLAM的固有特性重点看后面ATE的具体数值来定量判断。接下来正式计算ATE和RPEevo_ape tum groundtruth.txt CameraTrajectory.txt -a -va evo_rpe tum groundtruth.txt CameraTrajectory.txt -r trans_part -d 1 -a -va-va参数会输出详细的对齐参数和每个时间点的误差细节并把误差曲线图保存下来。运行完成后终端会打印RMSE、MAE、Median、Std、Max等统计结果。以fr1/desk为例一个调试正常的ORB-SBAM2系统ATE的RMSE通常在几厘米以内如果结果达到十几厘米甚至更高就要检查是不是有跟踪丢失、参数标定不准确或者时间戳关联出了问题。最后还可以用evo_res合并多次评估结果比如你在调参过程中记录了多次运行结果可以用evo_res把多份误差文件合并统计生成对比表这在做参数消融实验时比较有用。5. 常见问题与排查技巧实录5.1 evo安装和依赖的坑安装evo看似简单实际上依赖问题最容易让人卡住。我帮同事装的时候经常遇到pip在安装numpy或matplotlib过程中报编译错误或者安装完成后一运行evo_ape就提示找不到某个模块。这里提供几个经过验证的排查方向Python版本不要太高3.8到3.10之间最稳3.11以上evo部分依赖可能有兼容问题。优先在conda全新环境里装evo避免系统Python里其他包版本干扰。如果运行evo时报ImportError: libGL.so.1: cannot open shared object file说明系统缺少OpenGL库在Ubuntu上执行sudo apt update sudo apt install libgl1 libglib2.0-0即可解决。evo的绘图依赖tkinter如果你用的是headless服务器跑评估没有GUI环境可以在脚本里用--save_plot参数保存图片而不是弹出窗口或安装python3-tk解决。5.2 轨迹格式不对导致解析失败evo加载轨迹文件时报格式错误是最常见的问题之一。TUM格式要求每一行是timestamp tx ty tz qx qy qz qw注意四元数顺序是x y z wKITTI格式每一行是3x4变换矩阵的12个数字EuRoC格式每一行是timestamp tx ty tz qw qx qy qz旋转部分和TUM的顺序不一样。很多人在网上找到的轨迹文件或者从ROS的话题里导出的数据格式往往不标准直接喂给evo很容易报错。建议拿到轨迹文件后先用head命令看一眼内容结构确认列数是否匹配。另外ROS用户导出的geometry_msgs/PoseStamped话题需要先用evo_traj bag直接加载rosbag再转成TUM或KITTI格式不要手动拼接文本容易出错。5.3 时间戳对齐与插值的选择评估时估计轨迹和真值轨迹的时间戳通常不是一一对应的。evo在加载两个轨迹后会默认做时间戳对齐把真值轨迹插值到估计轨迹的时间点上。这个插值逻辑本身很成熟但如果你在命令行加了--t_offset或--sync参数就要格外小心比如TUM数据集的时间戳单位是秒而KITTI的某些文件时间是微秒如果混用单位对齐结果会完全错误。还有一个常见误区在计算ATE之前不做时间对齐就加-a此时对齐和误差计算会变得混乱。建议先不加-a单纯用evo_traj看一下两条轨迹的时间范围确认时间戳单位、起始时间差再决定是否需要调节时间偏移量。5.4 实操中的几个实用小技巧最后分享几个我在实际评测时总结的小技巧能帮你节省不少时间批量评估如果你在一个数据集上跑了很多参数组合别一个个手敲命令写个shell脚本循环调用evo_ape把结果重定向到CSV文件最后用Excel或Python汇总。在ORB-SLAM运行过程中同步保存轨迹ORB-SLAM2默认只在程序结束后写轨迹但长数据集跑到一半崩溃弹窗轨迹就丢了。可以在代码里加一个回调函数或定期写文件的逻辑保证崩溃前的最新轨迹能保存下来这在调试阶段很救命。用--plot_mode调整绘图视角evo默认的绘图是俯视图xy平面但你如果关心高度方向的漂移可以把--plot_mode改成xyz或者xz多视角看误差明显程度不同往往俯视图看起来贴合得很好换到侧视图就露馅了。同时评估多个轨迹evo_traj支持一次加载多个估计轨迹配合--ref真值轨迹可以在同一张图上对比不同参数下算法表现的差异比跑完一次截图一次直观得多。我个人的体会是数据集、算法、评估工具这三者是一套组合拳缺哪一个都不完整。很多人在调SLAM参数时只盯着可视化窗口看“感觉还挺稳定”缺少量化数据的反馈这样优化起来效率很低。而当你把evo接入日常工作流每次跑完数据都自动计算ATE和RPE算法改进的效果是好是坏就一目了然了。后续如果你想做更严谨的评测还可以把evo集成到你的训练或调参脚本里实现每次实验结束自动出报告效率会提升非常明显。