如何计算交并比IoU | 含图片说明和伪代码实现

文章详细介绍了IoU(交并比)的概念,即两个矩形框交集面积与并集面积的比值,并提供了计算交集和并集面积的步骤,以及如何通过Python代码实现两个矩形框的IoU计算。文中还涵盖了无交集情况的处理和IoU在目标检测中的重要性。
摘要由CSDN通过智能技术生成

交并比的定义

IoU(Intersection over Union)即交并比,定义为两个矩形框的交集面积除以并集面积。

所以计算交并比问题,可以转化为计算矩形框交集面积和并集面积问题。

计算矩形框交集面积

两个矩形框交集部分为规整的矩形,可以用矩形长乘以宽计算得到面积:

矩形框的宽和高分别通过x轴坐标和y轴坐标计算获得:w = x_min - x_max、h = y_max - y_min,难点在于获取两个方向上的坐标值,以x轴为例:

图中x_min和x_max为需要获取的坐标值,根据矩形框位置不同,坐标值来源不同:图一中x_min是红色框的x_left(边框左边点x轴坐标值),图二和图三中则是绿色框的x_left。

但不管哪种情况,x_min始终来源于两个框的x_left,再仔细观察发现,x_min始终是两个x_left中靠右(值较大)的那个,所以对于x_min,可以通过比较x_left获得。对于x_max也是相同的,它始终是两个x_right中靠左(值较小)的那个。再看y轴上需要获取的坐标,可以发现与x轴坐标是类似的:

对于y_min,始终是两个y_top中靠下(值较大)的那个;对于y_max,始终是两个y_bottom中靠上(值较小)的那个。

所以给定两个框的坐标,求它们交集部分坐标及面积的方法如下:

# 传入参数 | bbox_red:红色框坐标 | bbox_green:绿色框坐标
# 注释:坐标格式为(x_left, y_top, x_right, y_bottom)(voc格式坐标,即边框左上角点坐标和右下角点坐标)
def get_IoU(bbox_red, bbox_green):
    # 步骤一:获取交集部分坐标
    ix_min = max(bbox_red[0], bbox_green[0]) # 两个 x_left 中[靠右]的那个
    iy_min = max(bbox_red[1], bbox_green[1]) # 两个 y_top 中[靠下]的那个
    ix_max = min(bbox_red[2], bbox_green[2]) # 两个 x_right 中[靠左]的那个
    iy_max = min(bbox_red[3], bbox_green[3]) # 两个 y_bottom 中[靠上]的那个
    
    # 步骤二:计算交集部分的宽和高
    # 注:可能出现宽度或高度为负数的情况,此时两个框没有交集,交并比为0
    iw = max(ix_max - ix_min, 0.0)
    ih = max(iy_max - iy_min, 0.0)
    
    # 步骤三:计算交集部分面积
    inters = iw * ih

计算矩形框并集面积

计算交并比还需要两个矩形框的并集面积,计算方法为绿色框面积+红色框面积-交集面积:

原因及组合方法如下,由于重复累加了交集面积,所以末尾减掉其中一块交集面积:

计算交并比的代码实现

最后将交集面积除以并集面积即可得到交并比:

