3D目标检测IoU框计算详解

最近在看自动驾驶的面试题,有一题问三维旋转框的IoU计算方式,在csdn博客上看到此代码,但是没有解读,遂记录如下。3D IoU框的计算有如下的步骤:

  1. 计算高度的重叠部分,boxes_height先计算最高处与最低处。(z轴坐标±高度的一半)
  2. overlaps_h(height)存储高度重叠结果:min_of_max-max_of_min
  3. 计算水平方向的重叠部分,调用iou3d_nms_cuda.boxes_overlap_bev_gpu这个函数
  4. 计算overlaps_3d=水平重叠*高度重叠(交集)
  5. 无论是2D框还是3D框,计算公式都是 IoU=框的交集/框的并集,所以下一步计算框的并集
  6. 框的并集=两个框的体积之和(vol_a,vol_b)-重叠部分(overlaps_3d)
  7. 最后计算IoU_3d: iou3d = overlaps_3d / torch.clamp(vol_a + vol_b - overlaps_3d, min=1e-6)

大致示意图如下,画的不好,博主画工不大行…
请添加图片描述

具体代码如下,请对照阅读。

# 3D IOU 计算 
def boxes_iou3d_gpu(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:
        ans_iou: (N, M)
    """
    assert boxes_a.shape[1] == boxes_b.shape[1] == 7

    # height overlap
    # 最高:z轴坐标+高度的一半
    boxes_a_height_max = (boxes_a[:, 2] + boxes_a[:, 5] / 2).view(-1, 1)
    # 最低:z轴坐标-高度的一半
    boxes_a_height_min = (boxes_a[:, 2] - boxes_a[:, 5] / 2).view(-1, 1)
    boxes_b_height_max = (boxes_b[:, 2] + boxes_b[:, 5] / 2).view(1, -1)
    boxes_b_height_min = (boxes_b[:, 2] - boxes_b[:, 5] / 2).view(1, -1)

    # bev overlap
    overlaps_bev = torch.cuda.FloatTensor(torch.Size((boxes_a.shape[0], boxes_b.shape[0]))).zero_()  # (N, M)
    # 调用函数计算bev的overlap
		iou3d_nms_cuda.boxes_overlap_bev_gpu(boxes_a.contiguous(), boxes_b.contiguous(), overlaps_bev)
		# 选择两个框中的最低处的更高的位置
    max_of_min = torch.max(boxes_a_height_min, boxes_b_height_min)
    # 选择两个框中的最高处的更低的位置
    min_of_max = torch.min(boxes_a_height_max, boxes_b_height_max)
		# 计算垂直方向上的高度重叠部分	
    overlaps_h = torch.clamp(min_of_max - max_of_min, min=0)

    # 3d iou   水平*高度重叠部分
    overlaps_3d = overlaps_bev * overlaps_h
		
		# 计算两个框的体积
    vol_a = (boxes_a[:, 3] * boxes_a[:, 4] * boxes_a[:, 5]).view(-1, 1)
    vol_b = (boxes_b[:, 3] * boxes_b[:, 4] * boxes_b[:, 5]).view(1, -1)
		
	  # 交集除以并集  分母为两个框的体积减去重叠的部分
    iou3d = overlaps_3d / torch.clamp(vol_a + vol_b - overlaps_3d, min=1e-6)

### mmdet3dIoU3D 的实现与用法 #### 实现细节 `mmdet3d` 是一个用于三维物体检测和其他三维视觉任务的开源库。其中,IoU3D 计算对于评估模型性能至关重要。该库提供了高效的 IoU3D 计算函数来处理旋转和平移后的边界框之间的重叠情况。 在 `mmdet3d/core/evaluation/iou_3d.py` 文件中定义了 IoU3D 的计算逻辑[^1]: ```python def bbox_overlaps_3d(bboxes1, bboxes2, mode='iou', is_aligned=False, eps=1e-6): """Calculate overlap between two set of 3D boxes. If ``is_aligned`` is False, then calculate the ious between each bbox of bboxes1 and bboxes2, otherwise the ious between each aligned pair of bboxes1 and bboxes2. Args: bboxes1 (Tensor): shape (B, N, 7+C) or (N, 7+C), where C >= 0, representing box parameters including center coordinates, dimensions, orientation angle etc. bboxes2 (Tensor): shape (B, M, 7+C) or (M, 7+C). ... Returns: Tensor: Shape depends on whether 'is_aligned' flag was specified. When True returns tensor with shape (B,) or () depending on input; Otherwise returns matrix of overlaps with shape (B, N, M) or (N, M). """ ``` 此函数接受两组三维边框作为参数,并返回它们之间交并比的结果矩阵。每个边框由七个数值表示:中心坐标(x,y,z),尺寸(l,w,h),以及方向角(θ)。 #### 使用示例 下面是一个简单的例子展示如何调用上述 API 来获取两个给定集合间的所有配对 IoUs: ```python import torch from mmdet3d.core.evaluation import bbox_overlaps_3d # 定义第一个bbox集合作为tensor对象 bboxes1 = torch.tensor([ [0., 0., 0., 1., 1., 1., 0.], # Box centered at origin with size 1x1x1 facing forward ]) # 定义第二个bbox集合作为tensor对象 bboxes2 = torch.tensor([ [-0.5, -0.5, -0.5, 2., 2., 2., 0.] # Larger box encompassing first one fully ]) ious = bbox_overlaps_3d(bboxes1, bboxes2) print(f"IoU value(s):\n{ious}") ``` 这段代码会打印出这两个盒子间的 IoU 值,在这个情况下应该是接近于 1 表明完全包含关系。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值