Ejemplo n.º 1
0
def noise_per_object_v4_(gt_boxes, points=None, valid_mask=None, rotation_perturb=np.pi / 4, center_noise_std=1.0,\
                          global_random_rot_range=np.pi / 4, num_try=5, group_ids=None, data_aug_with_context=-1.0,\
                         data_aug_random_drop=-1.0):
    """
        perform random rotation and translation on each groundtruth independently.

        Args:
            gt_boxes: [N, 7], gt box in lidar, [x, y, z, w, l, h, ry]
            points: [M, 4], point cloud in lidar, all points in the scene.
            rotation_perturb: [-0.785, 0.785],
            center_noise_std: [1.0, 1.0, 0.5],
            global_random_rot_range: [0, 0]
            num_try: 100
    """
    num_boxes = gt_boxes.shape[0]

    center_noise_std = np.array(center_noise_std, dtype=gt_boxes.dtype)
    loc_noises = np.random.normal(scale=center_noise_std,
                                  size=[num_boxes, num_try, 3])
    rot_noises = np.random.uniform(rotation_perturb[0],
                                   rotation_perturb[1],
                                   size=[num_boxes, num_try])

    origin = [0.5, 0.5, 0.5]

    offset = [0.0, 0.0, 0.0, 0.0, 0.0]
    if data_aug_with_context > 0:  # to enlarge boxes and keep context
        offset = [0.0, 0.0, data_aug_with_context, data_aug_with_context, 0.0]

    # gt_boxes: x,y,z(lidar), w, l, h, ry(cam).
    gt_box_corners = box_np_ops.center_to_corner_box3d(gt_boxes[:, :3],
                                                       gt_boxes[:, 3:6] +
                                                       offset[2:5],
                                                       gt_boxes[:, 6],
                                                       origin=origin,
                                                       axis=2)
    # noise on bev_box (x, y, w, l, ry). # todo: seems without noise in z-axis velo, because only cal bev iou, but z-axis noise added later.
    selected_noise = noise_per_box(gt_boxes[:, [0, 1, 3, 4, 6]] + offset,
                                   valid_mask, loc_noises, rot_noises)  #

    loc_transforms = _select_transform(loc_noises, selected_noise)
    rot_transforms = _select_transform(rot_noises, selected_noise)
    surfaces = box_np_ops.corner_to_surfaces_3d_jit(gt_box_corners)
    if points is not None:
        point_masks = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)

        # todo: perform random drop here.
        if data_aug_random_drop > 0.0:
            point_masks = point_masks

        points_transform_(
            points,
            gt_boxes[:, :3],
            point_masks,
            loc_transforms,
            rot_transforms,
            valid_mask,
        )

    box3d_transform_(gt_boxes, loc_transforms, rot_transforms, valid_mask)
Ejemplo n.º 2
0
def points_in_rbbox(points, rbbox, z_axis=2, origin=(0.5, 0.5, 0.5)):
    rbbox_corners = center_to_corner_box3d(
        rbbox[:, :3], rbbox[:, 3:6], rbbox[:, -1], origin=origin, axis=z_axis
    )
    surfaces = corner_to_surfaces_3d(rbbox_corners)
    indices = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
    return indices
Ejemplo n.º 3
0
def points_in_pyramids_mask(points, pyramids):
    '''
    pyramids: [N', 15]
    surfaces: [N', 5, 3, 3]
               N': num of pyramids, '5: num of surfaces per pyramid, 3: num of corners per surface, 3: dim of each corner
    '''
    indices = [1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 1, 0, 4, 3, 2]
    surfaces = np.concatenate([pyramids[:, 3 * k:3 * k + 3] for k in indices],
                              axis=1).reshape(-1, 5, 3, 3)
    point_masks = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
    return point_masks
