2019年8月21日,谷歌母公司Alphabet旗下的自动驾驶公司Waymo在其博客公布了数据开放项目(Waymo Open Dataset),包括Waymo motion和Waymo perception两部分。文件格式为tfrecord
,需要对其进行解析,这里介绍一下Waymo perception数据集的解析,将其解析为KITTI数据集的格式。
下载地址:https://waymo.com/open/
论文:https://arxiv.org/abs/1912.04838
解析代码:https://download.csdn.net/download/qq_37591788/85313082
传感器配置
感知系统采用了5个相机和5个激光雷达。
点云数据解析
从官网下载后的数据为tfrecord格式,为了便于使用,将其解析为KITTI数据集格式(解析代码)。LIDAR点云被解析为.bin文件,这里有两种方式:
- 保留5个LIDAR的点云,将他们进行融合
- 只保留top的LIDAR点云
如果下载的是v1.3.0之后的数据,还增加了3D点云语义分割标签的解析。
MMDetection3D
MMDetection3D中提供了waymo数据集向KITTI数据集的转换工具,需要首先安装waymo-open-dataset工具,通过pip安装即可:
pip3 install waymo-open-dataset-tf-2-6-0==1.4.5 # waymo-open-dataset1.3.1以下的版本不支持3D label解析
转换使用tools/data_conveter下的waymo_converter.py文件。但需要进行相应的修改。
waymo_converter.py的使用
我这里通过修改waymo_converter.py,可以输出不同的点云文件:
load_dir:waymo的tfrecord文件存放位置
save_dir:生成的kitti格式存放位置
waymo v_1_3_0之后的版本有3D label,代码在MMDetection3D的tools/data_conveter/waymo_converter.py基础上增加了3D点云语义分割label的解析,核心代码如下:
def convert_range_image_to_point_cloud_labels(frame,
range_images,
segmentation_labels,
ri_index=0):
"""Convert segmentation labels from range images to point clouds.
Args:
frame: open dataset frame
range_images: A dict of {laser_name, [range_image_first_return,
range_image_second_return]}.
segmentation_labels: A dict of {laser_name, [range_image_first_return,
range_image_second_return]}.
ri_index: 0 for the first return, 1 for the second return.
Returns:
point_labels: {[N, 2]} list of 3d lidar points's segmentation labels. 0 for
points that are not labeled.
"""
calibrations = sorted(frame.context.laser_calibrations, key=lambda c: c.name)
point_labels = []
for c in calibrations:
range_image = range_images[c.name][ri_index]
range_image_tensor = tf.reshape(
tf.convert_to_tensor(range_image.data), range_image.shape.dims)
range_image_mask = range_image_tensor[..., 0] > 0
if c.name in segmentation_labels:
sl = segmentation_labels[c.name][ri_index]
sl_tensor = tf.reshape(tf.convert_to_tensor(sl.data), sl.shape.dims)
sl_points_tensor = tf.gather_nd(sl_tensor, tf.where(range_image_mask))
else:
num_valid_point = tf.math.reduce_sum(tf.cast(range_image_mask, tf.int32))
sl_points_tensor = tf.zeros([num_valid_point, 2], dtype=tf.int32)
point_labels.append(sl_points_tensor.numpy())
return point_labels
得到的label大小为Nx2,N是点云的数量(但有部分文件解析出的label大小和点云大小略有不同,不知什么原因)。
- label的第一列为实例标签,区分每一个具体实例;
- 第二列为语义标签,只区分类别。
代码链接:https://download.csdn.net/download/qq_37591788/85313082