数据集官网下载地址:
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_coord
y_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 np
import 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 point
y = pointcloud[:, 1] # y position of point
z = pointcloud[:, 2] # z position of point
r = pointcloud[:, 3] # reflectance value of point
d = np.sqrt(x ** 2 + y ** 2) # Map Distance from sensorvals='height'
if vals == "height":col = z
else:col = dfig = mayavi.mlab.figure(bgcolor=(0, 0, 0), size=(640, 500))
mayavi.mlab.points3d(x, y, z,col, # Values used for Colormode="point",colormap='spectral', # 'bone', 'copper', 'gnuplot'# color=(0, 1, 0), # Used a fixed (r,g,b) insteadfigure=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 np
from PIL import Image
import 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.05m
x_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/PointRCNN
1)将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/data
ln -s /home/ubuntu/dataset/KITTI/object obj
然后:下载源码和源码所需的库(mayavi之类的),照readme里面去做
最后:运行
(1) 只显示LiDAR 仅真值
cd kitti_object_vis
python 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预测值**+真值对比**
在以上所有命令后面加 -p
python 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.cpp
2.目录存放结构
KITTI标签文件需要存放在:。。。label_2
预测结果文件存放在:resluts/data (含有得分)
结果评估文件需要存放在: results/plot
其中预测结果也可以自己模仿:
如果是自己生成,需要注意的有:①将标签改为三类,为了改变P,R值可将标签复制三行,然后后面加上不同的置信度
3.开始评估
./evaluate_object_3d_offline gt_dir result_dir
其中gt_dir 是上面的label2的目录,而result_dir是上面的预测结果results的目录。
结果如下图:
参考链接:
1.https://blog.csdn.net/u013086672/article/details/103910266
2.https://blog.csdn.net/lovely_yoshino/article/details/105814646?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
3.https://blog.csdn.net/solomon1558/article/details/70173223
4.https://blog.csdn.net/lovely_yoshino/article/details/105814646?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.nonecase
5.https://www.cnblogs.com/notesbyY/p/10478645.html
6.https://blog.csdn.net/tiatiatiatia/article/details/97765165
7.https://www.sohu.com/a/397643311_99979179
8.https://blog.csdn.net/weixin_39999955/article/details/83819196
9.https://blog.csdn.net/weixin_39999955/article/details/83819313
10.https://stackoverflow.com/questions/29407474/how-to-understand-the-kitti-camera-calibration-files#
11.https://www.cnblogs.com/llfctt/p/9475659.html
12.https://blog.csdn.net/Xueting_B/article/details/106372195
13.https://blog.csdn.net/weixin_42886817/article/details/102839065?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
14.https://www.cnblogs.com/notesbyY/p/10478645.html
15.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
16.https://www.cnblogs.com/xiaoboge/p/10529971.html
17.https://blog.csdn.net/hit1524468/article/details/79857351