侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

浅谈Python3实现两个矩形的交并比(IoU)

Python  /  管理员 发布于 7年前   506

一、前言

因为最近刚好被问到这个问题,但是自己当时特别懵逼,导致没有做出来。所以下来后自己Google了很多IoU的博客,但是很多博客要么过于简略,要么是互相转载的,有一些博客图和代码还有点问题,也导致自己这个萌新走了不少弯路。所以自己重新整理了看的博客,力求以更简单的方式展现这个问题的解答办法,方便日后自己回顾。如果朋友们觉得写的有问题的地方,非常欢迎大家在下面留言交流,避免因为我的问题导致读者走弯路。

二、交并比的概念及应用

假设平面坐标中有一个矩形,并且这个矩形的长和宽均分别与x轴和y轴平行。

那么矩形在平面坐标中的唯一位置可以通过对角线上的两个顶点坐标来确定(这里不做证明)。

如下图所示:这个矩形的唯一位置可以用左上和右下的顶点坐标,即:(xmin, ymax, xmax, ymin)来确定,也可以用左下和右上顶点坐标,即(xmin, ymin, xmax, ymax)来确定。

接下来说一下自己踩的坑:网上的大部分博客,图是标的是左上和右下的顶点坐标,但是代码清一色是通过左下和右上顶点坐标来确定矩形位置的。所以一开始看着特别晕圈。

理论上两种确定方式都可以,不过相对而言,通过左下和右上两个顶点坐标,即(xmin, ymin, xmax, ymax)来确定矩形位置更符合我们的习惯,我想这也是网上大部分代码都是这样的原因吧。

矩形的面积很好求,长X宽就行:

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

好了,理清楚怎么确定矩形的位置后,接下来我们就来解决交并比的计算问题。

交并比(Intersection over Union, IoU)是目标检测任务中的一个非常重要的概念。它是产生的预测框(Predicted bounding box)与原标记框(Ground-truth bounding box)的交叠率,即它们的交集(相交面积)与并集(总面积)的比值。最理想情况是完全重叠,即比值为1。一般来说,这个score > 0.5 就可以被认为是一个不错的结果。这个标准用于测量真实和预测之间的相关度,相关度越高,该值越高,它可以评估算法的准确度。

假设平面坐标中有两个矩形:原标记框(Ground-truth bounding box, G)和预测框(Predicted bounding box, P),其中G为手动标记的框,P为算法预测的框,并且这两个矩形的长和宽均分别与x轴和y轴平行。如下图所示:

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) = 长 X 宽

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

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

area(G∩P) = w X 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代码。

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 IoUif __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 IoUif __name__ == '__main__': IoU = calculate_IoU( (1, 1, 3, -1), (0, 2, 2, 0)) print("IoU是:{}".format(IoU))

以上这篇浅谈Python3实现两个矩形的交并比(IoU)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


  • 上一条:
    python不使用for计算两组、多个矩形两两间的iou方式
    下一条:
    利用setuptools打包python程序的方法步骤
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客