Python 计算两个列表中所有IOU的有效方法
我有一个函数来计算两个矩形/边界框的IoUPython 计算两个列表中所有IOU的有效方法,python,numpy,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], box
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
现在,我想用另一个列表的BBox计算一个列表的所有BBox,也就是说,如果列表A包含4个BBox,列表B包含3个BBox,那么我想要一个包含所有可能IOU的4x3矩阵
当然,我可以用两个这样的循环来完成
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])
但这种方法非常缓慢,尤其是当列表变得非常大时
我正在努力寻找一种更有效的方法。必须有一种方法利用numpy来消除循环,但我不明白。现在的复杂性也是O(m*n)。是否有可能降低复杂性?您可以在python中使用product()
来替换嵌套的for循环。我认为使用内置函数总是更好。例如:
将numpy导入为np
l1=np.random.randint(0,10,(4,4))
l2=np.random.randint(0,10,(3,4))
打印(f'l1:\n{l1})
打印(f'l2:\n{l2}')
来自itertools进口产品
ious=np.数组(乘积(l1,l2)中box1,box2的[u与u并集(box1,box2)的交点])。重塑(len(l2),len(l1))
打印(文件:\n{ious})
此外,您应该将iou=interrea/float(boxarea+boxBArea-interrea)
更改为iou=interrea/float(boxarea+boxBArea-interrea+1e-16)
以避免除以零错误。
您可以使用产品()
在python中替换嵌套for循环。我认为使用内置函数总是更好。例如:
将numpy导入为np
l1=np.random.randint(0,10,(4,4))
l2=np.random.randint(0,10,(3,4))
打印(f'l1:\n{l1})
打印(f'l2:\n{l2}')
来自itertools进口产品
ious=np.数组(乘积(l1,l2)中box1,box2的[u与u并集(box1,box2)的交点])。重塑(len(l2),len(l1))
打印(文件:\n{ious})
此外,您应该将
iou=interrea/float(boxarea+boxBArea-interrea)
更改为iou=interrea/float(boxarea+boxBArea-interrea+1e-16)
以避免除以零错误。
矢量化:
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])
复杂性:
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])
由于您正在计算mxn值,因此不可能将复杂性降低到mxn以下,除非大多数值为零,并且可以接受矩阵的稀疏表示
这可以通过对A和B的所有端点进行argsorting(分别针对x和y)来完成。这就是O((M+N)log(M+N))编辑,因为坐标是整数,这里可能存在线性复杂度编辑结束然后可用于预过滤A x B。过滤和计算非零的复杂性为O(M+N+非零数量)。矢量化:
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])
复杂性:
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])
由于您正在计算mxn值,因此不可能将复杂性降低到mxn以下,除非大多数值为零,并且可以接受矩阵的稀疏表示
这可以通过对A和B的所有端点进行argsorting(分别针对x和y)来完成。这就是O((M+N)log(M+N))编辑,因为坐标是整数,这里可能存在线性复杂度编辑结束然后可用于预过滤A x B。过滤和计算非零的复杂性为O(M+N+非零数量)