写点什么

kitti 数据集在 3D 目标检测中的入门

作者:Studying_swz
  • 2022-11-20
    天津
  • 本文字数:6172 字

    阅读完需:约 20 分钟

kitti数据集在3D目标检测中的入门

数据集官网下载地址:http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d



3D 目标检测数据集由 7481 个训练图像和 7518 个测试图像以及相应的点云数据组成,包括总共 80256 个标记对象。上图红色框标记的为我们需要的数据,分别是彩色图像数据(12GB)、点云数据(29GB)、相机矫正数据(16MB)、标签数据(5MB)。其中彩色图像数据、点云数据、相机矫正数据均包含 training(7481)和 testing(7518)两个部分,标签数据只有 training 数据。需要填写邮箱,然后会给发送下载链接(但是很慢)!!!可以通过---KITTI 数据集下载(百度云)https://blog.csdn.net/u013086672/article/details/103910266

一:目前 3D 点云在目标检测的算法历程


其中,point representation、Voxel representation、graph representation 的详解见参考链接 7。



其中上半部分主要是利用了图片以及激光雷达作为输入,例如 F-PointNet 网络先从 2D 图片上检测出目标,然后投影到 3D 点云中。但是这种方法存在遮挡等问题。然后下半部分是仅仅利用了激光雷达的点云作为输入,其中同理分为两种类型,一是基于无规则的点云直接提取特征做检测即 Point-based,另一种是 Voxel-based,其主要先把无规则点云处理为有规则的,然后再提取特征。这里注意的是 AP 主要是 car 的检测,再行人检测其没有还这么好的效果,因为很多物体和人比较相似所以误差较大。

二:kitti 数据集的采集

KITTI 数据集的数据采集平台装配有 2 个灰度摄像机,2 个彩色摄像机,一个 Velodyne 64 线 3D 激光雷达,4 个光学镜头,以及 1 个 GPS 导航系统。



为了生成双目立体图像,相同类型的摄像头相距 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)images 文件



2)velodyne 文件





效果图如下:



3)calib 文件





注:这里可以将 label 中照相机标注的 3D 目标检测框的中心坐标通过上面公式映射到点云中物体的真实检测框,这样的话都是三位坐标系的转换,那么对于 2D 目标检测框如何从点云中来得到的,这是个问题!!!!------这段理解是错的。。应该是:从雷达坐标系变换到 xx 号相机的图像坐标系的公式:设 X 为雷达坐标系中的齐次坐标,Y 为对应在 xx 号相机的图像坐标系的齐次坐标,则



以上是对于 raw data,对于目标检测其转换是:



(R|T) : 雷达坐标系 -> 0 号相机坐标系 R_rect_00: 0 号相机坐标系 -> 矫正后的 0 号相机坐标系 P_rect_0x: 矫正后的 0 号相机坐标系 -> x 号相机的图像平面从上面可以看出主要是从三维到二维平面的转换!!!效果图:待!!重要注意:补充理解:在经过了之后的资料查询,有了之间的大体关系的认知,先重新将部分理解的梳理一遍:校准文件如上面所示,其主要包括,从 3D 激光雷达的点云坐标 x 映射到 0 号相机的坐标系 Tr_velo_to_cam * x(因为两者的三维空间的坐标系的标定是不一样的,可能不对);R0_rect Tr_velo_to_cam * x,其中校准是为了使多个摄像机的图像位于同一平面上,即所对应的图片*;**然后可以将其投影到对应的图片上,P_rect_2 * R0_rect *Tr_velo_to_cam * x ,注(等价将投影面向左移动同时保持针孔位置不变,即可投影到彩色摄像机的图片上)。然后在这里的两个测试第一个测试是将 3D 边界框从标签文件投影到图像上第二项测试是将点云坐标中的一个点投影到图像上。代数很简单,如下所示第一个等式用于将 3D 绑定框投影到与 camera_2 图像协调的参考摄像机中。第二个方程将 Velodyne 坐标点投影到 camera_2 图像中。y_image = P2 * R0_rect * R0_rot * x_ref_coordy_image = P2 * R0_rect * Tr_velo_to_cam * x_velo_coord 在上面,R0_rot 是要从对象坐标映射到参考坐标的旋转矩阵。”重要注意:补充理解 2:内参矩阵+外参矩阵点云到相机的坐标转换:见https://blog.csdn.net/qq_33801763/article/details/77033064?utm_medium=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant_right.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase部分内容摘取:1.内参矩阵:设空间中有一点 P,若世界坐标系与相机坐标系重合,则该点在空间中的坐标为(X, Y, Z),其中 Z 为该点到相机光心的垂直距离。设该点在像面上的像为点 p,像素坐标为(x, y)。



