1. 复制粘贴数据增广
复制粘贴(copy-paste)数据增广又叫GT增广,是将其余帧的边界框及其内部点云复制到当前帧,以增加当前帧数据丰富性的一种数据增广方法。复制前后的边界框在帧内的坐标不变,需要满足“不与已有边界框重合”的条件,且添加时会删除当前帧在复制边界框内的点。
2. mmdetection3d中物体点云数据库的建立
本节以nuScenes数据集为例,介绍mmdetection3d中复制粘贴数据增广的实现。
在运行create_data.py
文件生成数据集info文件的同时,会调用create_groundtruth_database()
函数生成物体点云数据库,对应的文件是nuscenes_dbinfos_train.pkl
和nuscenes_gt_database
文件夹(内含名称格式为$token$_$类别名称$_$序号$.bin
的点云文件)。
2.1 数据库的建立过程
create_groundtruth_database()
函数会首先建立数据集类(NuScenesDataset
),对应的pipeline仅包含LoadPointsFromFile
、LoadPointsFromMultiSweeps
和LoadAnnotations3D
。
随后遍历各帧,将各边界框内部的点取出(对应的函数为box_np_ops.points_in_rbbox()
),并平移到以边界框中心为原点的坐标系下,保存为nuscenes_gt_database
文件夹下的文件。同时将数据库的info信息保存为nuscenes_dbinfos_train.pkl
文件。
2.2 nuscenes_dbinfos_train.pkl
文件的内容
nuscenes_dbinfos_train.pkl
的存储内容为字典,格式如下:
dbinfos = dict(
pedestrian = 列表,
car = 列表,
...
human.pedestrian.personal_mobility = 列表
)
即键值对为类别名: 列表
的形式,其中各类列表的长度为训练集中各帧含有的该类物体数之和。列表的每一个元素是一个字典,对应某一帧中的一个该类物体。字典格式如下:
info = dict(
name = 字符串, # 类别名
path = 字符串, # 数据库中对应的bin文件相对路径
image_idx = 字符串, # 所属帧的token信息
gt_idx = 整数, # 在该帧中的物体序号
box3d_lidar = 大小为 9 的数值矩阵(ndarray), # 激光雷达下的9维边界框表达
num_points_in_gt = 整数, # 边界框内的激光雷达点数
difficulty = 0, # nuScenes数据集无检测难度区分,统一为0
group_id = 整数, # 与gt_idx相同
)
3. mmdetection3d中pipeline内的ObjectSample
步骤
通常的模型会在默认pipeline的基础上添加ObjectSample
步骤(位于LoadAnnotations3D
后)。该步骤也属于数据增广。
相关的代码见mmdetection3d/mmdet3d/datasets/pipelines/transforms_3d.py
。
-
该步骤会首先初始化
DataBaseSampler
类的一个实例db_sampler
; -
然后,调用
db_sampler.sample_all()
方法:- 统计当前帧内的各类物体数量 n n n,然后用预设的该类最大采样数量 n max n_\text{max} nmax减去 n n n,并乘以预设的、各类统一的采样率 r r r,得到该类实际采样数量 m m m。
- 当
m
>
0
m>0
m>0时,使用
sample_class_v2()
函数,从物体点云数据库中采样 m m m个物体:- 采样规则:初始时随机打乱数据库,在每次采样时从前往后依次取 m m m个未取过的物体。若某次刚好将数据库取完或数据库中未取过的物体不足,则将剩下的物体取完,同时重新打乱数据库以备后续采样。
- 求取真实边界框(含之前类别采样的边界框)和当前类别采样边界框在BEV下投影的角点坐标(对应
box_np_ops.center_to_corner_box2d()
函数:根据尺寸计算中心在原点、朝向角为0时的角点坐标,然后根据朝向角旋转,最后平移到激光雷达坐标系下),并一起输入到data_augment_utils.box_collision_test()
函数中检测原始边界框与采样边界框,以及采样边界框与采样边界框之间是否相交。 - 若某采样边界框与原始边界框或之前的采样边界框相交,则丢弃之。
- 读取各采样边界框内的点云,并平移到激光雷达坐标系下。
- 输出采样边界框及其类别、点云。
-
最后,将原始点云中处于采样边界框内的点移除(
remove_points_in_boxes()
),并加入采样边界框内的点。