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

Posted 吉平. 「集」

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何计算交并比IoU | 含图片说明和伪代码实现相关的知识,希望对你有一定的参考价值。

交并比的定义

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

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

以上是关于如何计算交并比IoU | 含图片说明和伪代码实现的主要内容,如果未能解决你的问题,请参考以下文章

使用Python计算四边形与拟合四边形的最大交并比IOU

使用Python计算四边形与拟合四边形的最大交并比IOU

目标检测计算两个标注框的交并比(python代码)

intersection-over-union(IoU: 交并比)

目标检测中各种IoU说明

目标检测+mAP+IoU