IoU 是目标检测中计算目标检测结果和实际结果重叠度的一种常用指标,它通过计算检测框和真实框的交集和与并集的比例,来衡量检测结果的准确性。

IoU 的取值范围是 (0, 1),值越接近 1 表示检测结果与实际结果之间的重叠度越高,表示检测结果越准确,而值越接近 0 表示检测结果与实际结果之间的重叠越小,表示结果越不准确。

两个矩形框 A 和 B,左上角和右下角的坐标为:

  • A(x 1_A, y 1_A, x 2_A, y 2_A)
  • B(x 1_B, y 1_B, x 2_B, y 2_B)

两个矩形框的交集面积 S(intersection) 为:

S(intersection) = max(0, x2_A - x1_A) * max(0, y2_A - y1_A) ∩
                  max(0, x2_B - x1_B) * max(0, y2_B - y1_B)

两个矩形框的并集面积 S(union)为:

S(union) = max(0, x 2_A - x 1_A) * max(0, y 2_A - y 1_A) ∪
           max(0, x 2_B - x 1_B) * max(0, y 2_B - y 1_B)

则它们之间的 IOU 为:

IOU = S(intersection) / S(union)

Python 实现:

def compute_iou(box1: list, box2: list) -> float:
    """计算两个矩形的重叠度
 
    Args: xyxy 形式
        box1 (tup / list): (x1, y1, x2, y2)
        box2 (tup / list):  (x1, y1, x2, y2)
 
    Returns:
        float: 两个边界框的 IoU
    """
 
    x1min, y1min, x1max, y1max = box1
    x2min, y2min, x2max, y2max = box2
 
    # 计算相交区域的左上角和右下角坐标
    xmin = max(x1min, x2min)
    ymin = max(y1min, y2min)
    xmax = min(x1max, x2max)
    ymax = min(y1max, y2max)
 
    # 计算相交区域面积
    inter_area = max(0, xmax - xmin) * max(0, ymax - ymin)
 
    # 计算两个矩形的面积
    box1_area = (y1max - y1min) * (x1max - x1min)
    box2_area = (y2max - y2min) * (x2max - x2min)
    union_area = box1_area + box2_area - inter_area
 
    # 返回 IoU
    return inter_area / union_area

如果数据是 xywh 形式, 需要先转为 xyxy:

def xywh_to_xyxy(xywh: list) -> tuple:
    """xywh 转 xyxy
 
    Args:
        xywh (list / tuple): [x, y, w, h]
 
    Returns:
        tuple: (xmin, ymin, xmax, ymax)
    """
 
    x, y, w, h = xywh
 
    xmin, ymin = x - w / 2, y - h / 2
    xmax, ymax = x + w / 2, y + h / 2
 
    return (xmin, ymin, xmax, ymax)

xyxy 转 xywh:

def xyxy_to_xywh(xyxy: list) -> tuple:
    """xyxy 转 wywh
 
    Args:
        xywh (list / tuple): [xmin, ymin, xmax, ymax]
 
    Returns:
        tuple: (x, y, w, h)
    """
 
    xmin, ymin, xmax, ymax = xyxy
 
    x, y = (xmin + xmax) / 2, (ymin + ymax) / 2
    w, h = xmax - xmin, ymax - ymin
 
    return (x, y, w, h)