|
|
@@ -206,37 +206,36 @@ class ConfusionMatrix: |
|
|
|
print(' '.join(map(str, self.matrix[i]))) |
|
|
|
|
|
|
|
|
|
|
|
def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): |
|
|
|
# Returns the IoU of box1 to box2. box1 is 4, box2 is nx4 |
|
|
|
box2 = box2.T |
|
|
|
def bbox_iou(box1, box2, xywh=True, GIoU=False, DIoU=False, CIoU=False, eps=1e-7): |
|
|
|
# Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4) |
|
|
|
|
|
|
|
# Get the coordinates of bounding boxes |
|
|
|
if x1y1x2y2: # x1, y1, x2, y2 = box1 |
|
|
|
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] |
|
|
|
else: # transform from xywh to xyxy |
|
|
|
b1_x1, b1_x2 = box1[0] - box1[2] / 2, box1[0] + box1[2] / 2 |
|
|
|
b1_y1, b1_y2 = box1[1] - box1[3] / 2, box1[1] + box1[3] / 2 |
|
|
|
b2_x1, b2_x2 = box2[0] - box2[2] / 2, box2[0] + box2[2] / 2 |
|
|
|
b2_y1, b2_y2 = box2[1] - box2[3] / 2, box2[1] + box2[3] / 2 |
|
|
|
if xywh: # transform from xywh to xyxy |
|
|
|
(x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, 1), box2.chunk(4, 1) |
|
|
|
w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2 |
|
|
|
b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_ |
|
|
|
b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_ |
|
|
|
else: # x1, y1, x2, y2 = box1 |
|
|
|
b1_x1, b1_y1, b1_x2, b1_y2 = box1.chunk(4, 1) |
|
|
|
b2_x1, b2_y1, b2_x2, b2_y2 = box2.chunk(4, 1) |
|
|
|
w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps |
|
|
|
w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps |
|
|
|
|
|
|
|
# Intersection area |
|
|
|
inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \ |
|
|
|
(torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0) |
|
|
|
|
|
|
|
# Union Area |
|
|
|
w1, h1 = b1_x2 - b1_x1, b1_y2 - b1_y1 + eps |
|
|
|
w2, h2 = b2_x2 - b2_x1, b2_y2 - b2_y1 + eps |
|
|
|
union = w1 * h1 + w2 * h2 - inter + eps |
|
|
|
|
|
|
|
# IoU |
|
|
|
iou = inter / union |
|
|
|
if CIoU or DIoU or GIoU: |
|
|
|
cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1) # convex (smallest enclosing box) width |
|
|
|
ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1) # convex height |
|
|
|
if CIoU or DIoU: # Distance or Complete IoU https://arxiv.org/abs/1911.08287v1 |
|
|
|
c2 = cw ** 2 + ch ** 2 + eps # convex diagonal squared |
|
|
|
rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + |
|
|
|
(b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center distance squared |
|
|
|
rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4 # center dist ** 2 |
|
|
|
if CIoU: # https://github.com/Zzh-tju/DIoU-SSD-pytorch/blob/master/utils/box/box_utils.py#L47 |
|
|
|
v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2) |
|
|
|
with torch.no_grad(): |
|
|
@@ -248,6 +247,11 @@ def bbox_iou(box1, box2, x1y1x2y2=True, GIoU=False, DIoU=False, CIoU=False, eps= |
|
|
|
return iou # IoU |
|
|
|
|
|
|
|
|
|
|
|
def box_area(box): |
|
|
|
# box = xyxy(4,n) |
|
|
|
return (box[2] - box[0]) * (box[3] - box[1]) |
|
|
|
|
|
|
|
|
|
|
|
def box_iou(box1, box2): |
|
|
|
# https://github.com/pytorch/vision/blob/master/torchvision/ops/boxes.py |
|
|
|
""" |
|
|
@@ -261,16 +265,12 @@ def box_iou(box1, box2): |
|
|
|
IoU values for every element in boxes1 and boxes2 |
|
|
|
""" |
|
|
|
|
|
|
|
def box_area(box): |
|
|
|
# box = 4xn |
|
|
|
return (box[2] - box[0]) * (box[3] - box[1]) |
|
|
|
|
|
|
|
area1 = box_area(box1.T) |
|
|
|
area2 = box_area(box2.T) |
|
|
|
|
|
|
|
# inter(N,M) = (rb(N,M,2) - lt(N,M,2)).clamp(0).prod(2) |
|
|
|
inter = (torch.min(box1[:, None, 2:], box2[:, 2:]) - torch.max(box1[:, None, :2], box2[:, :2])).clamp(0).prod(2) |
|
|
|
return inter / (area1[:, None] + area2 - inter) # iou = inter / (area1 + area2 - inter) |
|
|
|
(a1, a2), (b1, b2) = box1[:, None].chunk(2, 2), box2.chunk(2, 1) |
|
|
|
inter = (torch.min(a2, b2) - torch.max(a1, b1)).clamp(0).prod(2) |
|
|
|
|
|
|
|
# IoU = inter / (area1 + area2 - inter) |
|
|
|
return inter / (box_area(box1.T)[:, None] + box_area(box2.T) - inter) |
|
|
|
|
|
|
|
|
|
|
|
def bbox_ioa(box1, box2, eps=1E-7): |
|
|
@@ -280,11 +280,9 @@ def bbox_ioa(box1, box2, eps=1E-7): |
|
|
|
returns: np.array of shape(n) |
|
|
|
""" |
|
|
|
|
|
|
|
box2 = box2.transpose() |
|
|
|
|
|
|
|
# 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] |
|
|
|
b1_x1, b1_y1, b1_x2, b1_y2 = box1 |
|
|
|
b2_x1, b2_y1, b2_x2, b2_y2 = box2.T |
|
|
|
|
|
|
|
# Intersection area |
|
|
|
inter_area = (np.minimum(b1_x2, b2_x2) - np.maximum(b1_x1, b2_x1)).clip(0) * \ |