def remove_outside_points(points, rect, Trv2c, P2, image_shape):
    # 5x faster than remove_outside_points_v1(2ms vs 10ms)
    C, R, T = projection_matrix_to_CRT_kitti(P2)
    image_bbox = [0, 0, image_shape[1], image_shape[0]]
    frustum = get_frustum(image_bbox, C)
    frustum -= T
    frustum = np.linalg.inv(R) @ frustum.T
    frustum = camera_to_lidar(frustum.T, rect, Trv2c)
    frustum_surfaces = corner_to_surfaces_3d_jit(frustum[np.newaxis, ...])
    indices = points_in_convex_polygon_3d_jit(points[:, :3], frustum_surfaces)
    points = points[indices.reshape([-1])]
    return points
def assign_label_to_voxel(gt_boxes, coors, voxel_size, coors_range):
    """assign a 0/1 label to each voxel based on whether
    the center of voxel is in gt_box. LIDAR.
    """
    voxel_size = np.array(voxel_size, dtype=gt_boxes.dtype)
    coors_range = np.array(coors_range, dtype=gt_boxes.dtype)
    shift = coors_range[:3]
    voxel_origins = coors[:, ::-1] * voxel_size + shift
    voxel_centers = voxel_origins + voxel_size * 0.5
    gt_box_corners = center_to_corner_box3d(
        gt_boxes[:, :3] - voxel_size * 0.5,
        gt_boxes[:, 3:6] + voxel_size,
        gt_boxes[:, 6],
        origin=[0.5, 0.5, 0.5],
        axis=2,
    )
    gt_surfaces = corner_to_surfaces_3d(gt_box_corners)
    ret = points_in_convex_polygon_3d_jit(voxel_centers, gt_surfaces)
    return np.any(ret, axis=1).astype(np.int64)
def assign_label_to_voxel_v3(gt_boxes, coors, voxel_size, coors_range):
    """assign a 0/1 label to each voxel based on whether
    the center of voxel is in gt_box. LIDAR.
    """
    voxel_size = np.array(voxel_size, dtype=gt_boxes.dtype)
    coors_range = np.array(coors_range, dtype=gt_boxes.dtype)
    shift = coors_range[:3]
    voxel_origins = coors[:, ::-1] * voxel_size + shift
    voxel_maxes = voxel_origins + voxel_size
    voxel_minmax = np.concatenate([voxel_origins, voxel_maxes], axis=-1)
    voxel_corners = minmax_to_corner_3d(voxel_minmax)
    gt_box_corners = center_to_corner_box3d(
        gt_boxes[:, :3],
        gt_boxes[:, 3:6],
        gt_boxes[:, 6],
        origin=[0.5, 0.5, 0.5],
        axis=2,
    )
    gt_surfaces = corner_to_surfaces_3d(gt_box_corners)
    voxel_corners_flat = voxel_corners.reshape([-1, 3])
    ret = points_in_convex_polygon_3d_jit(voxel_corners_flat, gt_surfaces)
    ret = ret.reshape([-1, 8, ret.shape[-1]])
    return ret.any(-1).any(-1).astype(np.int64)
