核心要点

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

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

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

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

标准回答

一、先把结论讲清楚

可以先给公式:IoU = 交集面积 / 并集面积,它衡量两个检测框重叠得有多多。

一、交集怎么求?

框格式先统一成 [x1, y1, x2, y2]。交集左上角取两个框左上坐标的最大值,右下角取两个框右下坐标的最小值。交集宽高要写成 max(0, x2-x1)、max(0, y2-y1),因为两框不相交时宽高会是负数。

二、拆开机制和判断点

二、并集怎么求?

并集不是两个面积直接相加,而是 areaA + areaB - inter。最后 IoU = inter / union。如果 union 是 0,比如退化框,就返回 0,避免除零。

**三、面试里最该强调什么?

三、补上例子、边界和取舍

**

坐标格式不能混,[x,y,w,h] 要先转成 [x1,y1,x2,y2];无重叠一定要 clamp,否则负宽乘负高可能变成假的正面积。下面给出单框版与向量化批量版:

面试里可以补一个视觉任务例子:手撕代码:实现两个边界框的 IoU 在分类、检测、分割或多模态理解里分别会影响数据增强、模型结构、指标选择和误检漏检分析。这样回答会比单独讲概念更像真实项目经验。

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))

常见误区

⚠️ 常见踩坑

误区一:不 clamp 交集宽高。 两框不相交时,负宽乘负高可能变成正面积,IoU 会完全错。

误区二:混用坐标格式。 [x,y,w,h] 和 [x1,y1,x2,y2] 不能直接混算,必须先统一。

追问

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

NMS 会先按置信度排序,保留最高分框,然后删掉和它 IoU 超过阈值 的候选框,循环直到没有框。朴素复杂度是 O(n²),工程上常用向量化、GPU 或 Soft-NMS 优化。

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

两框不相交时 IoU 恒为 0,几乎没有有效梯度指导框靠近。GIoU 加最小包围框惩罚,DIoU 加中心距离,CIoU 再考虑长宽比,让框回归更稳定。

🔗 相似问题

同一考点的不同问法,换着练更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习