1.1 KITTI数据集介绍和下载方式
KITTI数据集由德国卡尔斯鲁厄理工学院和丰田美国技术研究院联合创办,是目前国际上最大的自动驾驶场景下的计算机视觉算法评测数据集。该数据集用于评测立体图像(stereo),光流(optical flow),视觉测距(visual odometry),3D物体检测(object detection)和3D跟踪(tracking)等计算机视觉技术在车载环境下的性能。KITTI包含市区、乡村和高速公路等场景采集的真实图像数据,每张图像中最多达15辆车和30个行人,还有各种程度的遮挡与截断。整个数据集由389对立体图像和光流图,39.2 km视觉测距序列以及超过200k 3D标注物体的图像组成 ,以10Hz的频率采样及同步。总体上看,原始数据集被分类为’Road’, ’City’, ’Residential’, ’Campus’ 和 ’Person’。对于3D物体检测,label细分为car, van, truck, pedestrian, pedestrian(sitting), cyclist, tram以及misc组成。
KITTI数据集包括了很多任务,针对检测任务提供了14999张图像及对应的点云,7481个样本用于训练,7518个样本用于测试。但测试样本我们是不可见的,所以一般将7481个训练样本划分为3712与3769分别作为训练集和测试集。
1.1.1 KITTI的采集方式
KITTI 数据集的数据采集平台装配有2个灰度摄像机,2个彩色摄像机,一个Velodyne 64线3D激光雷达,4个光学镜头,以及1个GPS导航系统。具体的传感器参数如下:
-
2 × PointGray Flea2 grayscale cameras (FL2-14S3M-C), 1.4 Megapixels, 1/2” Sony ICX267 CCD, global shutter
2 台 PointGray Flea2灰度相机(FL2-14S3M-C), 140万像素,1/2英寸索尼ICX267 CCD,全局快门
-
2 × PointGray Flea2 color cameras (FL2-14S3C-C), 1.4 Megapixels, 1/2” Sony ICX267 CCD, global shutter
2台PointGray Flea2彩色相机(FL2-14S3C-C), 140万像素,1/2英寸索尼ICX267 CCD,全局快门
-
1 × Velodyne HDL-64E rotating 3D laser scanner, 10 Hz, 64 beams, 0.09 degree angular resolution, 2 cm distance accuracy, collecting ∼ 1.3 million points/second, field of view: 360◦ horizontal, 26.8◦ vertical, range: 120 m
1 台Velodyne HDL-64E旋转3D激光扫描仪,10赫兹,64光束,0.09度角分辨率,2厘米距离精度,收集~ 130万点/秒,视野:360◦水平,26.8◦垂直,范围:120米
-
1 × OXTS RT3003 inertial and GPS navigation system, 6 axis, 100 Hz, L1/L2 RTK, resolution: 0.02m / 0.1
1 台 OXTS RT3003惯性和GPS导航系统,6轴,100 Hz, L1/L2 RTK,分辨率:0.02m / 0.1
从传感器分布平面图可以看出,为了生成双目立体图像,相同类型的摄像头相距54cm安装。由于彩色摄像机的分辨率和对比度不够好,所以还使用了两个立体灰度摄像机,它和彩色摄像机相距6cm安装。为了方便传感器数据标定,规定坐标系方向如下 :
- Camera: x = right, y = down, z = forward
- Velodyne: x = forward, y = left, z = up
- GPS/IMU: x = forward, y = left, z = up
1.1.2 KITTI下载方式
您可以在这里下载 KITTI 3D 检测数据并解压缩所有 zip 文件。此外,您可以在这里下载道路平面信息,其在训练过程中作为一个可选项,用来提高模型的性能。道路平面信息由 AVOD 生成,更多细节请参考此处。
像准备数据集的一般方法一样,建议将数据集根目录链接到 $MMDETECTION3D/data
。
文件夹结构应该按照如下方式组织:
mmdetection3d
├── mmdet3d
├── tools
├── configs
├── data
│ ├── kitti
│ │ ├── ImageSets
│ │ ├── testing
│ │ │ ├── calib
│ │ │ ├── image_2
│ │ │ ├── velodyne
│ │ ├── training
│ │ │ ├── calib
│ │ │ ├── image_2
│ │ │ ├── label_2
│ │ │ ├── velodyne
│ │ │ ├── planes (optional)
我们可以进入官方网站 The KITTI Vision Benchmark Suite (cvlibs.net)下载KITTI3D数据集,注意没注册的需要先注册,并注明下载数据集的用途。也可以通过网友分享的链接下载,百度云链接: 此处 ,提取码:2lyj
,点云算法需要用到以下四个数据。当然如果你想尝试在小型数据集上练习,可以点击此处下载已经划分好的阉割版KITTI数据集。
它们依次是:
- data_object_imgae_2
- data_object_velodyne
- data_object_calib
- data_objtct_label_2
1.2 每个数据格式分别是什么?
按照上述文件夹结构组织好数据集之后,我们可以来看看对应的文件都是什么样的。
-
图像数据(
data_ object_image_ 2
)包含驾驶的场景图像
-
标注数据(
data_ object_label 2
)标注数据只需要放在训练集里面就可以,文件是txt格式
Pedestrian 0.00 0 -0.20 712.40 143.00 810.73 307.92 1.89 0.48 1.20 1.84 1.47 8.41 0.01
- 第1列:目标类比别(type),共有8种类别,分别是Car、Van、Truck、Pedestrian、Person_sitting、Cyclist、Tram、Misc或’DontCare。DontCare表示某些区域是有目标的,但是由于一些原因没有做标注,比如距离激光雷达过远。但实际算法可能会检测到该目标,但没有标注,这样会被当作false positive (FP)。这是不合理的。用DontCare标注后,评估时将会自动忽略这个区域的预测结果,相当于没有检测到目标,这样就不会增加FP的数量了。此外,在 2D 与 3D Detection Benchmark 中只针对 Car、Pedestrain、Cyclist 这三类。
- 第2列:截断程度(truncated),表示处于边缘目标的截断程度,取值范围为0~1,0表示没有截断,取值越大表示截断程度越大。处于边缘的目标可能只有部分出现在视野当中,这种情况被称为截断。
- 第3列:遮挡程度(occlude),取值为(0,1,2,3)。0表示完全可见,1表示小部分遮挡,2表示大部分遮挡,3表示未知(遮挡过大)。
- 第4列:观测角度(alpha),取值范围为(− π , π )。是在相机坐标系下,以相机原点为中心,相机原点到物体中心的连线为半径,将物体绕相机y轴旋转至相机z轴,此时物体方向与相机x轴的夹角。这相当于将物体中心旋转到正前方后,计算其与车身方向的夹角。
- 第5-8列:二维检测框(bbox),目标二维矩形框坐标,分别对应
left、top、right、bottom
,即左上(x,y)和右下的坐标(x,y)。 - 第9-11列:三维物体的尺寸(dimensions),分别对应高度、宽度、长度,以米为单位。
- 第12-14列:中心坐标(location),三维物体中心在相机坐标系下的位置坐标(x,y,z),单位为米。
- 第15列:旋转角(rotation_y),取值范围为(− π , π )。表示车体朝向,绕相机坐标系y轴的弧度值,即物体前进方向与相机坐标系x轴的夹角。rolation_y与alpha的关系为alpha=rotation_y - theta,theta为物体中心与车体前进方向上的夹角。alpha的效果是从正前方看目标行驶方向与车身方向的夹角,如果物体不在正前方,那么旋转物体或者坐标系使得能从正前方看到目标,旋转的角度为theta。
- 第16列:置信度分数(score),仅在测试评估的时候才需要用到。置信度越高,表示目标越存在的概率越大。
-
激光雷达数据(
data_ object_velodyne
)该文件夹下包含
tarining
和testing
两个文件夹,两个文件夹下各自包含了velodyne
文件,velodyne
文件夹下存储了点云文件,以bin格式存储。激光雷达坐标系中,z方向是高度方向,x方向是汽车前进方向,前进左手边方向为y方向,满足右手定则。from mayavi import mlab import numpy as np def viz_mayavi(points, vals="distance"): x = points[:, 0] # x position of point y = points[:, 1] # y position of point z = points[:, 2] # z position of point fig = mlab.figure(bgcolor=(0, 0, 0), size=(640, 360)) mlab.points3d(x, y, z, z, # Values used for Color mode="point", colormap='spectral', # 'bone', 'copper', 'gnuplot' # color=(0, 1, 0), # Used a fixed (r,g,b) instead figure=fig, ) mlab.savefig("mayavi_visualization.png") # Save the visualization as an image mlab.close(fig) # Close the Mayavi figure if __name__ == '__main__': points = np.fromfile('./data/kitti_tiny_3D/training/velodyne/000000.bin', dtype=np.float32).reshape([-1, 4]) viz_mayavi(points)
-
标定校准数据(
data_ object_calib
)标定校准数据主要是把激光雷达坐标系测得的点云坐标转换到相机坐标中去。
一个典型的标定文件如下表示:
P0: 7.215377000000e+02 0.000000000000e+00 6.095593000000e+02 0.000000000000e+00 0.000000000000e+00 7.215377000000e+02 1.728540000000e+02 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00 P1: 7.215377000000e+02 0.000000000000e+00 6.095593000000e+02 -3.875744000000e+02 0.000000000000e+00 7.215377000000e+02 1.728540000000e+02 0.000000000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 0.000000000000e+00 P2: 7.070493000000e+02 0.000000000000e+00 6.040814000000e+02 4.575831000000e+01 0.000000000000e+00 7.070493000000e+02 1.805066000000e+02 -3.454157000000e-01 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 4.981016000000e-03 P3: 7.215377000000e+02 0.000000000000e+00 6.095593000000e+02 -3.395242000000e+02 0.000000000000e+00 7.215377000000e+02 1.728540000000e+02 2.199936000000e+00 0.000000000000e+00 0.000000000000e+00 1.000000000000e+00 2.729905000000e-03 R0_rect: 9.999128000000e-01 1.009263000000e-02 -8.511932000000e-03 -1.012729000000e-02 9.999406000000e-01 -4.037671000000e-03 8.470675000000e-03 4.123522000000e-03 9.999556000000e-01 Tr_velo_to_cam: 6.927964000000e-03 -9.999722000000e-01 -2.757829000000e-03 -2.457729000000e-02 -1.162982000000e-03 2.749836000000e-03 -9.999955000000e-01 -6.127237000000e-02 9.999753000000e-01 6.931141000000e-03 -1.143899000000e-03 -3.321029000000e-01 Tr_imu_to_velo: 9.999976000000e-01 7.553071000000e-04 -2.035826000000e-03 -8.086759000000e-01 -7.854027000000e-04 9.998898000000e-01 -1.482298000000e-02 3.195559000000e-01 2.024406000000e-03 1.482454000000e-02 9.998881000000e-01 -7.997231000000e-01
p0, p1, p2, p3 代表相机编号:
编号 说明 p0 左边灰度相机 p1 右边灰度相机 p2 左边彩色相机 p3 右边彩色相机 R0_rect: 为0号相机的修正矩阵 Tr_velo_to_cam: velodyne到camera的矩阵,包含了旋转矩阵 R 和 平移向量 t. Tr_imu_to_velo: imu到camera的矩阵,包含了旋转矩阵 R 和 平移向量 t. 整个过程可以表示为下图:
1.3 MMDet3D中的坐标系
由上图可知,3D检测任务重包含多个传感器,分为两种坐标系,一种是蓝色的激光点云坐标系,一种是红色的相机坐标系。
-
激光点云坐标系(蓝色)
x,y平面为地平面,z表示垂直
-
相机坐标系(红色)
x,y平面与图像相似,z表示向前
激光雷达和相机之间存在水平和竖直方向的偏移,激光点云坐标系要想转到相机坐标系,需要旋转,同时加上两个方向的位移。除了x,y坐标之外,3D检测还需要针对每个物体给出它在水平方向的转角,KITTI数据集中转角是在相机坐标系下的。当一个物体朝向x轴正半轴的时候,那么这个转角就是0度。朝向z轴的话就是-90度,这是右手坐标系的约束,当我们伸开右手,大拇指向下,对应相机坐标系的y轴,四指向右,对应相机坐标系的x轴,然后握拳,握拳的方向就是z轴的负半轴,对应是90度,所以z轴的正半轴就是-90度。
上图是MMDet3D自己定义的坐标系,RGBD深度相机的深度坐标系,激光雷达的雷达坐标系,相机坐标系,雷达坐标系、相机坐标系与KITTI坐标系一致,不同的是转角的定义,MMDet3D中转角的定义:以相机坐标系的转角为例,伸出右手,大拇指指向纸面内部,四指指向x轴(朝右是0度),那么握拳的方向对应的是z的负半轴,是正的旋转角度。所以z的正半轴就是负的转角。以雷达坐标系的转角为例,伸出右手,大拇指指向纸面外部,四指指向x轴,那么握拳的方向对应的是y轴的正半轴,角度是正的,y轴的负半轴角度就是负的,通俗来说,就是MMDet3D中雷达坐标系,朝向右是-90度,朝前是0度,KITTI中朝右是0度,朝前是-90度。所以KITTI的转角定义在相机坐标系下,放到MMDet3d的雷达坐标系下需要变换。
为了方便训练,MMDet3D还需要将KITTI中的数据进一步转换,将存储在文本文件中的相机矩阵、标注等信息集中存储在pkl文件中。
命令行工具:
python tools/create_data.py kitti --root-path ./data/kitti --out-dir ./data/kitti --extra-tag kitti
后续步骤可以参考官方手册数据预处理 — MMDetection3D 1.2.0 文档