def noise_per_object_v2_(
    gt_boxes,
    points=None,
    valid_mask=None,
    rotation_perturb=np.pi / 4,
    center_noise_std=1.0,
    global_random_rot_range=np.pi / 4,
    num_try=100,
):
    """random rotate or remove each groundtrutn independently.
    use kitti viewer to test this function points_transform_

    Args:
        gt_boxes: [N, 7], gt box in lidar.points_transform_
        points: [M, 4], point cloud in lidar.
    """
    num_boxes = gt_boxes.shape[0]
    if not isinstance(rotation_perturb, (list, tuple, np.ndarray)):
        rotation_perturb = [-rotation_perturb, rotation_perturb]
    if not isinstance(global_random_rot_range, (list, tuple, np.ndarray)):
        global_random_rot_range = [
            -global_random_rot_range, global_random_rot_range
        ]

    if not isinstance(center_noise_std, (list, tuple, np.ndarray)):
        center_noise_std = [
            center_noise_std, center_noise_std, center_noise_std
        ]
    if valid_mask is None:
        valid_mask = np.ones((num_boxes, ), dtype=np.bool_)
    center_noise_std = np.array(center_noise_std, dtype=gt_boxes.dtype)
    loc_noises = np.random.normal(scale=center_noise_std,
                                  size=[num_boxes, num_try, 3])
    # loc_noises = np.random.uniform(
    #     -center_noise_std, center_noise_std, size=[num_boxes, num_try, 3])
    rot_noises = np.random.uniform(rotation_perturb[0],
                                   rotation_perturb[1],
                                   size=[num_boxes, num_try])
    gt_grots = np.arctan2(gt_boxes[:, 0], gt_boxes[:, 1])
    grot_lowers = global_random_rot_range[0] - gt_grots
    grot_uppers = global_random_rot_range[1] - gt_grots
    global_rot_noises = np.random.uniform(
        grot_lowers[..., np.newaxis],
        grot_uppers[..., np.newaxis],
        size=[num_boxes, num_try],
    )

    origin = [0.5, 0.5, 0]
    gt_box_corners = box_np_ops.center_to_corner_box3d(gt_boxes[:, :3],
                                                       gt_boxes[:, 3:6],
                                                       gt_boxes[:, 6],
                                                       origin=origin,
                                                       axis=2)
    if np.abs(global_random_rot_range[0] - global_random_rot_range[1]) < 1e-3:
        selected_noise = noise_per_box(gt_boxes[:, [0, 1, 3, 4, 6]],
                                       valid_mask, loc_noises, rot_noises)
    else:
        selected_noise = noise_per_box_v2_(
            gt_boxes[:, [0, 1, 3, 4, 6]],
            valid_mask,
            loc_noises,
            rot_noises,
            global_rot_noises,
        )
    loc_transforms = _select_transform(loc_noises, selected_noise)
    rot_transforms = _select_transform(rot_noises, selected_noise)
    if points is not None:
        surfaces = box_np_ops.corner_to_surfaces_3d_jit(gt_box_corners)
        point_masks = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
        points_transform_(
            points,
            gt_boxes[:, :3],
            point_masks,
            loc_transforms,
            rot_transforms,
            valid_mask,
        )

    box3d_transform_(gt_boxes, loc_transforms, rot_transforms, valid_mask)
def mask_points_in_corners(points, box_corners):
    surfaces = box_np_ops.corner_to_surfaces_3d(box_corners)
    mask = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
    return mask
