IoU计算代码
前言
刚入门的时候,尤其对于算法,很多东西不自己亲自写一遍是很难真正理解透的。最近在准备复现yolo的代码,对于IoU的实现,就遇到一点小问题,在此记录一下。
torch实现的方式
矩阵运算速度更快,代码更简洁。这里取最大最小值,需要利用广播的机制。
def bbox_iou(box1, box2,):
"""
x1y1x2y2格式
Returns the IoU of two bounding boxes
"""
# Get the coordinates of bounding boxes
b1_x1, b1_y1, b1_x2, b1_y2 = box1[:, 0], box1[:, 1], box1[:, 2], box1[:, 3]
b2_x1, b2_y1, b2_x2, b2_y2 = box2[:, 0], box2[:, 1], box2[:, 2], box2[:, 3]
# get the coordinates of the intersection rectangle
inter_rect_x1 = torch.max(b1_x1, b2_x1)
inter_rect_y1 = torch.max(b1_y1, b2_y1)
inter_rect_x2 = torch.min(b1_x2, b2_x2)
inter_rect_y2 = torch.min(b1_y2, b2_y2)
# Intersection area
inter_area = torch.clamp(inter_rect_x2 - inter_rect_x1, 0) * torch.clamp(inter_rect_y2 - inter_rect_y1, 0)
# Union Area
b1_area = (b1_x2 - b1_x1) * (b1_y2 - b1_y1)
b2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1)
# print(box1, box1.shape)
# print(box2, box2.shape)
return inter_area / (b1_area + b2_area - inter_area + 1e-16)
numpy实现的方式
同样的,np.maximum()取对应位置上的大值,np.minimum 取对应位置上的较小值.
def bbox_iou_numpy(box1, box2):
"""
Computes IoU between bounding boxes.
Parameters
----------
x1y1x2y2格式
box1 : ndarray(N, 4) shaped array with bboxes
box2 : ndarray(M, 4) shaped array with bboxes
Returns
-------
: ndarray(N, M) shaped array with IoUs
"""
area = (box2[:, 2] - box2[:, 0]) * (box2[:, 3] - box2[:, 1])
iw = np.minimum(np.expand_dims(box1[:, 2], axis=1), box2[:, 2]) - np.maximum(
np.expand_dims(box1[:, 0], 1), box2[:, 0])
ih = np.minimum(np.expand_dims(box1[:, 3], axis=1), box2[:, 3]) - np.maximum(
np.expand_dims(box1[:, 1], 1), box2[:, 1])
iw = np.maximum(iw, 0)
ih = np.maximum(ih, 0)
ua = np.expand_dims((box1[:, 2] - box1[:, 0]) * (box1[:, 3] - box1[:, 1]), axis=1) + area - iw * ih
ua = np.maximum(ua, np.finfo(float).eps)
intersection = iw * ih
return intersection / ua