Python3计算矩形交并比(IoU)详解与代码实现

今天早睡
今天早睡
发布时间:2026-10-13 | 5人浏览过
原创

本文详细解析Python3中两个矩形交并比(IoU)的计算原理。从矩形坐标定义入手,推导相交区域面积公式,并对比处理无交集情况的两种代码实现方式。提供基于左下/右上及左上/右下坐标系的完整Python3代码示例,适用于目标检测算法评估。

前言与背景

一、前言

近期在解答相关疑问时,发现许多关于IoU的博客内容过于简略或相互转载,部分甚至存在图示与代码不符的问题,导致初学者容易误解。为此,本文重新梳理了相关资源,旨在以清晰易懂的方式展示IoU的计算方法,便于日后复习。若文中存在疏漏,欢迎留言指正,避免读者因错误信息而走弯路。

交并比概念与矩形定义

二、交并比的概念及应用

假设在平面坐标系中存在一个矩形,其长和宽分别平行于x轴和y轴。

该矩形在平面中的唯一位置可由对角线上的两个顶点坐标确定(此处省略证明过程)。

如图所示,矩形的位置既可以用左上角和右下角的顶点坐标表示,即(xmin, ymax, xmax, ymin),也可以用左下角和右上角的顶点坐标表示,即(xmin, ymin, xmax, ymax)。

这里需要指出一个常见的误区:许多网络博客的图示标注为左上和右下顶点,但配套代码却统一使用左下和右上顶点坐标来确定矩形。这种不一致性容易让初学者感到困惑。

理论上,两种坐标定义方式均可行。但从习惯角度来看,使用左下和右上顶点坐标(xmin, ymin, xmax, ymax)来定义矩形更符合常规思维,这也是网上多数代码采用此方式的原因。

计算矩形面积非常简单,只需长乘以宽:

矩形面积 = (xmax - xmin) × (ymax - ymin)

IoU计算原理

明确了矩形位置的确定方法后,接下来我们深入探讨交并比的具体计算过程。

交并比(Intersection over Union, IoU)是目标检测任务中的核心指标。它衡量的是预测框(Predicted bounding box)与真实标注框(Ground-truth bounding box)的重叠程度,即交集面积与并集面积的比值。理想状态下,两框完全重合时比值为1。通常认为IoU大于0.5即为较好的检测结果。该指标用于评估预测框与真实框的相关性,数值越高代表算法准确度越高。

假设平面坐标系中有两个矩形:真实标注框(Ground-truth bounding box, G)和预测框(Predicted bounding box, P)。其中G为人工标注的框,P为算法预测生成的框,且两者的长宽均平行于坐标轴。具体示意如下:

IoU的计算公式为:

因此,设矩形G的坐标为(gxmin, gymin, gxmax, gymax),矩形P的坐标为(pxmin, pymin, pxmax, pymax)。

计算交并比的关键在于求出两个矩形相交部分(G∩P)的面积。

解决此问题的关键在于确定相交矩形的左下角(xmin, ymin)和右上角(xmax, ymax)坐标,即确定(xmin, ymin, xmax, ymax)。

通过观察图形,我们可以得出以下规律:


# 相交矩形的左下顶点坐标, 就是两个矩形左下坐标的x和y分别取最大值
xmin = max(gxmin, pxmin)
ymin = max(gymin, pymin)
# 相交矩形的右上顶点坐标, 就是两个矩形右上坐标的x和y分别取最小值
xmax = min(gxmax, pxmax)
ymax = min(gymax, pyxmax)

若初次理解有困难,建议在纸上绘制图形进行辅助理解。

一旦确定了相交矩形的坐标(xmin, ymin, xmax, ymax),计算其面积便十分简单。

相交矩形面积 area(G∩P) = 长 × 宽

w = xmax - xmin # 计算相交矩形的长

h = ymax - ymin # 计算相交矩形的宽

area(G∩P) = w × h # 计算相交矩形的面积

最后需处理一种特殊情况:当计算出的宽或长为0或负数时,表明两个矩形不相交,此时相交面积为0,IoU也为0。对此有两种处理策略:

1. 使用if语句进行分类讨论:


if w <=0 or h <= 0:
 return 0

2. 使用max()函数进行处理:


w = max(0, (x2 - x1))
h = max(0, (y1 - y2))

Python3代码实现

三、Python3 实现代码

经过上述分析,思路已十分清晰。以下直接提供完整的Python3代码实现。


