核心要点

  • 交集左上角取两框左上的较大值、右下角取右下的较小值,宽高用 max(0, 右下−左上) 钳制

  • 并集 = 面积A + 面积B − 交集,IoU = 交集 / 并集

  • 无重叠时交集宽或高为负,必须 clamp 到 0,否则得到错误的正面积

  • 框格式约定为 [x1, y1, x2, y2](左上、右下);可向量化扩展到 N×M 框对

标准回答

IoU(交并比)衡量两个边界框的重叠程度,是目标检测里 NMS 和 mAP 评估的核心。计算分三步:先求交集矩形(左上取两框左上坐标的逐分量最大值,右下取右下坐标的最小值),交集宽高务必用 max(0,...) 钳制以处理不相交情形;再用容斥求并集面积;最后相除。下面给出单框版与向量化批量版:

python
import numpy as np

def iou(box_a, box_b):
    """框格式 [x1, y1, x2, y2](左上、右下)。"""
    # 交集矩形的左上与右下
    x1 = max(box_a[0], box_b[0])
    y1 = max(box_a[1], box_b[1])
    x2 = min(box_a[2], box_b[2])
    y2 = min(box_a[3], box_b[3])
    # 无重叠时宽/高为负,钳制到 0
    inter = max(0, x2 - x1) * max(0, y2 - y1)
    area_a = (box_a[2] - box_a[0]) * (box_a[3] - box_a[1])
    area_b = (box_b[2] - box_b[0]) * (box_b[3] - box_b[1])
    union = area_a + area_b - inter
    return inter / union if union > 0 else 0.0

def iou_matrix(boxes_a, boxes_b):
    """向量化:boxes_a (N,4), boxes_b (M,4) -> IoU 矩阵 (N, M)。"""
    a = np.asarray(boxes_a, dtype=float)
    b = np.asarray(boxes_b, dtype=float)
    x1 = np.maximum(a[:, None, 0], b[None, :, 0])
    y1 = np.maximum(a[:, None, 1], b[None, :, 1])
    x2 = np.minimum(a[:, None, 2], b[None, :, 2])
    y2 = np.minimum(a[:, None, 3], b[None, :, 3])
    inter = np.clip(x2 - x1, 0, None) * np.clip(y2 - y1, 0, None)
    area_a = (a[:, 2] - a[:, 0]) * (a[:, 3] - a[:, 1])
    area_b = (b[:, 2] - b[:, 0]) * (b[:, 3] - b[:, 1])
    union = area_a[:, None] + area_b[None, :] - inter
    return np.where(union > 0, inter / union, 0.0)

if __name__ == '__main__':
    print(round(iou([0, 0, 2, 2], [1, 1, 3, 3]), 4))   # 1/7 ≈ 0.1429
    print(round(iou([0, 0, 1, 1], [2, 2, 3, 3]), 4))   # 不相交 -> 0.0
    print(np.round(iou_matrix([[0, 0, 2, 2]], [[1, 1, 3, 3], [0, 0, 2, 2]]), 4))

常见误区

⚠️ 常见踩坑

忘记对交集宽高做 max(0,...) 钳制,两框不相交时算出负宽乘负高变成正面积,IoU 完全错误。另一坑是坐标约定:[x,y,w,h] 与 [x1,y1,x2,y2] 不可混用,需先统一转换;并集为 0(退化框)时要返回 0 防除零。

追问

追问 1IoU 在 NMS 里如何使用?复杂度?

NMS 先按置信度排序,保留最高分框,剔除与它 IoU 超过阈值(如 0.5)的其余框,循环往复。朴素实现 O(n²),n 为候选框数。改进有 Soft-NMS(按 IoU 衰减分数而非硬删)和向量化批量计算 IoU 矩阵加速。

追问 2IoU 作为损失有什么问题,GIoU/DIoU 怎么改进?

两框不相交时 IoU 恒为 0、梯度消失,无法指导回归靠近。GIoU 引入最小包围框惩罚分离程度;DIoU 进一步加入中心点距离项加速收敛;CIoU 再考虑长宽比一致性,使边界框回归更稳更快。

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。