KITTI 数据集格式介绍

本文主要记录了有关 KITTI 数据集中点云相关的标注格式以及 PointPillars 中对 KITTI 数据集的处理。

KITTI 数据集的标注格式

name truncated occluded alpha bbox bbox bbox bbox Dimensions/h Dimensions/w Dimensions/l location location location rotation_y
Car 0.00 0 1.85 387.63 181.54 423.81 203.12 1.67 1.87 3.69 -16.53 2.39 58.49 1.57

**注意:**dimension 维度中的顺序为 h,w,l, h 为 lidar 坐标系下沿 z 轴尺寸, w 为 lidar 坐标系下沿 y 轴尺寸,l 为 lidar 坐标系下沿 x 轴尺寸
RoboSense 的标注的 dimension 也是这样,和 kitti 一致。

但是对 location 的不一致。RoboSense 对 location 的标注是 lidar 坐标系下的 x,y,z,但是 kitti 的是 相机坐标系下的 x,y,z,对应的是 lidar 坐标系下的 -y,-z,x.

在代码中,kitti_dataset.pybox_camera_to_lidar 函数将 location 的三个值转换到 lidar 坐标系下,且顺序为 x_lidar, y_lidar, z_lidar,而 robosense 数据集标注时就是这个坐标系,这个顺序,因此不需要做任何改变。

重要::RoboSense 对 rotation_y 的标注和 kitti 不一致,需要将 RoboSense 标注的值 取负 之后再 减去 pi/2,即 -rot - pi/2

PointPillars 中的处理

Kitti_infos_train.pkl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{
'image': {
'image_idx': 0,
'image_path': 'training/image_2/000007.png',
'image_shape': array([375, 1242], dtype=int32)
},

'point_cloud': {
'num_features': 4,
'velodyne_path': 'training/velodyne/000007.bin'
},

'calib': {
'P0': shape [4,4]
'P1': shape [4,4]
'P2': shape [4,4]
'P3': shape [4,4]
'R0_rect': shape [4,4]
'Tr_velo_to_cam': shape [4,4]
'Tr_imu_to_velo': shape [4,4]
},

'annos':{
'name': array(['Car', 'Car', 'Car', 'Cyclist', 'DontCare', 'DontCare'], dtype='<U8'),
'truncated': array([0., 0., 0., 0., -1., -1.]),
'occluded': array([0, 0, 0, 0, -1, -1]),
'alpha': array([-1.56, 1.71, 1.64, 1.89, -10., -10.]),
'bbox':
array([[564.62, 174.59, 616.43, 224.74],
[481.59, 180.09, 512.55, 202.42],
[542.05, 175.55, 565.27, 193.79],
[330.6 , 176.09, 355.61, 213.6 ],
[753.33, 164.32, 798. , 186.74],
[738.5 , 171.32, 753.27, 184.42]]),
'dimensions':
array([[ 3.2 , 1.61, 1.66],
[ 3.7 , 1.4 , 1.51],
[ 4.05, 1.46, 1.66],
[ 1.95, 1.72, 0.5 ],
[-1. , -1. , -1. ],
[-1. , -1. , -1. ]]),
'location':
array([[-6.900e-01, 1.690e+00, 2.501e+01],
[-7.430e+00, 1.880e+00, 4.755e+01],
[-4.710e+00, 1.710e+00, 6.052e+01],
[-1.263e+01, 1.880e+00, 3.409e+01],
[-1.000e+03, -1.000e+03, -1.000e+03],
[-1.000e+03, -1.000e+03, -1.000e+03]]),

'rotation_y': array([-1.59, 1.55, 1.56, 1.54, -10., -10.]),
'score': array([0., 0., 0., 0., 0., 0.]),
'index': array([0, 1, 2, 3, -1, -1], dtype=int32),
'group_ids': array([0, 1, 2, 3, 4, 5], dtype=int32),
'difficulty': array([0, -1, -1, 1, -1, -1], dtype=int32),
'num_points_in_gt': array([130, 21, 5, 12, -1, -1], dtype=int32)}
}
}

