机器视觉中的交并比IoU:概念、计算及代码实现
创作时间:
作者:
@小白创作中心
机器视觉中的交并比IoU:概念、计算及代码实现
引用
CSDN
1.
https://blog.csdn.net/qq_35644010/article/details/136237635
在目标检测领域,交并比(IoU,全称Intersection of Union)是目标检测和分割任务中一个重要的衡量标准。它用来描述两个边界框(或两个分割掩模)之间的重叠程度,其值范围在0到1之间,值越大表示重叠程度越高。
交并比IoU的基本概念
交并比这一概念来源于数学中的集合论,用于描述两个集合A和B之间的关系。具体来说,IoU等于两个集合的交集区域面积除以它们的并集区域面积,计算公式如下:
$$
IoU = \frac{A \cap B}{A \cup B}
$$
在目标检测任务中,通常将IoU大于某个阈值(例如0.5)的边界框视为检测正确,否则视为检测错误。在分割任务中,IoU常用于计算分割的准确率和召回率等指标。
交并比IoU的计算方法
假设我们有两个矩形框A和B,它们的位置分别由左上角和右下角的坐标表示。为了计算这两个矩形框的IoU,我们需要先确定它们的交集和并集区域。
- 计算交集区域的坐标:
- 交集区域的左上角坐标为两个矩形框左上角坐标的最大值:
xA = max(RecA[0], RecB[0]),yA = max(RecA[1], RecB[1]) - 交集区域的右下角坐标为两个矩形框右下角坐标的最小值:
xB = min(RecA[2], RecB[2]),yB = min(RecA[3], RecB[3])
- 计算交集区域的面积:
- 交集区域的面积为
(xB - xA + 1) * (yB - yA + 1),其中加1是为了防止没有交集时出现负数的情况。
- 计算并集区域的面积:
- 矩形框A的面积为
(RecA[2] - RecA[0] + 1) * (RecA[3] - RecA[1] + 1) - 矩形框B的面积为
(RecB[2] - RecB[0] + 1) * (RecB[3] - RecB[1] + 1) - 并集区域的面积为两个矩形框面积之和减去交集区域的面积。
- 计算IoU:
- 最终的IoU值为交集区域面积除以并集区域面积。
交并比大小与重合度的关系
IoU的大小直观地反映了两个矩形框的重合程度。当IoU为1时,表示两个矩形框完全重合;当IoU为0时,表示两个矩形框没有任何重叠。下图示意了不同IoU值下两个框之间的相对位置关系:
代码实现
简单示例
下面是一个简单的Python代码示例,演示如何计算两个矩形框的IoU。在这个例子中,我们使用OpenCV库来绘制矩形框并显示结果。
import cv2
import numpy as np
from matplotlib import pyplot as plt
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
img = np.zeros((512,512,3), np.uint8)
img.fill(255)
RecA = [50,50,300,300]
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.imwrite('output_image.jpg', img)
# 在Colab中显示图像文件
image = cv2.imread('output_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
图片实现
接下来,我们使用一张包含小女孩和小狗的图片来演示IoU的计算。在这个例子中,我们预先定义了两个矩形框A和B的坐标,分别对应于小女孩和小狗的位置。
import cv2
import numpy as np
from matplotlib import pyplot as plt
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
img = cv2.imread('/content/girlwithdog.jpg')
if img is None:
print("Error: Could not read the image.")
exit()
RecA = [381,86,715,651]
RecB = [558,371,781,608]
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,(580, 500),font,1.0,(0,0,255),2,cv2.LINE_AA)
# 保存图像文件
cv2.imwrite('output_image.jpg', img)
# 在Colab中显示图像文件
image = cv2.imread('output_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('off')
plt.show()
从XML文件读取边界框
在实际应用中,边界框的信息往往存储在XML文件中。下面的代码展示了如何从XML文件中读取边界框信息并计算IoU。
import cv2
import numpy as np
from matplotlib import pyplot as plt
import xml.etree.ElementTree as ET
from PIL import Image
import matplotlib.patches as patches
# 解析XML文件
xml_file = '/content/girlwithdog.xml'
tree = ET.parse(xml_file)
root = tree.getroot()
# 获取图像文件名
filename = root.find('filename').text
# 获取图像尺寸
size = root.find('size')
width = int(size.find('width').text)
height = int(size.find('height').text)
# 读取图像
image_path = filename
image = Image.open(image_path)
# 定义类别和对应的颜色
category_colors = {'dog': 'r', 'person': 'b', 'car': 'g'}
# 获取并绘制边界框
for obj in root.findall('object'):
# 获取类别和边界框信息
obj_name = obj.find('name').text
bbox = obj.find('bndbox')
xmin = int(bbox.find('xmin').text)
ymin = int(bbox.find('ymin').text)
xmax = int(bbox.find('xmax').text)
ymax = int(bbox.find('ymax').text)
width = xmax - xmin
height = ymax - ymin
# 绘制边界框
rect = patches.Rectangle((xmin, ymin), width, height, linewidth=1, edgecolor=category_colors[obj_name], facecolor='none')
plt.gca().add_patch(rect)
plt.text(xmin, ymin - 5, obj_name, color='yellow', fontsize=8, ha='left', va='top')
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
img = cv2.imread('/content/girlwithdog.jpg')
if img is None:
print("Error: Could not read the image.")
exit()
IOU = CountIOU(RecA,RecB)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"IOU = %.2f"%IOU,(580, 500),font,1.0,(0,0,255),2,cv2.LINE_AA)
# 保存图像文件
cv2.imwrite('output_image.jpg', img)
# 在Colab中显示图像文件
image = cv2.imread('output_image.jpg')
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
plt.axis('on')
plt.show()
通过以上代码,我们可以清晰地看到两个边界框的IoU值,并直观地理解它们的重叠程度。
热门推荐
明世隐化身神秘电台主播!“夜落电台”皮肤深度解析
武功山几小时能爬完?五月徒步攻略速览
“八纵八横”渝昆高铁渝宜段开通,重庆至宜宾缩至48分钟
胃不好怎么吃水果?遵守这两个原则,否则越吃身体越糟糕
离婚后与前任相处三原则:尊重、合作、沟通
上海圣诞节必去三地:外滩源市集、思南公馆文艺范、欢乐谷狂欢夜
罗汉果栽培历史
掌握饵水比和状态饵,轻松制作高附钩性搓饵
稳压芯片AMS1117详解:两种版本功能与使用方法
财富自由密码:五个层级与五大途径全解析
从家政到摄政:塞琉古帝国女性地位探析
银川地震频发,宁夏地震局教你如何正确应对
错失点球后,李毅转型青训教练培育足球新苗
武夷山两日游必打卡:天游峰
北欧自驾游:斯德哥尔摩和卑尔根的最佳打卡点
《哈利·波特与混血王子》:英语学习者的魔法钥匙
第三套人民币5元纸币:收藏价值与投资前景
益生菌补充剂:抗生素后遗症的新疗法
爱而不得?这些话或许能温暖你的心
兵家之祖孙武:《孙子兵法》的智慧与永恒
爱而不得的情感文案,让你秒懂心碎
浙江卫视今晚播出《清明上河图密码》:一幅画里的千年传奇
一处失信处处受限,宁夏构建社会信用体系见成效
生吃大蒜降血压?专家:作用有限,健康生活更关键
《地理·中国》揭秘辽阳古城变迁:2300年沧桑见证东北文明发展
突破中考数学压轴题:代数几何解题策略
张宇带你玩转考研高数:从基础到高分的制胜秘诀
汉景帝之母弟弟被拐卖,古代人贩子有多猖獗?
精益六西格玛、品管圈、5S/6S:医院管理提效利器
日本建筑学留学攻略:六大名校详解及申请条件