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格式 时间戳 + 位置 + 四元数 SLAM评估常用 KITTI格式 3×4变换矩阵 无时间戳 自动驾驶标准 EuRoC格式 TUM + 协方差 21个协方差元素 VIO评估专用 通用CSV 自定义列 灵活但无标准 通用场景 转矩阵 加协方差 矩阵转四元数 双向转换 核心要点 • 时间戳:TUM和EuRoC必须带,KITTI不带,CSV看心情 • 姿态表示:四元数(TUM/EuRoC) vs 旋转矩阵(KITTI) • 协方差:只有EuRoC有,但大部分评估工具用不上 • 转换工具:evo、自己写Python脚本、或者MATLAB • 避坑:格式不对齐,评估结果全是错的——我吃过这个亏

嗯,四种格式讲完了。说白了,TUM最通用,KITTI最简洁,EuRoC最完整,CSV最灵活。选哪个?看你用什么工具、做什么评估。我个人建议:如果只是做SLAM精度评估,TUM格式就够了;如果要做自动驾驶,KITTI是绕不开的;如果做VIO,EuRoC更合适。

记住一句话:格式转换不是技术问题,是细心问题。我见过太多人因为时间戳单位搞错、四元数顺序搞反,浪费一整天调bug。所以,拿到数据第一件事——打开文件看一眼。

可可精品资料库