3. 轨迹数据格式:TUM格式、KITTI格式、EuRoC格式、通用CSV格式
做轨迹评估,第一步就是搞清楚数据长什么样。
我见过不少新手,算法写得飞起,结果数据格式没对齐,评估出来的误差大得离谱。嗯,这种坑我自己也踩过。今天咱们就把四种最常见的轨迹格式掰开揉碎讲清楚。
3.1 TUM格式:最直观的“时间-位置-姿态”
TUM格式来自慕尼黑工业大学,说白了就是最朴素的人眼可读格式。每行8个数字,用空格或逗号隔开。
格式定义:
timestamp tx ty tz qx qy qz qw
其中:
timestamp:时间戳,单位秒,通常是浮点数tx ty tz:平移向量,单位米qx qy qz qw:四元数,表示旋转
举个例子,我项目中经常这样记录轨迹:
1623456789.123 1.234 2.345 3.456 0.707 0.000 0.707 0.000
1623456789.456 1.245 2.356 3.467 0.708 0.001 0.706 0.002
我个人习惯用TUM格式做快速验证。为什么?因为它简单到可以用Excel打开,一眼就能看出轨迹有没有明显跳变。我曾经在调试一个VIO算法时,发现轨迹突然飞出去,就是靠肉眼扫TUM文件发现的——时间戳跳了0.5秒,但位置变了10米,明显是数据同步出了问题。
小技巧:如果你用Python,numpy.loadtxt()可以直接读TUM文件,省去写解析器的麻烦。
3.2 KITTI格式:自动驾驶界的“通用语”
KITTI格式来自KITTI数据集,它不记录时间戳,只记录位姿。每行12个数字,代表一个3x4的变换矩阵。
格式定义:
r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz
实际上就是:
[R | t] 矩阵按行展开
你想想看,为什么KITTI不用四元数?因为自动驾驶里经常需要做矩阵运算,直接给变换矩阵省去了转换的麻烦。
实际数据长这样:
9.999e-01 1.234e-03 2.345e-03 1.234e+00
-1.234e-03 9.999e-01 3.456e-03 2.345e+00
-2.345e-03 -3.456e-03 9.999e-01 3.456e+00
注意:KITTI格式没有时间戳!这意味着你无法做时间对齐。我遇到过有人拿KITTI格式的ground truth和TUM格式的估计轨迹做评估,结果对不上——因为两边帧率不一样。嗯,这种低级错误我也犯过。
3.3 EuRoC格式:视觉惯性SLAM的“标准答案”
EuRoC格式来自EuRoC MAV数据集,它比TUM多了一个东西——协方差矩阵。
格式定义:
timestamp tx ty tz qx qy qz qw cov_matrix_upper_triangle
协方差矩阵是6x6的上三角部分,共21个元素。
说实话,大部分评估工具根本不用协方差。但为什么EuRoC要加?因为视觉惯性SLAM的估计是有不确定性的——比如纯旋转时,平移的协方差会很大。我曾在做无人机定位时,发现轨迹评估结果忽好忽坏,后来发现是协方差没传对,导致优化器把不可靠的位姿当成了硬约束。
数据示例:
1623456789.123 1.234 2.345 3.456 0.707 0.000 0.707 0.000
0.001 0.000 0.000 0.000 0.000 0.000
0.002 0.000 0.000 0.000 0.000
0.003 0.000 0.000 0.000
0.001 0.000 0.000
0.002 0.000
0.003
避坑指南:我曾经在转换EuRoC到TUM格式时,忘了把协方差去掉,结果评估工具报错。所以如果你不需要协方差,记得只取前8列。
3.4 通用CSV格式:想怎么存就怎么存
通用CSV格式没有标准,但通常包含:时间戳、位置、姿态(四元数或欧拉角)。
我个人建议的通用格式:
timestamp, x, y, z, roll, pitch, yaw
1623456789.123, 1.234, 2.345, 3.456, 0.123, 0.456, 0.789
或者用四元数:
timestamp, x, y, z, qx, qy, qz, qw
1623456789.123, 1.234, 2.345, 3.456, 0.707, 0.000, 0.707, 0.000
警告:通用CSV最大的坑是——没有约定!我见过有人把欧拉角写成度,有人写成弧度,还有人把四元数顺序写成qw qx qy qz。所以用CSV时,一定要在文件头或文档里写明格式。
3.5 四种格式对比
| 特性 | TUM | KITTI | EuRoC | 通用CSV |
|---|---|---|---|---|
| 时间戳 | 有 | 无 | 有 | 通常有 |
| 姿态表示 | 四元数 | 旋转矩阵 | 四元数 | 任意 |
| 协方差 | 无 | 无 | 有 | 可选 |
| 可读性 | 高 | 低 | 中 | 高 |
| 适用场景 | SLAM评估 | 自动驾驶 | VIO评估 | 自定义 |
3.6 格式转换:绕不开的苦力活
做轨迹评估,80%的时间花在格式转换上。这不是夸张,我亲身体会。
这里给一个Python转换示例,把TUM转KITTI:
import numpy as np
def tum_to_kitti(tum_file, kitti_file):
data = np.loadtxt(tum_file)
with open(kitti_file, 'w') as f:
for row in data:
t = row[1:4]
q = row[4:8]
# 四元数转旋转矩阵
R = quaternion_to_matrix(q)
# 拼接成3x4矩阵
T = np.column_stack((R, t))
# 按行写入
f.write(' '.join(f'{v:.6e}' for v in T.flatten()) + '\n')
def quaternion_to_matrix(q):
# 标准四元数转旋转矩阵
x, y, z, w = q
return np.array([
[1-2*y*y-2*z*z, 2*x*y-2*z*w, 2*x*z+2*y*w],
[2*x*y+2*z*w, 1-2*x*x-2*z*z, 2*y*z-2*x*w],
[2*x*z-2*y*w, 2*y*z+2*x*w, 1-2*x*x-2*y*y]
])
实用建议:我一般用evo工具做格式转换,它支持TUM、KITTI、EuRoC互转。命令就一行:evo_traj tum traj.txt --save_as_kitti。但如果你要批量处理,还是得自己写脚本。
3.7 知识体系总览
下面这张图总结了四种格式的核心区别和转换关系:
嗯,四种格式讲完了。说白了,TUM最通用,KITTI最简洁,EuRoC最完整,CSV最灵活。选哪个?看你用什么工具、做什么评估。我个人建议:如果只是做SLAM精度评估,TUM格式就够了;如果要做自动驾驶,KITTI是绕不开的;如果做VIO,EuRoC更合适。
记住一句话:格式转换不是技术问题,是细心问题。我见过太多人因为时间戳单位搞错、四元数顺序搞反,浪费一整天调bug。所以,拿到数据第一件事——打开文件看一眼。