#IoU
#给定两个边界框或锚框的列表
def box_iou(boxes1,boxes2):
""" 计算两个锚框或边界框列表中成对的交并比"""
box_area = lambda boxes : ((boxes[:,2]-boxes[:,0])*(boxes[:,3]-boxes[:,1])) #box面积
# boxes1:[nums_boxes1,4]
# boxes2:[nums_boxes2,4]
# areas1:[nums_boxes1,]
# areas2:[nums_boxes2,]
areas1 = box_area(boxes1)
areas2 = box_area(boxes2)
"""
areas1:tensor([100., 225.])
areas2:tensor([144., 676.])
"""
#print(f"areas1:{areas1}\n areas2:{areas2}")
"""
inter_upperlefts ,inter_lowerrights,inters :
shape:(nums_boxes1,nums_boxes2,2)
box_axis:[xmin,ymin,xmax,ymax]
"""
inter_upperlefts = torch.max(boxes1[:,None,:2],boxes2[:,:2]) #[:2]左上角,两两组合所有左上角坐标max值
inter_lowerrights = torch.min(boxes1[:,None,2:],boxes2[:,2:]) #[2:]右下角
inters =(inter_lowerrights - inter_upperlefts).clamp(min=0) #clamp确保不出现负数
"""
inter_upperlefts: 4组坐标左上角max值(与右下角一一对应)
tensor([[[13., 13.],
[22., 22.]],
[[15., 15.],
[22., 22.]]])
inter_lowerrights:4组坐标右下角min值
tensor([[[20., 20.],
[20., 20.]],
[[25., 25.],
[30., 30.]]])
inters:(右下角-左上角)得到每一对box交集的(宽,高)
tensor([[[ 7., 7.],
[ 0., 0.]],
[[10., 10.],
[ 8., 8.]]])
"""
print(f"inters:{inters}")
# inter_areas , union_areas ,shape:[nums_boxes1,nums_boxes2]
inter_areas =inters[:,:,0] * inters[:,:,1] #分子 每一组数据的宽和高相乘获得交集面积
union_areas =areas1[:,None] + areas2 - inter_areas #分母
"""
inter_areas:
tensor([[[ 7., 7.],
[ 0., 0.]],
[[10., 10.],
[ 8., 8.]]])
union_areas:
tensor([[195., 776.],
[269., 837.]])
"""
return inter_areas / union_areas
#-----Test--------------------
#假设每个box中有两组数据:[2,4]
boxes1 = [ [10.,10.,20.,20.],
[15.,15.,30.,30.]]
boxes2 = [[13.,13.,25.,25.],
[22.,22.,48.,48.]]
boxes1 = torch.tensor(boxes1)
boxes2 = torch.tensor(boxes2)
print(boxes2.shape)
box_iou(boxes1,boxes2)
输出:
tensor([[0.25, 0.00],
[0.37, 0.08]])
如何理解左上角和右下角坐标计算代码?![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/8cec84d07478f01e9cdb6bebab65097e.jpeg)
x =torch.arange(4,8).view(2,2)
y = torch.arange(4).view(2,2)
print(x,y)
"""
x:tensor([[4, 5],
[6, 7]])
----------------------
y:tensor([[0, 1],
[2, 3]])
-------------------------------------
x[:,None,:]: 根据广播机制,x会在中间None创建的新维度复制数据形成[2,2,2]以匹配y的维度[2,2],只有在计算的时候才会复制,打印不出来
tensor([[[4, 5],
[4,5]],
[[6, 7],
[6,7]]])
"""
print(x[:,None,:]-y[:,:]) #shape:[2,1,2]-[2,2]
"""
输出:
tensor([[[4, 4],
[2, 2]],
[[6, 6],
[4, 4]]])
"""