Ejemplo n.º 9
0
    def get_task_detections(self, task_id, num_class_with_bg, test_cfg, batch_cls_preds, batch_reg_preds,
                            batch_dir_preds=None,
                            batch_iou_preds=None, batch_anchors=None, batch_anchors_mask=None, meta_list=None,
                            batch_valid_frustum=None):
        predictions_dicts = []
        post_center_range = self.post_center_range
        anchors = batch_anchors[0][0]

        for box_preds, cls_preds, dir_preds, iou_preds, a_mask, meta, valid_frustum in zip(batch_reg_preds,  batch_cls_preds, batch_dir_preds,
                                                                                          batch_iou_preds, batch_anchors_mask, meta_list, batch_valid_frustum):
            # get dir labels
            if self.use_direction_classifier:
                dir_labels = torch.max(dir_preds, dim=-1)[1]  # [70400]

            # get scores from cls_preds
            total_scores = torch.sigmoid(cls_preds)  # [70400, 1]
            top_scores = total_scores.squeeze(-1)  # [70400]
            top_labels = self.top_labels

            # SCORE_THRESHOLD: REMOVE those boxes lower than 0.3.
            if test_cfg.score_threshold > 0.0:
                thresh = self.thresh
                # thresh = 0.4
                top_scores_keep = top_scores >= thresh
                top_scores = top_scores.masked_select(top_scores_keep)

                # todo: replace classification score with iou prediction.
                iou_preds = (iou_preds.squeeze() + 1) * 0.5
                top_scores *= torch.pow(iou_preds.masked_select(top_scores_keep), 4)
                # extra centerness from dinms
                # dist_boxes_anchors = torch.abs(box_preds[top_scores_keep] - anchors[top_scores_keep])
                # dist_metric = torch.softmax(torch.pow(torch.pow(dist_boxes_anchors[:, 0:2], 2).sum(-1), 0.5), dim=0)
                # dist_metric = torch.ones_like(dist_metric) - dist_metric
                # top_scores *= torch.pow(dist_metric, 2)

            # NMS: obtain remained box_preds & dir_labels & cls_labels after score threshold.
            if top_scores.shape[0] != 0:
                if test_cfg.score_threshold > 0.0:
                    box_preds = box_preds[top_scores_keep]
                    if self.use_direction_classifier:
                        dir_labels = dir_labels[top_scores_keep]
                    top_labels = top_labels[top_scores_keep]

                boxes_for_nms = box_preds[:, [0, 1, 3, 4, -1]]

                # REMOVE overlap boxes by bev rotate-nms.
                nms_type = "rotate_weighted_nms"
                if nms_type == "rotate_nms":
                    nms_func = box_torch_ops.rotate_nms
                    selected = nms_func(boxes_for_nms,
                                        top_scores,
                                        pre_max_size=test_cfg.nms.nms_pre_max_size,
                                        post_max_size=test_cfg.nms.nms_post_max_size,
                                        iou_threshold=test_cfg.nms.nms_iou_threshold, )
                    box_preds = box_preds[selected]
                    if self.use_direction_classifier:
                        dir_labels = dir_labels[selected]
                    label_preds = top_labels[selected]
                    scores = top_scores[selected]

                elif nms_type == 'rotate_weighted_nms':
                    nms_func = box_torch_ops.rotate_weighted_nms
                    box_preds, dir_labels, label_preds, scores, selected = nms_func(box_preds,
                                                                          boxes_for_nms,
                                                                          dir_labels,
                                                                          top_labels,
                                                                          top_scores,
                                                                          iou_preds[top_scores_keep],
                                                                          anchors[top_scores_keep],
                                                                          pre_max_size=test_cfg.nms.nms_pre_max_size,
                                                                          post_max_size=test_cfg.nms.nms_post_max_size,
                                                                          iou_threshold=test_cfg.nms.nms_iou_threshold,
                                                                          enable_centerness=True,
                                                                          centerness_pow=2,
                                                                          nms_cnt_thresh=2.6,  # 2.6
                                                                          nms_sigma_dist_interval=(0, 20, 40, 60),
                                                                          nms_sigma_square=(0.0009, 0.009, 0.1, 1),
                                                                          suppressed_thresh=0.3,
                                                                          )
                else:
                    raise NotImplementedError
            else:
                box_preds = torch.zeros([0, 7], dtype=float)

            if box_preds.shape[0] > 0:
                from det3d.core.bbox.geometry import points_in_convex_polygon_3d_jit
                indices = points_in_convex_polygon_3d_jit(box_preds[:, :3].cpu().numpy(), valid_frustum.cpu().numpy())
                box_preds = box_preds[indices.reshape([-1])]
                dir_labels = dir_labels[indices.reshape([-1])]
                label_preds = label_preds[indices.reshape([-1])]
                scores = scores[indices.reshape([-1])]

            # POST-PROCESSING of predictions.
            if box_preds.shape[0] != 0:
                # move pred boxes direction by pi, eg. pred_ry < 0 while pred_dir_label > 0.
                if self.use_direction_classifier:
                    opp_labels = ((box_preds[..., -1] - self.direction_offset) > 0) ^ (dir_labels.byte() == 1)
                    box_preds[..., -1] += torch.where(opp_labels, torch.tensor(np.pi).type_as(box_preds), torch.tensor(0.0).type_as(box_preds), )  # useful for dir accuracy, but has no impact on localization

                # remove pred boxes out of POST_VALID_RANGE
                mask = (box_preds[:, :3] >= post_center_range[:3]).all(1)
                mask &= (box_preds[:, :3] <= post_center_range[3:]).all(1)
                predictions_dict = {"box3d_lidar": box_preds[mask],
                                    "scores": scores[mask],
                                    "label_preds": label_preds[mask],
                                    "metadata": meta, }
            else:
                # TODO: what can zero_pred can be used for? and how to eval zero results?
                dtype = batch_reg_preds.dtype
                device = batch_reg_preds.device
                predictions_dict = {
                    "box3d_lidar": torch.zeros([0, self.box_n_dim], dtype=dtype, device=device),
                    "scores": torch.zeros([0], dtype=dtype, device=device),
                    "label_preds": torch.zeros([0], dtype=top_labels.dtype, device=device),
                    "metadata": meta,
                }
            predictions_dicts.append(predictions_dict)

        return predictions_dicts
