pointpillar anchor匹配

定位:pcdet/models/dense_heads/target_assigner/axis_aligned_target_assigner.py
# 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])

# (cx, cy, cz) 为物体3D框的几何中心位置,(dx, dy, dz)分别为物体3D框在heading角度为0时沿着x-y-z三个方向的长度,heading为物体在俯视图下的朝向角
anchors[:, 0:7]  #(cx, cy, cz, dx, dy, dz, heading)
gt_boxes[:, 0:7]
tensor([[  0.0000, -39.6800,   0.2650,  ...,   0.6000,   1.7300,   0.0000],
        [  0.0000, -39.6800,   0.2650,  ...,   0.6000,   1.7300,   1.5700],
        [  0.3215, -39.6800,   0.2650,  ...,   0.6000,   1.7300,   0.0000],
        ...,
        [ 68.7985,  39.6800,   0.2650,  ...,   0.6000,   1.7300,   1.5700],
        [ 69.1200,  39.6800,   0.2650,  ...,   0.6000,   1.7300,   0.0000],
        [ 69.1200,  39.6800,   0.2650,  ...,   0.6000,   1.7300,   1.5700]],
       device='cuda:0')
tensor([[  5.7474,  -2.8168,  -0.7688,   0.7971,   0.4994,   1.6710,   1.7641],
        [  7.4414,  -1.6039,  -0.6621,   0.9123,   0.6050,   1.8727,   2.8541],
        [ 10.8724,   0.4536,  -0.6721,   0.9988,   0.4033,   1.8247,   1.5041],
        [ 10.9733,  -8.8892,  -0.6260,   1.0852,   0.8451,   1.8151,   1.9441],
        [  4.6155,  -5.4593,  -0.7389,   0.7299,   0.6242,   1.7190,   1.6041],
        [ 16.6888, -11.4180,  -0.7195,   0.8355,   0.6434,   1.5173,  -0.6459],
        [  7.5312,  -4.4219,  -0.7520,   1.0756,   0.4802,   1.6614,  -2.0691],
        [  9.3284, -12.7250,  -0.6318,   1.1140,   0.5282,   1.7862,  -1.9059],
        [ 24.1482, -16.5193,  -0.5080,   0.9411,   0.6530,   1.7766,  -1.6359],
        [ 10.7779, -14.6549,  -0.6205,   1.0756,   0.7491,   1.7670,   2.0641],
        [ 10.7733,  -2.6072,  -0.8293,   0.4898,   0.7011,   1.4789,   2.9741],
        [ 37.1105,   1.8952,  -0.5361,   0.1921,   0.4129,   1.7286,  -2.4791]],
       device='cuda:0')
torch.Size([107136, 7])  # 固定107136个anchor,2种角度:0°、90°
torch.Size([12, 7]) # 这个batch=3有12个anchor,不是固定的

产生的anchor,解释107136,backbone之后的feature map是[batch_size,6C, H/2=248, W/2=216],每个位置产生2种角度(0°、90°)的anchor,248 x 216 x 2 = 107136

产生的anchor分析(预测3类)

仅仅看90°的anchor

print(anchors[1, 0:7])
print(anchors[3, 0:7])
print(anchors[5, 0:7])
print(anchors[431, 0:7])
print(anchors[433, 0:7])
print(anchors[435, 0:7])
print(anchors[437, 0:7])
print(anchors[863, 0:7])

tensor([  0.0000, -39.6800,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([  0.3215, -39.6800,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([  0.6430, -39.6800,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.6800,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([  0.0000, -39.3587,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([  0.3215, -39.3587,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([  0.6430, -39.3587,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.3587,  -1.0000,   3.9000,   1.6000,   1.5600,   1.5700], device='cuda:0')

1、3、5、431行只有x移动,每次移动0.3215,怎么来的呢,69.12/216=0.32(3.9, 1.6, 1.56)Car的尺寸。
433、435、437行和上面x移动一样距离,同时y也移动了0.3213,这又是怎么来的呢,(39.68x2)/248=0.32

来看看Pedestrian的尺寸,和上面非常类似,仅仅尺寸改变。

tensor([  0.0000, -39.6800,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.3215, -39.6800,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700],  device='cuda:0')
tensor([  0.6430, -39.6800,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.6800,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700],  device='cuda:0')
tensor([  0.0000, -39.3587,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700],  device='cuda:0')
tensor([  0.3215, -39.3587,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.6430, -39.3587,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.3587,   0.2650,   0.8000,   0.6000,   1.7300,   1.5700], device='cuda:0')

同理,Cyclist

tensor([  0.0000, -39.6800,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.3215, -39.6800,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.6430, -39.6800,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.6800,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.0000, -39.3587,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.3215, -39.3587,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([  0.6430, -39.3587,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')
tensor([ 69.1200, -39.3587,   0.2650,   1.7600,   0.6000,   1.7300,   1.5700], device='cuda:0')

然后就是计算IOU了,用的是标准2D IOU计算方法。返回[107136, num_gt_box]

# 标准/普通 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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值