由上图可知,这是一个简单的相似三角形关系,从而得到



但是,图像的像素坐标系原点在左上角,而上面公式假定原点在图像中心,为了处理这一偏移,设光心在图像上对应的像素坐标为(cx,cy),则




2.外参矩阵以上情况是世界坐标系与相机坐标系重合的特殊情况,而在一般情况下,世界坐标系中的某一点 P 要投影到像面上时,先要将该点的坐标转换到相机坐标系下。设 P 在世界坐标系中的坐标为 X,P 到光心的垂直距离为 s(即上文中的 Z),在像面上的坐标为 x,世界坐标系与相机坐标系之间的相对旋转为矩阵 R(R 是一个三行三列的旋转矩阵),相对位移为向量 T(三行一列),则



其中[R T]是一个三行四列的矩阵,称为外参矩阵,它和相机的参数无关,只与相机在世界坐标系中的位置有关。3.点云到相机的坐标转换





表示相对于参考相机 0 的基线(以米为单位)。为了在参考相机坐标中将 3D 点 X 投影到第 i 个相机图像面上的点 Y,相机 0 的矫正旋转矩阵 R_{rect}^{(0)} $ 也必须考虑进去,所以:




图像校正:https://www.cnblogs.com/xiaoboge/p/10529971.html


补充粗略坐标系转换:







4)label 文件



每一行代表一个 object,每一行都有 16 列分别表示不同的含义,具体如下:第 1 列(字符串):代表物体类别(type)总共有 9 类,分别是:Car、Van、Truck、Pedestrian、Person_sitting、Cyclist、Tram、Misc、DontCare。其中 DontCare 标签表示该区域没有被标注,比如由于目标物体距离激光雷达太远。为了防止在评估过程中(主要是计算 precision),将本来是目标物体但是因为某些原因而没有标注的区域统计为假阳性(false positives),评估脚本会自动忽略 DontCare 区域的预测结果。第 2 列(浮点数):代表物体是否被截断(truncated)数值在 0(非截断)到 1(截断)之间浮动,数字表示指离开图像边界对象的程度。第 3 列(整数):代表物体是否被遮挡(occluded)整数 0、1、2、3 分别表示被遮挡的程度。第 4 列(弧度数):物体的观察角度(alpha)取值范围为:-pi ~ pi(单位:rad),它表示在相机坐标系下,以相机原点为中心,相机原点到物体中心的连线为半径,将物体绕相机 y 轴旋转至相机 z 轴,此时物体方向与相机 x 轴的夹角,如图 1 所示。第 5~8 列(浮点数):物体的 2D 边界框大小(bbox)四个数分别是 xmin、ymin、xmax、ymax(单位:pixel),表示 2 维边界框的左上角和右下角的坐标。第 9~11 列(浮点数):3D 物体的尺寸(dimensions)分别是高、宽、长(单位:米)第 12-14 列(整数):3D 物体的位置(location)分别是 x、y、z(单位:米),特别注意的是,这里的 xyz 是在相机坐标系下 3D 物体的中心点位置。第 15 列(弧度数):3D 物体的空间方向(rotation_y)取值范围为:-pi ~ pi(单位:rad),它表示,在照相机坐标系下,物体的全局方向角(物体前进方向与相机坐标系 x 轴的夹角),如图 1 所示。



第 16 列(整数):检测的置信度(score)要特别注意的是,这个数据只在测试集的数据中有。5)development kit 文件下载 raw data development kit,其中的 readme 文件详细记录了你想知道的一切,数据采集装置,不同装置的数据格式,label 等。即以上的所有信息都在此文件中介绍了。