Ejemplo n.º 10
0
def noise_per_object_v3_( gt_boxes, points=None, valid_mask=None, rotation_perturb=np.pi / 4, center_noise_std=1.0,\
                          global_random_rot_range=np.pi / 4, num_try=5, group_ids=None,):
    """random rotate or remove each groundtruth independently.
    use kitti viewer to test this function points_transform_

    Args:
        gt_boxes: [N, 7], gt box in lidar.points_transform_
        points: [M, 4], point cloud in lidar.
        rotation_perturb: [-0.785, 0.785],
        center_noise_std: [1.0, 1.0, 0.5],
        global_random_rot_range: [0, 0]
        num_try: 100
    """
    num_boxes = gt_boxes.shape[0]
    if not isinstance(rotation_perturb, (list, tuple, np.ndarray)):  # False
        rotation_perturb = [-rotation_perturb, rotation_perturb]

    if not isinstance(global_random_rot_range,
                      (list, tuple, np.ndarray)):  # False
        global_random_rot_range = [
            -global_random_rot_range, global_random_rot_range
        ]
    enable_grot = (
        np.abs(global_random_rot_range[0] - global_random_rot_range[1]) >= 1e-3
    )  # False

    if not isinstance(center_noise_std, (list, tuple, np.ndarray)):  # False
        center_noise_std = [
            center_noise_std, center_noise_std, center_noise_std
        ]

    if valid_mask is None:  # False
        valid_mask = np.ones((num_boxes, ), dtype=np.bool_)

    center_noise_std = np.array(center_noise_std, dtype=gt_boxes.dtype)
    loc_noises = np.random.normal(scale=center_noise_std,
                                  size=[num_boxes, num_try, 3])
    rot_noises = np.random.uniform(rotation_perturb[0],
                                   rotation_perturb[1],
                                   size=[num_boxes, num_try])

    gt_grots = np.arctan2(gt_boxes[:, 0], gt_boxes[:, 1])
    grot_lowers = global_random_rot_range[0] - gt_grots
    grot_uppers = global_random_rot_range[1] - gt_grots
    global_rot_noises = np.random.uniform(
        grot_lowers[..., np.newaxis],
        grot_uppers[..., np.newaxis],
        size=[num_boxes, num_try],
    )

    if group_ids is not None:  # False
        if enable_grot:
            set_group_noise_same_v2_(loc_noises, rot_noises, global_rot_noises,
                                     group_ids)
        else:
            set_group_noise_same_(loc_noises, rot_noises, group_ids)
        group_centers, group_id_num_dict = get_group_center(
            gt_boxes[:, :3], group_ids)
        if enable_grot:
            group_transform_v2_(
                loc_noises,
                rot_noises,
                gt_boxes[:, :3],
                gt_boxes[:, 6],
                group_centers,
                global_rot_noises,
                valid_mask,
            )
        else:
            group_transform_(
                loc_noises,
                rot_noises,
                gt_boxes[:, :3],
                gt_boxes[:, 6],
                group_centers,
                valid_mask,
            )
        group_nums = np.array(list(group_id_num_dict.values()), dtype=np.int64)

    origin = [0.5, 0.5, 0.5]
    gt_box_corners = box_np_ops.center_to_corner_box3d(gt_boxes[:, :3],
                                                       gt_boxes[:, 3:6],
                                                       gt_boxes[:, 6],
                                                       origin=origin,
                                                       axis=2)

    if group_ids is not None:
        if not enable_grot:
            selected_noise = noise_per_box_group(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                group_nums,
            )
        else:
            selected_noise = noise_per_box_group_v2_(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                group_nums,
                global_rot_noises,
            )
    else:
        if not enable_grot:  # True
            selected_noise = noise_per_box(
                gt_boxes[:, [0, 1, 3, 4, 6]], valid_mask, loc_noises,
                rot_noises)  # todo: seems without noise in z-axis velo
        else:
            selected_noise = noise_per_box_v2_(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                global_rot_noises,
            )

    loc_transforms = _select_transform(loc_noises, selected_noise)
    rot_transforms = _select_transform(rot_noises, selected_noise)
    surfaces = box_np_ops.corner_to_surfaces_3d_jit(gt_box_corners)
    if points is not None:
        point_masks = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
        points_transform_(
            points,
            gt_boxes[:, :3],
            point_masks,
            loc_transforms,
            rot_transforms,
            valid_mask,
        )

    box3d_transform_(gt_boxes, loc_transforms, rot_transforms, valid_mask)
