您现在的位置是:首页 >技术杂谈 >不同数量的预测框和Ground Truth框计算IoU网站首页技术杂谈

不同数量的预测框和Ground Truth框计算IoU

低吟浅笑 2023-06-05 12:00:02
简介不同数量的预测框和Ground Truth框计算IoU
import numpy as np

def calculate_iou(boxes1, boxes2):
    # 转换为 numpy 数组
    boxes1 = np.array(boxes1)
    boxes2 = np.array(boxes2)
    
    # 扩展维度,以便广播计算
    boxes1 = np.expand_dims(boxes1, axis=1)
    boxes2 = np.expand_dims(boxes2, axis=0)
    
    # 计算两组框的交集坐标范围
    x_min = np.maximum(boxes1[:, :, 0], boxes2[:, :, 0])
    y_min = np.maximum(boxes1[:, :, 1], boxes2[:, :, 1])
    x_max = np.minimum(boxes1[:, :, 2], boxes2[:, :, 2])
    y_max = np.minimum(boxes1[:, :, 3], boxes2[:, :, 3])
    
    # 计算交集和并集的面积
    intersection = np.maximum(x_max - x_min, 0) * np.maximum(y_max - y_min, 0)
    union = (boxes1[:, :, 2] - boxes1[:, :, 0]) * (boxes1[:, :, 3] - boxes1[:, :, 1]) + 
            (boxes2[:, :, 2] - boxes2[:, :, 0]) * (boxes2[:, :, 3] - boxes2[:, :, 1]) - 
            intersection
    
    # 计算 IoU
    iou = intersection / np.maximum(union, 1e-8)
    
    return iou

这个代码使用了 NumPy 的广播(broadcasting)机制,它可以使得不同形状的数组在某些维度上进行“自动”扩展,从而使它们可以参与到同样形状的计算中。这种机制可以避免我们手动对数组进行复制或循环操作,从而减少计算的时间和空间消耗。

具体来说,在这个代码中,我们首先将两个数组 boxes1boxes2 转换为 numpy 数组,并对它们的形状进行扩展,以便后续计算。这里使用了 np.expand_dims() 函数,将 boxes1 扩展为 N1 × 1 × 4 的三维数组,将 boxes2 扩展为 1 × N2 × 4 的三维数组。这样,当我们进行计算时,NumPy 就会自动将这两个数组沿着扩展的维度进行广播,从而得到一个 N1 × N2 × 4 的数组,它包含了所有可能的框对之间的坐标范围信息。

接下来,我们对这个三维数组进行切片操作,得到所有可能的框对之间的坐标范围信息。具体来说,我们使用切片 boxes1[:, :, 0] 获取所有预测框的左上角 x 坐标,使用切片 boxes2[:, :, 0] 获取所有 ground truth 框的左上角 x 坐标。然后,使用 NumPy 的 np.maximum() 函数对这两个切片进行按位取最大值,得到两组框的交集左上角 x 坐标。这个操作会得到一个 N1 × N2 的二维数组,它包含了所有可能的框对之间的交集左上角 x 坐标。

类似地,我们对所有可能的框对之间的坐标范围信息进行处理,得到交集和并集的宽度和高度,并使用它们计算交集和并集的面积。最后,我们使用 NumPy 的 np.maximum() 函数计算 IoU,并得到一个 N1 × N2 的二维数组,它包含了所有可能的框对之间的 IoU 值。

通过这种方式,我们可以高效地对不同数量的预测框和 ground truth 框进行 IoU 计算,而不需要手动对它们进行复制或循环操作。这可以大大提高计算的效率,尤其是当预测框和 ground truth 框的数量很大时。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。