四:点云可视化

程序:


import numpy as npimport mayavi.mlab #000010.bin这里需要填写文件的位置pointcloud = np.fromfile(str("000010.bin"), dtype=np.float32, count=-1).reshape([-1,4]) print(pointcloud.shape)x = pointcloud[:, 0]  # x position of pointy = pointcloud[:, 1]  # y position of pointz = pointcloud[:, 2]  # z position of pointr = pointcloud[:, 3]  # reflectance value of pointd = np.sqrt(x ** 2 + y ** 2)  # Map Distance from sensor  vals='height'if vals == "height":    col = zelse:    col = d fig = mayavi.mlab.figure(bgcolor=(0, 0, 0), size=(640, 500))mayavi.mlab.points3d(x, y, z,                     col,          # Values used for Color                     mode="point",                     colormap='spectral', # 'bone', 'copper', 'gnuplot'                     # color=(0, 1, 0),   # Used a fixed (r,g,b) instead                     figure=fig,                     ) x=np.linspace(5,5,50)y=np.linspace(0,0,50)z=np.linspace(0,5,50)mayavi.mlab.plot3d(x,y,z)mayavi.mlab.show()
复制代码


图示:



注意:需要顺序安装的包 vtk、mayavi 这里推荐 whl 下载,因为 pip 直接安装 vtk 比较慢,下载地址:https://download.csdn.net/download/qq_37534947/12515312这里需要注意的是,这里的点云可视化后,和下面点云+检测框的可视化的 ,点云显示不太一样。

五:kitti LIDAR 点云生成鸟瞰图 BEV

import numpy as npfrom PIL import Imageimport matplotlib.pyplot as plt # 点云读取pointcloud = np.fromfile(str("000010.bin"), dtype=np.float32, count=-1).reshape([-1, 4])# 设置鸟瞰图范围side_range = (-40, 40)  # 左右距离fwd_range = (0, 70.4)  # 后前距离 x_points = pointcloud[:, 0]y_points = pointcloud[:, 1]z_points = pointcloud[:, 2] # 获得区域内的点f_filt = np.logical_and(x_points > fwd_range[0], x_points < fwd_range[1])s_filt = np.logical_and(y_points > side_range[0], y_points < side_range[1])filter = np.logical_and(f_filt, s_filt)indices = np.argwhere(filter).flatten()x_points = x_points[indices]y_points = y_points[indices]z_points = z_points[indices] res = 0.1  # 分辨率0.05mx_img = (-y_points / res).astype(np.int32)y_img = (-x_points / res).astype(np.int32)# 调整坐标原点x_img -= int(np.floor(side_range[0]) / res)y_img += int(np.floor(fwd_range[1]) / res)print(x_img.min(), x_img.max(), y_img.min(), x_img.max()) # 填充像素值height_range = (-2, 0.5)pixel_value = np.clip(a=z_points, a_max=height_range[1], a_min=height_range[0])  def scale_to_255(a, min, max, dtype=np.uint8):  return ((a - min) / float(max - min) * 255).astype(dtype)  pixel_value = scale_to_255(pixel_value, height_range[0], height_range[1]) # 创建图像数组x_max = 1 + int((side_range[1] - side_range[0]) / res)y_max = 1 + int((fwd_range[1] - fwd_range[0]) / res)im = np.zeros([y_max, x_max], dtype=np.uint8)im[y_img, x_img] = pixel_value # imshow (灰度)im2 = Image.fromarray(im)im2.show() # imshow (彩色)# plt.imshow(im, cmap="nipy_spectral", vmin=0, vmax=255)# plt.show()
复制代码


图示:


六:训练集可视化(包括图片的 2D 和 3D 检测框以及点云的 3D 检测框,但不包含仅仅是点云的可视化)