Ejemplo n.º 11
0
def noise_per_object_v3_(
    gt_boxes,
    gt_boxes_1,
    gt_boxes_2,
    gt_boxes_3,
    points=None,
    points_1=None,
    points_2=None,
    valid_mask=None,
    rotation_perturb=np.pi / 4,
    center_noise_std=1.0,
    global_random_rot_range=np.pi / 4,
    num_try=5,
    group_ids=None,
):
    """random rotate or remove each groundtruth independently.
    use kitti viewer to test this function points_transform_

    Args:
        gt_boxes: [N, 7], gt box in lidar.points_transform_
        points: [M, 4], point cloud in lidar.
    """
    num_boxes = gt_boxes.shape[0]
    if not isinstance(rotation_perturb, (list, tuple, np.ndarray)):
        rotation_perturb = [-rotation_perturb, rotation_perturb]
    if not isinstance(global_random_rot_range, (list, tuple, np.ndarray)):
        global_random_rot_range = [
            -global_random_rot_range, global_random_rot_range
        ]
    enable_grot = (np.abs(global_random_rot_range[0] -
                          global_random_rot_range[1]) >= 1e-3)
    if not isinstance(center_noise_std, (list, tuple, np.ndarray)):
        center_noise_std = [
            center_noise_std, center_noise_std, center_noise_std
        ]
    if valid_mask is None:
        valid_mask = np.ones((num_boxes, ), dtype=np.bool_)
    center_noise_std = np.array(center_noise_std, dtype=gt_boxes.dtype)
    loc_noises = np.random.normal(scale=center_noise_std,
                                  size=[num_boxes, num_try, 3])
    # loc_noises = np.random.uniform(
    #     -center_noise_std, center_noise_std, size=[num_boxes, num_try, 3])
    rot_noises = np.random.uniform(rotation_perturb[0],
                                   rotation_perturb[1],
                                   size=[num_boxes, num_try])
    gt_grots = np.arctan2(gt_boxes[:, 0], gt_boxes[:, 1])
    grot_lowers = global_random_rot_range[0] - gt_grots
    grot_uppers = global_random_rot_range[1] - gt_grots
    global_rot_noises = np.random.uniform(
        grot_lowers[..., np.newaxis],
        grot_uppers[..., np.newaxis],
        size=[num_boxes, num_try],
    )
    if group_ids is not None:
        if enable_grot:
            set_group_noise_same_v2_(loc_noises, rot_noises, global_rot_noises,
                                     group_ids)
        else:
            set_group_noise_same_(loc_noises, rot_noises, group_ids)
        group_centers, group_id_num_dict = get_group_center(
            gt_boxes[:, :3], group_ids)
        if enable_grot:
            group_transform_v2_(
                loc_noises,
                rot_noises,
                gt_boxes[:, :3],
                gt_boxes[:, 6],
                group_centers,
                global_rot_noises,
                valid_mask,
            )
        else:
            group_transform_(
                loc_noises,
                rot_noises,
                gt_boxes[:, :3],
                gt_boxes[:, 6],
                group_centers,
                valid_mask,
            )
        group_nums = np.array(list(group_id_num_dict.values()), dtype=np.int64)

    origin = [0.5, 0.5, 0.5]
    # TODO: 3个gt_box
    gt_box_corners = box_np_ops.center_to_corner_box3d(gt_boxes[:, :3],
                                                       gt_boxes[:, 3:6],
                                                       gt_boxes[:, 6],
                                                       origin=origin,
                                                       axis=2)
    # T-1
    gt_box_corners_1 = box_np_ops.center_to_corner_box3d(gt_boxes_1[:, :3],
                                                         gt_boxes_1[:, 3:6],
                                                         gt_boxes_1[:, 6],
                                                         origin=origin,
                                                         axis=2)
    # T+1
    gt_box_corners_2 = box_np_ops.center_to_corner_box3d(gt_boxes_2[:, :3],
                                                         gt_boxes_2[:, 3:6],
                                                         gt_boxes_2[:, 6],
                                                         origin=origin,
                                                         axis=2)
    # T-2
    gt_box_corners_3 = box_np_ops.center_to_corner_box3d(gt_boxes_3[:, :3],
                                                         gt_boxes_3[:, 3:6],
                                                         gt_boxes_3[:, 6],
                                                         origin=origin,
                                                         axis=2)
    if group_ids is not None:
        if not enable_grot:
            selected_noise = noise_per_box_group(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                group_nums,
            )
        else:
            selected_noise = noise_per_box_group_v2_(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                group_nums,
                global_rot_noises,
            )
    else:
        if not enable_grot:
            selected_noise = noise_per_box(gt_boxes[:, [0, 1, 3, 4, 6]],
                                           gt_boxes_1[:, [0, 1, 3, 4, 6]],
                                           gt_boxes_2[:, [0, 1, 3, 4, 6]],
                                           gt_boxes_3[:, [0, 1, 3, 4, 6]],
                                           valid_mask, loc_noises, rot_noises)
        else:
            selected_noise = noise_per_box_v2_(
                gt_boxes[:, [0, 1, 3, 4, 6]],
                valid_mask,
                loc_noises,
                rot_noises,
                global_rot_noises,
            )
    loc_transforms = _select_transform(loc_noises, selected_noise)
    rot_transforms = _select_transform(rot_noises, selected_noise)
    surfaces = box_np_ops.corner_to_surfaces_3d_jit(gt_box_corners)
    if points is not None:
        point_masks = points_in_convex_polygon_3d_jit(points[:, :3], surfaces)
        points_transform_(
            points,
            gt_boxes[:, :3],
            point_masks,
            loc_transforms,
            rot_transforms,
            valid_mask,
        )

    # T-1 帧的增广
    loc_transforms_1 = get_loc_transform(loc_transforms, rot_transforms,
                                         gt_boxes, gt_boxes_1)
    surfaces = box_np_ops.corner_to_surfaces_3d_jit(gt_box_corners_1)
    if points_1 is not None:
        point_masks = points_in_convex_polygon_3d_jit(points_1[:, :3],
                                                      surfaces)
        points_transform_(
            points_1,
            gt_boxes_1[:, :3],
            point_masks,
            loc_transforms_1,
            rot_transforms,
            valid_mask,
        )

    box3d_transform_(gt_boxes_1, loc_transforms_1, rot_transforms, valid_mask)

    # T+1帧的增广
    loc_transforms_2 = get_loc_transform(loc_transforms, rot_transforms,
                                         gt_boxes, gt_boxes_2)
    box3d_transform_(gt_boxes_2, loc_transforms_2, rot_transforms, valid_mask)

    # T-2帧的增广
    loc_transforms_3 = get_loc_transform(loc_transforms, rot_transforms,
                                         gt_boxes, gt_boxes_3)
    if points_2 is not None:
        point_masks = points_in_convex_polygon_3d_jit(points_2[:, :3],
                                                      surfaces)
        points_transform_(
            points_2,
            gt_boxes_3[:, :3],
            point_masks,
            loc_transforms_3,
            rot_transforms,
            valid_mask,
        )

    # T帧的box需要做为基准,所以最后变换
    box3d_transform_(gt_boxes, loc_transforms, rot_transforms, valid_mask)