数据处理配置文件
数据处理配置如下:
包含三个模块,mask_points_and_boxes_outside_range,shuffle_points
transform_points_to_voxels
DATA_PROCESSOR:
- NAME: mask_points_and_boxes_outside_range
REMOVE_OUTSIDE_BOXES: True
- NAME: shuffle_points
SHUFFLE_ENABLED: {
'train': True,
'test': False
}
- NAME: transform_points_to_voxels
VOXEL_SIZE: [0.16, 0.16, 4]
MAX_POINTS_PER_VOXEL: 32
MAX_NUMBER_OF_VOXELS: {
'train': 16000,
'test': 40000
}
模块详解
mask_points_and_boxes_outside_range
def mask_points_and_boxes_outside_range(self, data_dict=None, config=None):
if data_dict is None:
return partial(self.mask_points_and_boxes_outside_range, config=config)
if data_dict.get('points', None) is not None:
mask = common_utils.mask_points_by_range(data_dict['points'], self.point_cloud_range)
data_dict['points'] = data_dict['points'][mask]
if data_dict.get('gt_boxes', None) is not None and config.REMOVE_OUTSIDE_BOXES and self.training:
mask = box_utils.mask_boxes_outside_range_numpy(
data_dict['gt_boxes'], self.point_cloud_range, min_num_corners=config.get('min_num_corners', 1),
use_center_to_filter=config.get('USE_CENTER_TO_FILTER', True)
)
data_dict['gt_boxes'] = data_dict['gt_boxes'][mask]
return data_dict
- mask_points_by_range
def mask_points_by_range(points, limit_range):
mask = (points[:, 0] >= limit_range[0]) & (points[:, 0] <= limit_range[3]) \
& (points[:, 1] >= limit_range[1]) & (points[:, 1] <= limit_range[4])
return mask
POINT_CLOUD_RANGE: [0, -39.68, -3, 69.12, 39.68, 1] 滤掉range范围外的点
- mask_boxes_outside_range_numpy
def mask_boxes_outside_range_numpy(boxes, limit_range, min_num_corners=1, use_center_to_filter=True):
"""
Args:
boxes: (N, 7) [x, y, z, dx, dy, dz, heading, ...], (x, y, z) is the box center
limit_range: [minx, miny, minz, maxx, maxy, maxz]
min_num_corners:
Returns:
"""
if boxes.shape[1] > 7:
boxes = boxes[:, 0:7]
if use_center_to_filter:
box_centers = boxes[:, 0:3]
mask = ((box_centers >= limit_range[0:3]) & (box_centers <= limit_range[3:6])).all(axis=-1)
else:
corners = boxes_to_corners_3d(boxes) # (N, 8, 3)
corners = corners[:, :, 0:2]
mask = ((corners >= limit_range[0:2]) & (corners <= limit_range[3:5])).all(axis=2)
mask = mask.sum(axis=1) >= min_num_corners # (N)
return mask
滤掉gt_box的中心点在point range 之外的点。mask = ((box_centers >=
limit_range[0:3]) & (box_centers <=
limit_range[3:6])).all(axis=-1):这一行代码创建了一个布尔掩码
mask。它使用了类似之前的方法,对边界框的中心坐标是否在给定的 limit_range 范围内进行了比较。limit_range
中的前三个元素表示最小范围(min),后三个元素表示最大范围(max)。all(axis=-1)
表示沿着最后一个维度(即每个边界框)进行元素的逻辑“与”操作,得到一个布尔数组,表示每个边界框的中心坐标是否都在范围内。
shuffle_points
def shuffle_points(self, data_dict=None, config=None):
if data_dict is None:
return partial(self.shuffle_points, config=config)
if config.SHUFFLE_ENABLED[self.mode]:
points = data_dict['points']
shuffle_idx = np.random.permutation(points.shape[0])
points = points[shuffle_idx]
data_dict['points'] = points
return data_dict
transform_points_to_voxels
核心思想就是使用voxel_generator 对points生成voxels,然后对data_dict 新增字段voxels, coordinates, num_points
points = data_dict['points']
voxel_output = self.voxel_generator.generate(points)
voxels, coordinates, num_points = voxel_output
data_dict['voxels'] = voxels
data_dict['voxel_coords'] = coordinates
data_dict['voxel_num_points'] = num_points
voxel_generator 模块后续详细展开讲下