# 传入参数 | bbox_red:红色框坐标 | bbox_green:绿色框坐标
# 注释:坐标格式为(x_left, y_top, x_right, y_bottom)(voc格式坐标,即边框左上角点坐标和右下角点坐标)
def get_IoU(bbox_red, bbox_green):
    # 步骤一:获取交集部分坐标
    ix_min = max(bbox_red[0], bbox_green[0]) # 两个 x_left 中[靠右]的那个
    iy_min = max(bbox_red[1], bbox_green[1]) # 两个 y_top 中[靠下]的那个
    ix_max = min(bbox_red[2], bbox_green[2]) # 两个 x_right 中[靠左]的那个
    iy_max = min(bbox_red[3], bbox_green[3]) # 两个 y_bottom 中[靠上]的那个
    
    # 步骤二:计算交集部分的宽和高
    # 注:可能出现宽度或高度为负数的情况,此时两个框没有交集,交并比为0
    iw = max(ix_max - ix_min, 0.0)
    ih = max(iy_max - iy_min, 0.0)
    
    # 步骤三:计算交集部分面积
    inters = iw * ih
    
    # 步骤四:计算两个框的面积
    # area = w * h = (x_right - x_left) * (y_bottom - y_top)
    red_area = (bbox_red[2] - bbox_red[0]) * (bbox_red[3] - bbox_red[1]) 
    green_area = (bbox_green[2] - bbox_green[0]) * (bbox_green[3] - bbox_green[1]) 
    
    # 步骤五:计算并集面积
    uni = red_area + green_area - inters # 红色框面积 + 绿色框面积 - 交集面积
    
    # 步骤六:计算和返回交并比
    overlaps = inters / uni
    return overlaps

代码测试

有交集的情况:

if __name__ == '__main__':
	bbox_red = [2, 3, 9, 10]
	bbox_green = [1, 2, 7, 8]
	print('r&g: ', get_IoU(bbox_red, bbox_green)) # 计算红色框与绿色框的交并比
	print('self: ', get_IoU(bbox_green, bbox_green)) # 计算边框完全重合时的交并比

输出:

r&g:  0.4166666666666667
self:  1.0

没有交集的情况:

if __name__ == '__main__':
	bbox_red = [9, 3, 16, 10]
	bbox_green = [1, 2, 7, 8]
	print('none: ', get_IoU(bbox_red, bbox_green))

输出:

none:  0.0

参考链接

目标检测番外篇(1)_IoU

【Batch IOU】IOU计算的简单理解

目标检测之 IoU

本文作者:吉平. 「集」,如有侵权请联系。

㈠ 点的基本运算 1. 平面上两点之间距离 2. 判断两点是否重合 3. 矢量叉乘 4. 矢量点乘 5. 判断点是否在线段上 6. 求一点饶某点旋转后的坐标 7. 求矢量夹角 ㈡ 线段及直线的基本运算 1. 点与线段的关系 2. 求点到线段所在直线垂线的垂足 3. 点到线段的最近点 4. 点到线段所在直线的距离 5. 点到折线集的最近距离 6. 判断圆是否在多边形内 7. 求矢量夹角余弦 8. 求线段之间的夹角 9. 判断线段是否相交 10.判断线段是否相交但不交在端点处 11.求线段所在直线的方程 12.求直线的斜率 13.求直线的倾斜角 14.求点关于某直线的对称点 15.判断两条直线是否相交及求直线交点 16.判断线段是否相交,如果相交返回交点 ㈢ 多边形常用算法模块 1. 判断多边形是否简单多边形 2. 检查多边形顶点的凸凹性 3. 判断多边形是否凸多边形 4. 求多边形面积 5. 判断多边形顶点的排列方向,方法一 6. 判断多边形顶点的排列方向,方法二 7. 射线法判断点是否在多边形内 8. 判断点是否在凸多边形内 9. 寻找点集的graham算法 10.寻找点集凸包的卷包裹法 11.判断线段是否在多边形内 12.求简单多边形的重心 13.求凸多边形的重心 14.求肯定在给定多边形内的一个点 15.求从多边形外一点出发到该多边形的切线 16.判断多边形的核是否存在 ㈣ 圆的基本运算 1 .点是否在圆内 2 .求不共线的三点所确定的圆 ㈤ 矩形的基本运算 1.已知矩形三点坐标,求第4点坐标 ㈥ 常用算法的描述 ㈦ 补充 1.两圆关系 2.判断圆是否在矩形内 3.点到平面的距离 4.点是否在直线同侧 5.镜面反射线 6.矩形包 7.两圆交点 8.两圆公共面积 9. 圆和直线关系 10. 内切圆 11. 求切点 12. 线段的左右旋 13.公式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值