pointpillar IOU计算

# 分配目标
def assign_targets_single(self, anchors, gt_boxes, gt_classes, matched_threshold=0.6, unmatched_threshold=0.45):
    # Car:匹配使用0.6和0.45的正负样本阈值
    # anchors:[107136, 7]
    # gt_boxes:[num, 7]
    # gt_classes:[1, num] ,Car:全是1、Pedestrian:全是2、Cyclist:全是3 , gt_boxes的类别标签
    num_anchors = anchors.shape[0]  # 107136
    num_gt = gt_boxes.shape[0]  # 不固定

    labels = torch.ones((num_anchors,), dtype=torch.int32, device=anchors.device) * -1  # [-1, -1, -1,  ...] [107136, 1]
    gt_ids = torch.ones((num_anchors,), dtype=torch.int32, device=anchors.device) * -1  # [-1, -1, -1,  ...] [107136, 1]

    # IOU 计算
    if len(gt_boxes) > 0 and anchors.shape[0] > 0:
        anchor_by_gt_overlap = iou3d_nms_utils.boxes_iou3d_gpu(anchors[:, 0:7], gt_boxes[:, 0:7]) \
            if self.match_height else box_utils.boxes3d_nearest_bev_iou(anchors[:, 0:7], gt_boxes[:, 0:7])
        # IOU:[107136, num_gt_box]
def boxes3d_nearest_bev_iou(boxes_a, boxes_b):
    """
    Args:
        boxes_a: (N, 7) [x, y, z, dx, dy, dz, heading]
        boxes_b: (N, 7) [x, y, z, dx, dy, dz, heading]
    Returns:
    """
    boxes_bev_a = boxes3d_lidar_to_aligned_bev_boxes(boxes_a)
    boxes_bev_b = boxes3d_lidar_to_aligned_bev_boxes(boxes_b)
    return boxes_iou_normal(boxes_bev_a, boxes_bev_b)
# 雷达坐标系,转换到bev视图坐标
def boxes3d_lidar_to_aligned_bev_boxes(boxes3d):
    """
    Args:
        boxes3d: (N, 7 + C) [x, y, z, dx, dy, dz, heading] 在激光雷达坐标系中
    Returns:
        aligned_bev_boxes: (N, 4) [x1, y1, x2, y2] in the above lidar coordinate 俯视图
    """
    rot_angle = common_utils.limit_period(boxes3d[:, 6], offset=0.5, period=np.pi).abs()  # 旋转角度,只希望pi/2到-pi/2范围
    # 进一步,将全部gt_box规范到pi/4到-pi/4范围内,好匹配
    choose_dims = torch.where(rot_angle[:, None] < np.pi / 4, boxes3d[:, [3, 4]], boxes3d[:, [4, 3]])
    aligned_bev_boxes = torch.cat((boxes3d[:, 0:2] - choose_dims / 2, boxes3d[:, 0:2] + choose_dims / 2), dim=1) # 中心 + 长宽
    return aligned_bev_boxes
def limit_period(val, offset=0.5, period=np.pi):
    val, is_numpy = check_numpy_to_torch(val)
    ans = val - torch.floor(val / period + offset) * period  # 向下取整,不大于元素的最大整数
    return ans.numpy() if is_numpy else ans  # 结果需要转numpy

公式:val - torch.floor(val / period + offset) * period如下,角度规范到pi/2到-pi/2范围
在这里插入图片描述

标准/普通 2D IOU 计算

def boxes_iou_normal(boxes_a, boxes_b):
    """
    Args:
        boxes_a: (N, 4) [x1, y1, x2, y2] [x_min, y_min, x_max, y_max]
        boxes_b: (M, 4) [x1, y1, x2, y2]
    Returns:
    """
    assert boxes_a.shape[1] == boxes_b.shape[1] == 4
    x_min = torch.max(boxes_a[:, 0, None], boxes_b[None, :, 0])
    x_max = torch.min(boxes_a[:, 2, None], boxes_b[None, :, 2])
    y_min = torch.max(boxes_a[:, 1, None], boxes_b[None, :, 1])
    y_max = torch.min(boxes_a[:, 3, None], boxes_b[None, :, 3])
    x_len = torch.clamp_min(x_max - x_min, min=0)
    y_len = torch.clamp_min(y_max - y_min, min=0)
    area_a = (boxes_a[:, 2] - boxes_a[:, 0]) * (boxes_a[:, 3] - boxes_a[:, 1])
    area_b = (boxes_b[:, 2] - boxes_b[:, 0]) * (boxes_b[:, 3] - boxes_b[:, 1])
    a_intersect_b = x_len * y_len  # 交
    iou = a_intersect_b / torch.clamp_min(area_a[:, None] + area_b[None, :] - a_intersect_b, min=1e-6)

    return iou
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值