def calculate_IoU(predicted_bound, ground_truth_bound):
 """
 computing the IoU of two boxes.
 Args:
  box: (xmin, ymin, xmax, ymax),通过左下和右上两个顶点坐标来确定矩形位置
 Return:
  IoU: IoU of box1 and box2.
 """
 pxmin, pymin, pxmax, pymax = predicted_bound
 print("预测框P的坐标是:({}, {}, {}, {})".format(pxmin, pymin, pxmax, pymax))
 gxmin, gymin, gxmax, gymax = ground_truth_bound
 print("原标记框G的坐标是:({}, {}, {}, {})".format(gxmin, gymin, gxmax, gymax))

 parea = (pxmax - pxmin) * (pymax - pymin) # 计算P的面积
 garea = (gxmax - gxmin) * (gymax - gymin) # 计算G的面积
 print("预测框P的面积是:{};原标记框G的面积是:{}".format(parea, garea))

 # 求相交矩形的左下和右上顶点坐标(xmin, ymin, xmax, ymax)
 xmin = max(pxmin, gxmin) # 得到左下顶点的横坐标
 ymin = max(pymin, gymin) # 得到左下顶点的纵坐标
 xmax = min(pxmax, gxmax) # 得到右上顶点的横坐标
 ymax = min(pymax, gymax) # 得到右上顶点的纵坐标

 # 计算相交矩形的面积
 w = xmax - xmin
 h = ymax - ymin
 if w <=0 or h <= 0:
  return 0

 area = w * h # G∩P的面积
 # area = max(0, xmax - xmin) * max(0, ymax - ymin) # 可以用一行代码算出来相交矩形的面积
 print("G∩P的面积是:{}".format(area))

 # 并集的面积 = 两个矩形面积 - 交集面积
 IoU = area / (parea + garea - area)

 return IoU

if __name__ == '__main__':
 IoU = calculate_IoU( (1, -1, 3, 1), (0, 0, 2, 2))
 print("IoU是:{}".format(IoU))

此外,这里也提供了基于左上和右下顶点坐标确定矩形位置的Python3代码。其原理相同,请注意区分使用场景即可。


def calculate_IoU(predicted_bound, ground_truth_bound):
 """
 computing the IoU of two boxes.
 Args:
  box: (x1, y1, x2, y2),通过左上和右下两个顶点坐标来确定矩形
 Return:
  IoU: IoU of box1 and box2.
 """
 px1, py1, px2, py2 = predicted_bound
 print("预测框P的坐标是:({}, {}, {}, {})".format(px1, py1, px2, py2))

 gx1, gy1, gx2, gy2 = ground_truth_bound
 print("原标记框G的坐标是:({}, {}, {}, {})".format(gx1, gy1, gx2, gy2))

 parea = (px2 - px1) * (py1 - py2) # 计算P的面积
 garea = (gx2 - gx1) * (gy1 - gy2) # 计算G的面积
 print("预测框P的面积是:{};原标记框G的面积是:{}".format(parea, garea))

 # 求相交矩形的左上和右下顶点坐标(x1, y1, x2, y2)
 x1 = max(px1, gx1) # 得到左上顶点的横坐标
 y1 = min(py1, gy1) # 得到左上顶点的纵坐标
 x2 = min(px2, gx2) # 得到右下顶点的横坐标
 y2 = max(py2, gy2) # 得到右下顶点的纵坐标

 # 利用max()方法处理两个矩形没有交集的情况,当没有交集时,w或者h取0,比较巧妙的处理方法
 # w = max(0, (x2 - x1)) # 相交矩形的长,这里用w来表示
 # h = max(0, (y1 - y2)) # 相交矩形的宽,这里用h来表示
 # print("相交矩形的长是:{},宽是:{}".format(w, h))
 # 这里也可以考虑引入if判断
 w = x2 - x1
 h = y1 - y2
 if w <=0 or h <= 0:
  return 0

 area = w * h # G∩P的面积
 print("G∩P的面积是:{}".format(area))

 # 并集的面积 = 两个矩形面积 - 交集面积
 IoU = area / (parea + garea - area)

 return IoU

if __name__ == '__main__':
 IoU = calculate_IoU( (1, 1, 3, -1), (0, 2, 2, 0))
 print("IoU是:{}".format(IoU))

以上便是关于Python3实现两个矩形交并比(IoU)的全部内容,希望能对大家有所帮助,欢迎支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表