由于 pointRCNN 源码的训练和 inference 很详细,但是没有可视化的代码,本文介绍其 3d 框结果的可视化方法 github 连接:https://github.com/sshaoshuai/PointRCNN1)将 pointRCNN 预测结果拷贝到 KITTI 数据集 pointRCNN 的结果存储在:(里面包含 000001.txt 等等,存的是 3d 框的预测结果)PointRCNN/output/rcnn/default/eval/epoch_no_number/val/final_result 把整个文件夹复制到 kitti 数据集的 training 目录下,文件夹命名 pred 数据组织结构如下:(注意,这里的 training 里面是全部 7481 张图,不然会报错没有 000000.txt)



2) 运行可视化源码 kitti_object_vis 源码地址:https://github.com/kuixu/kitti_object_vis首先:下载源码并进到源码文件夹'git clone https://github.com/kuixu/kitti_object_vis其次:把上述 kitti 数据集的 object/目录,链接到 data/目录下过去,并命名为 obj(因为这个源码需求)cd kitti_object_vis/dataln -s /home/ubuntu/dataset/KITTI/object obj 然后:下载源码和源码所需的库(mayavi 之类的),照 readme 里面去做最后:运行(1) 只显示 LiDAR 仅真值 cd kitti_object_vispython kitti_object.py --show_lidar_with_depth --img_fov --const_box --vis(回车键进入下一张)(2) 显示 LiDAR 和 image 仅真值 python kitti_object.py --show_lidar_with_depth --img_fov --const_box --vis --show_image_with_boxes(回车键进入下一张)(3) 显示特定某张图的 LiDAR 和 image 仅真值 python kitti_object.py --show_lidar_with_depth --img_fov --const_box --vis --show_image_with_boxes --ind 100(ind 100 表示就是图像编号为 000100.txt)注:红色是预测框,绿色是真值框

(4)** 显示 pointRCNN 预测值**+真值对比**在以上所有命令后面加 -ppython kitti_object.py --show_lidar_with_depth --img_fov --const_box --vis --show_image_with_boxes --ind 6 -p




可以看到:对于预测的 3D 点云检测框,只能在 lidar 中展示,暂且不知道如何将其转换到图片上进行 2D 和 3D 的展示,即 image 中只能显示 gt,无法显示预测结果。我的理解:在输入图片训练的时候,将 3D 照相机的坐标映射到点云中的坐标系中,但是不知道准确的映射关系;另外在输出的时候会检测到 2D 和 3D 的坐标,从而我认为 3D 的照相机坐标就是点云中的坐标,并且为什么存在 2D 坐标,可能 3D 和 2D 坐标也有一定的映射关系-----待。

七:KITTI 3D Object Detection Evaluation 结果评估程序

在对 KITTI 数据集进行预测得到结果后,如何对结果进行评估呢?其实,官方就给出了结果评估程序,在官网上就可以下载:http://www.cvlibs.net/datasets/kitti/eval_object.php?obj_benchmark=3d在如上网址中,点击 Download object development kit ,就可以下载了。



下载完成后,在文件夹 devkit_object\cpp 中,可以看到一个 cpp 文件: evaluate_object.cpp ,该文件就是对 KITTI 结果数据集进行评估的程序了。或者从 github 中下载,可以利用 git clone https://github.com/prclibo/kitti_eval.git进行下载获取。目录结构如下:



使用步骤:1.安装 g++ -o evaluate_object_3d_offline evaluate_object_3d_offline.cpp2.目录存放结构 KITTI 标签文件需要存放在:。。。label_2 预测结果文件存放在:resluts/data (含有得分)结果评估文件需要存放在: results/plot



其中预测结果也可以自己模仿:如果是自己生成,需要注意的有:①将标签改为三类,为了改变 P,R 值可将标签复制三行,然后后面加上不同的置信度 3.开始评估./evaluate_object_3d_offline gt_dir result_dir 其中 gt_dir 是上面的 label2 的目录,而 result_dir 是上面的预测结果 results 的目录。结果如下图:



发布于: 2022-11-20阅读数: 19
用户头像

Studying_swz

关注

还未添加个人签名 2020-12-23 加入

还未添加个人简介

评论

发布
暂无评论
kitti数据集在3D目标检测中的入门_3D点云_Studying_swz_InfoQ写作社区