KITTI 和 RoboSnese 的点云数据格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Kitti: Train/000000.bin
In [20]: np.min(kitti_points, axis=0)
Out[20]: array([4.535, -16.133, -2.347, 0.], dtype=float32)

In [21]: np.max(kitti_points, axis=0)
Out[21]: array([73.039, 23.589, 2.644, 0.99], dtype=float32)

Robo: train/000000.bin
In [22]: np.min(robo_points, axis=0)
Out[22]:
array([4.4810915, -170.61516, -15.27258, 0.], dtype=float32)

In [23]: np.max(robo_points, axis=0)
Out[23]: array([188.42923, 30.45892, 14.691492, 1.], dtype=float32)

可以看出,Kitti 和 RoboSense 在点云数据格式上是一致的,都是 lidar 坐标系下的 x,y,z,r.

KITTI 和 RoboSense 数据集在 PointPillars 代码中的不同处理

在尝试使用 RoboSense 数据集进行训练的时候,发现了很多 RoboSense 数据集和 KITTI 数据集的不同之处,因此记录下来。

  • kitti_infos_train.pkl 中,annos 下 dimension 的顺序与标注文件的顺序有差别,将原来的 [0,1,2] 变成了 [2,0,1], (kitti_common.py/get_label_anno()) annos 下 location 的顺序与标注文件的顺序一致。
  • Kitti_dataset.py 中
1
gt_boxes = box_np_ops.box_camera_to_lidar(gt_boxes, calib["R0_rect"], calib["Tr_velo_to_cam"])

将 gt box 从 camera 坐标系转换到了 lidar 坐标系。

  • 在 box_camera_to_lidar() 中, xyz 是 gt box 底面中心点camera 坐标系下的 x,y,z 坐标,而得到的 xyz_lidar 是中心点在 lidar 坐标系下的 x,y,z 坐标。
  • RoboSense 对 rotation_y 的标注和 kitti 不一致,需要将 RoboSense 标注的值取负之后再减去 pi/2,即 -rot - pi/2.
  • Kitti 数据集中,调用了 box_np_ops.box_camera_to_lidar 将中心点从 相机坐标系 转换到 雷达坐标系,且对 dimension 的三个维度进行了重排,从 l,h,w 变成了 w,l,h. 由于 RoboSense 的数据不需要调用 box_np_ops.box_camera_to_lidar,因此后面要手动对 RoboSense 的数据的 dimension 的三个维度进行重排。

点云目标检测的经验总结

  1. 当雷达 XoY 平面与地面平行时,采集到的地面上的点的 Z 轴坐标值基本是一致的。

  2. 但是当雷达的姿态绕 Y 轴向下旋转一定角度后(雷达向下照射),采集到的地面上的点的Z轴的值不再是基本一致的了。而是会呈现出一种斜向上的状态。

  3. 这是因为,当雷达绕 Y 轴向下旋转后(X 轴和 Z 轴发生了旋转),地面上某一固定点在旋转后的坐标系中,Z 轴的坐标值变大,如 -5->-3。而越远处地面上的点的 Z 轴的值会越大。因而形成了一个斜向上的趋势。
    雷达绕 Y 轴旋转后 Z 轴坐标值的变化

  4. 在对自己采集的点云图像进行测试时,需要通过调整绕 X 轴和 Y 轴的旋转角度(乘以旋转矩阵)来将路面上的点调平,也就是路面上的点云的 Z 轴坐标值基本在一个很小的范围内,且这个范围应该在模型的检测范围内。同时也要考虑,大车顶部的点在调整路面点的 Z 轴后,是否超出 Z 轴检测范围。因为如果超出的话,会导致大车顶部的一些点无法参与到模型的计算中去。因为其在构造 pillars 的时候就已经被丢弃了。

  5. 发现当雷达架设过高,俯视程度过大的时候,现有的模型检测效果不好。推测是由于训练集是在车上采集的,视角相对较平。而俯视视角采集的点云数据和训练集偏差较大,造成效果不好。在采集的两段数据中,较高的天桥上效果不好,但是较低的台阶上效果还可以。


文章作者: taosean
文章链接: https://taosean.github.io/2021/12/12/KITTI-Dataset/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 taosean's 学习之旅