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)