目标检测中的IOU和CIOU原理讲解以及应用(附测试代码)
上期讲解了目标检测中的三种数据增强的方法,这期我们讲讲目标检测中用来评估对象检测算法的IOU和CIOU的原理应用以及代码实现。
交并比IOU(Intersection over union)
在目标检测任务中,我们用框框来定位对象,如下图定位图片中这个汽车,假设实际框是图中红色的框框,你的算法预测给出的是紫色的框框,怎么判断你的算法预测的这个框框的效果好坏呢?
这就用到我们的交并比函数IOU了,计算公式如下:
将我们图片汽车的实际红色框记为A,算法的预测框记为B,交并比就是数学中A和B的交集A∩B跟A和B的并集的A∪B的面积之比,非常容易理解。IOU实际上衡量了两个边界框重叠地相对大小,预测框和真实框重叠越大,说明你的算法预测效果比较好,IOU是一个评价指标。
那么回到刚刚的问题:如何利用IOU进行判断算法的预测效果好坏呢?也就是这个预测框是否可以当做正确的定位到我们的目标汽车呢?
在计算机检测任务中,如果我们算法的预测框和实际框之间的交并比IOU≧0.5,那么你的算法预测结果是可以接受的,就说你预测的这个框框是正确的,这个阈值0.5,你可以设置得更高,边界框越精确,在YOLOv3中正是用到这个IOU来对我们的先验框进行了一个筛选,以及计算测试集的模型效果mAP时也用到了IOU进行阈值判断。
效果图
首先借助Opencv和numpy框画两个框,然后计算IOU进行展示,如下图。
IOU实现代码
以框的左上角(x1,y1)和右下角(x2,y2)坐标形式来计算它们之间的IOU。
import cv2
import numpy as np
def CountIOU(RecA, RecB):
xA = max(RecA[0], RecB[0])
yA = max(RecA[1], RecB[1])
xB = min(RecA[2], RecB[2])
yB = min(RecA[3], RecB[3])
# 计算交集部分面积
interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)
# 计算预测值和真实值的面积
RecA_Area = (RecA[2] - RecA[0] + 1) * (RecA[3] - RecA[1] + 1)
RecB_Area = (RecB[2] - RecB[0] + 1) * (RecB[3] - RecB[1] + 1)
# 计算IOU
iou = interArea / float(RecA_Area + RecB_Area - interArea)
return iou
if __name__ == "__main__":
img = np.zeros((512, 512, 3), np.uint8)
img.fill(255)
RecA = [50, 50, 300, 300] # x1,y1,x2,y2
RecB = [60, 60, 320, 320]
cv2.rectangle(img, (RecA[0], RecA[1]), (RecA[2], RecA[3]), (0, 255, 0), 5)
cv2.rectangle(img, (RecB[0], RecB[1]), (RecB[2], RecB[3]), (255, 0, 0), 5)
IOU = CountIOU(RecA, RecB)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, "IOU = %.2f" % IOU, (130, 190), font, 0.8, (0, 0, 0), 2)
cv2.imshow("image", img)
cv2.waitKey()
cv2.destroyAllWindows()
CIOU(Complete-IOU)
IoU是比值的概念,对目标物体的尺寸scale是不敏感的。我们在计算框框BBox的回归损失函数进行优化有多种优化方式,如在CIOU之前有GIOU、DIOU,而CIOU解决了一般IoU无法直接优化两个框框没有重叠的部分。
IoU经过GIOU再到DIOU最终发展到CIOU,CIOU将目标与框框anchor之间的距离,重叠率、尺度以及惩罚项都考虑进去,使得目标框回归变得更加稳定,不会像IoU和GIoU一样出现训练过程中发散等问题,而惩罚因子把预测框长宽比拟合目标框的长宽比考虑进去,在最新发布的yolov4中anchor的回归就是用的CIOU方式。
CIOU计算公式
效果图
首先借助Opencv和numpy框画两个框,然后按照公式计算CIOU进行展示,如下图。
代码实现:
import torch
import numpy as np
import cv2
import math
def box_ciou(b1, b2):
"""
输入为: ----------
b1: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
b2: tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
返回为: -------
ciou: tensor, shape=(batch, feat_w, feat_h, anchor_num, 1)
"""
# 求出预测框左上角右下角
b1_xy = b1[..., :2]
b1_wh = b1[..., 2:4]
b1_wh_half = b1_wh/2.
b1_mins = b1_xy - b1_wh_half
b1_maxes = b1_xy + b1_wh_half
# 求出真实框左上角右下角
b2_xy = b2[..., :2]
b2_wh = b2[..., 2:4]
b2_wh_half = b2_wh/2.
b2_mins = b2_xy - b2_wh_half
b2_maxes = b2_xy + b2_wh_half
# 求真实框和预测框所有的iou
intersect_mins = torch.max(b1_mins, b2_mins)
intersect_maxes = torch.min(b1_maxes, b2_maxes)
intersect_wh = torch.max(intersect_maxes - intersect_mins, torch.zeros_like(intersect_maxes))
intersect_area = intersect_wh[..., 0] * intersect_wh[..., 1]
b1_area = b1_wh[..., 0] * b1_wh[..., 1]
b2_area = b2_wh[..., 0] * b2_wh[..., 1]
union_area = b1_area + b2_area - intersect_area
iou = intersect_area / (union_area + 1e-6)
# 计算中心的差距
center_distance = torch.sum(torch.pow((b1_xy - b2_xy), 2), axis=-1)
# 找到包裹两个框的最小框的左上角和右下角
enclose_mins = torch.min(b1_mins, b2_mins)
enclose_maxes = torch.max(b1_maxes, b2_maxes)
enclose_wh = torch.max(enclose_maxes - enclose_mins, torch.zeros_like(intersect_maxes))
# 计算对角线距离
enclose_diagonal = torch.sum(torch.pow(enclose_wh,2), axis=-1)
ciou = iou - 1.0 * (center_distance) / (enclose_diagonal + 1e-7)
v = (4 / (math.pi ** 2)) * torch.pow((torch.atan(b1_wh[..., 0]/b1_wh[..., 1]) - torch.atan(b2_wh[..., 0]/b2_wh[..., 1])), 2)
alpha = v / (1.0 - iou + v)
ciou = ciou - alpha * v
return ciou
if __name__ == "__main__":
img = np.zeros((512, 512, 3), np.uint8)
img.fill(255)
RecA = [1, 90, 90, 150, 150]
RecB = [1, 150, 150, 200, 200]
a = torch.tensor(RecA, dtype=torch.float) # tensor, shape=(batch, feat_w, feat_h, anchor_num, 4), xywh
b = torch.tensor(RecB, dtype=torch.float)
cv2.rectangle(img, (int(RecA[1]-RecA[3]/2), int(RecA[2]-RecA[4]/2)), (int(RecA[1]+RecA[3]/2), int(RecA[2]+RecA[4]/2)), (0, 255, 0), 5)
cv2.rectangle(img,(int(RecB[1]-RecB[3]/2), int(RecB[2]-RecB[4]/2)), (int(RecB[1]+RecB[3]/2), int(RecB[2]+RecB[4]/2)), (255, 0, 0), 5)
CIOU = box_ciou(a,b)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img, "CIOU = %.2f" % CIOU, (130, 190), font, 0.8, (0, 0, 0), 2)
cv2.imshow("image", img)
cv2.waitKey()
cv2.destroyAllWindows()
相关代码,还请关注微信公众号:码农的后花园,回复关键字:IOU,下载使用。
更多有关python、深度学习和计算机编程和电脑知识的精彩内容,可以关注微信公众号:码农的后花园
目标检测中的IOU和CIOU原理讲解以及应用(附测试代码)的更多相关文章
- Adaboost原理及目标检测中的应用
Adaboost原理及目标检测中的应用 whowhoha@outlook.com Adaboost原理 Adaboost(AdaptiveBoosting)是一种迭代算法,通过对训练集不断训练弱分类器 ...
- 目标检测算法(1)目标检测中的问题描述和R-CNN算法
目标检测(object detection)是计算机视觉中非常具有挑战性的一项工作,一方面它是其他很多后续视觉任务的基础,另一方面目标检测不仅需要预测区域,还要进行分类,因此问题更加复杂.最近的5年使 ...
- 目标检测 1 : 目标检测中的Anchor详解
咸鱼了半年,年底了,把这半年做的关于目标的检测的内容总结下. 本文主要有两部分: 目标检测中的边框表示 Anchor相关的问题,R-CNN,SSD,YOLO 中的anchor 目标检测中的边框表示 目 ...
- 目标检测算法之R-CNN和SPPNet原理
一.R-CNN的原理 R-CNN的全称是Region-CNN,它可以说是第一个将深度学习应用到目标检测上的算法.后面将要学习的Fast R-CNN.Faster R-CNN全部都是建立在R-CNN基础 ...
- 【计算机视觉】目标检测中的指标衡量Recall与Precision
[计算机视觉]目标检测中的指标衡量Recall与Precision 标签(空格分隔): [图像处理] 说明:目标检测性能指标Recall与Precision的理解. Recall与Precision ...
- 目标检测中proposal的意义
在目标检测中,从很早就有候选区域的说法,也是在2008年可能就有人使用这个方法,在2014年的卷积神经网络解决目标检测问题的文章中,这个候选框方法大放异彩,先前的目标检测方法主要集中在使用滑动窗口的方 ...
- 目标检测中的bounding box regression
目标检测中的bounding box regression 理解:与传统算法的最大不同就是并不是去滑窗检测,而是生成了一些候选区域与GT做回归.
- 目标检测中的anchor-based 和anchor free
目标检测中的anchor-based 和anchor free 1. anchor-free 和 anchor-based 区别 深度学习目标检测通常都被建模成对一些候选区域进行分类和回归的问题.在 ...
- 目标检测中特征融合技术(YOLO v4)(下)
目标检测中特征融合技术(YOLO v4)(下) ASFF:自适应特征融合方式 ASFF来自论文:<Learning Spatial Fusion for Single-Shot Object D ...
随机推荐
- IndexFlatL2、IndexIVFFlat、IndexIVFPQ三种索引方式示例
上文针对Faiss安装和一些原理做了简单说明,本文针对标题所列三种索引方式进行编码验证. 首先生成数据集,这里采用100万条数据,每条50维,生成数据做本地化保存,代码如下: import numpy ...
- 工作小记[csv文件、admin中filed与list_display区别、ModuleNotFoundError: No module named'xxx'、django创建admin用户]
CSV-Comma Separated Values,CSV文件可以直接用Excel表格打开,如果用文本打开属性之间用逗号隔开,Python有直接操作CSV文件的函数. fileds字段控制“修改添加 ...
- 2020-07-13:es是去查id再根据id去查数据库这种方式好,还是所有数据都放es,直接去查es好?
福哥答案2020-07-13: 有人觉得第一种方法好,也有人觉得第二种方法好.如果搜索字段远小于显示字段,比如搜索字段为3个,显示字段有20个,这个时候用第一种方法好.es+hbase,一般这样搭配. ...
- TD课程通的使用体验
这个软件一点进去便是石家庄铁道大学,但是那张图片可以尽量的缩小一点比例,可以选择部分,至少能够让人了解到这是什么,另外,可以添加注册功能,或者是使用学号什么的来登录,亦或者手机号码等,整体的展示效果还 ...
- eclipse中点击pre-commit Request to ReviewBoard,预提交框不显示问题
需要设置:
- 第二章 Kuberbetes实践指南
kubernetes安装与配置 网络,安全,服务启动配置 参考: kubernetes权威指南第二版 kubectl命令行工具用法详解 kubectl [command] [type] [name] ...
- unity探索者之protobuf的序列化和反序列化导致unity崩溃的问题研究
版权声明:本文为原创文章,转载请声明http://www.cnblogs.com/unityExplorer/p/7574569.html 这两天博主在接微信支付SDK的时候碰到一个非常恶心又诡异的问 ...
- Apache Hudi 0.6.0版本重磅发布
1. 下载信息 源码:Apache Hudi 0.6.0 Source Release (asc, sha512) 二进制Jar包:nexus 2. 迁移指南 如果您从0.5.3以前的版本迁移至0.6 ...
- Java面试题(反射篇+对象拷贝篇)
反射 57.什么是反射? 反射主要是指程序可以访问.检测和修改它本身状态或行为的一种能力 Java反射: 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否 ...
- IDEA2019.3激活
1 下载: 1.1 下载安装文件 https://blog.csdn.net/Beuty_Chen/article/details/103804886 1.2 下载激活补丁 链接 ...