计算两个列表的所有 IoU 的有效方法

Pik*_*ack 1 python numpy

我有一个函数来计算两个矩形/边界框的 IoU。

def intersection_over_union(boxA, boxB):
    # determine the (x, y)-coordinates of the intersection rectangle
    xA = max(boxA[0], boxB[0])
    yA = max(boxA[1], boxB[1])
    xB = min(boxA[2], boxB[2])
    yB = min(boxA[3], boxB[3])

    # compute the area of intersection rectangle
    interArea = max(0, xB - xA + 1) * max(0, yB - yA + 1)

    # compute the area of both the prediction and ground-truth
    # rectangles
    boxAArea = (boxA[2] - boxA[0] + 1) * (boxA[3] - boxA[1] + 1)
    boxBArea = (boxB[2] - boxB[0] + 1) * (boxB[3] - boxB[1] + 1)

    # compute the intersection over union by taking the intersection
    # area and dividing it by the sum of prediction + ground-truth
    # areas - the interesection area
    iou = interArea / float(boxAArea + boxBArea - interArea)

    # return the intersection over union value
    return iou
Run Code Online (Sandbox Code Playgroud)

现在我想用另一个列表的 bbox 计算一个列表的 bbox 的所有 IoU,即如果列表 A 包含 4 个 bbox,列表 B 包含 3 个 bbox,那么我想要一个 4x3 矩阵,结果是所有可能的 IoU。

当然我可以用两个这样的循环来做到这一点

import numpy as np

n_i = len(bboxes_a)
n_j = len(bboxes_b)
iou_mat = np.empty((n_i, n_j))
for i in range(n_i):
    for j in range(n_j):
        iou_mat[i, j] = intersection_over_union(bboxes_a[i], bboxes_b[j])
Run Code Online (Sandbox Code Playgroud)

但是这种方法很慢,尤其是当列表变得非常大时。

我正在努力寻找更有效的方法。必须有一种方法可以利用 numpy 来摆脱循环,但我不明白。现在的复杂度也是 O(m*n)。有没有可能降低复杂性?

Pau*_*zer 5

矢量化:

low = np.s_[...,:2]
high = np.s_[...,2:]

def iou(A,B):
    A,B = A.copy(),B.copy()
    A[high] += 1; B[high] += 1
    intrs = (np.maximum(0,np.minimum(A[high],B[high])
                        -np.maximum(A[low],B[low]))).prod(-1)
    return intrs / ((A[high]-A[low]).prod(-1)+(B[high]-B[low]).prod(-1)-intrs)

AB = iou(A[:,None],B[None])
Run Code Online (Sandbox Code Playgroud)

复杂:

由于您正在计算 M x N 值,除非大多数值为零并且矩阵的稀疏表示是可以接受的,否则不可能将复杂性降低到 M x N 以下。

这可以通过对 A 和 B 的所有末端进行 argsorting(分别用于 x 和 y)来完成。这是 O((M+N) log(M+N))编辑因为坐标是整数线性复杂度在这里可能是可能的。编辑结束然后这可以用于预过滤 A x B。过滤和计算非零值的复杂性将是 O(M + N + 非零值的数量)。