| 2 | |
| 3 | |
| 4 | def ciou(bboxes1, bboxes2): |
| 5 | bboxes1 = torch.sigmoid(bboxes1) |
| 6 | bboxes2 = torch.sigmoid(bboxes2) |
| 7 | rows = bboxes1.shape[0] |
| 8 | cols = bboxes2.shape[0] |
| 9 | cious = torch.zeros((rows, cols)) |
| 10 | if rows * cols == 0: |
| 11 | return cious |
| 12 | exchange = False |
| 13 | if bboxes1.shape[0] > bboxes2.shape[0]: |
| 14 | bboxes1, bboxes2 = bboxes2, bboxes1 |
| 15 | cious = torch.zeros((cols, rows)) |
| 16 | exchange = True |
| 17 | w1 = torch.exp(bboxes1[:, 2]) |
| 18 | h1 = torch.exp(bboxes1[:, 3]) |
| 19 | w2 = torch.exp(bboxes2[:, 2]) |
| 20 | h2 = torch.exp(bboxes2[:, 3]) |
| 21 | area1 = w1 * h1 |
| 22 | area2 = w2 * h2 |
| 23 | center_x1 = bboxes1[:, 0] |
| 24 | center_y1 = bboxes1[:, 1] |
| 25 | center_x2 = bboxes2[:, 0] |
| 26 | center_y2 = bboxes2[:, 1] |
| 27 | |
| 28 | inter_l = torch.max(center_x1 - w1 / 2, center_x2 - w2 / 2) |
| 29 | inter_r = torch.min(center_x1 + w1 / 2, center_x2 + w2 / 2) |
| 30 | inter_t = torch.max(center_y1 - h1 / 2, center_y2 - h2 / 2) |
| 31 | inter_b = torch.min(center_y1 + h1 / 2, center_y2 + h2 / 2) |
| 32 | inter_area = torch.clamp((inter_r - inter_l), min=0) * torch.clamp( |
| 33 | (inter_b - inter_t), min=0) |
| 34 | |
| 35 | c_l = torch.min(center_x1 - w1 / 2, center_x2 - w2 / 2) |
| 36 | c_r = torch.max(center_x1 + w1 / 2, center_x2 + w2 / 2) |
| 37 | c_t = torch.min(center_y1 - h1 / 2, center_y2 - h2 / 2) |
| 38 | c_b = torch.max(center_y1 + h1 / 2, center_y2 + h2 / 2) |
| 39 | |
| 40 | inter_diag = (center_x2 - center_x1)**2 + (center_y2 - center_y1)**2 |
| 41 | c_diag = torch.clamp((c_r - c_l), min=0)**2 + torch.clamp( |
| 42 | (c_b - c_t), min=0)**2 |
| 43 | |
| 44 | union = area1 + area2 - inter_area |
| 45 | u = (inter_diag) / c_diag |
| 46 | iou = inter_area / union |
| 47 | v = (4 / (math.pi**2)) * torch.pow( |
| 48 | (torch.atan(w2 / h2) - torch.atan(w1 / h1)), 2) |
| 49 | with torch.no_grad(): |
| 50 | S = (iou > 0.5).float() |
| 51 | alpha = S * v / (1 - iou + v) |
| 52 | cious = iou - u - alpha * v |
| 53 | cious = torch.clamp(cious, min=-1.0, max=1.0) |
| 54 | if exchange: |
| 55 | cious = cious.T |
| 56 | return 1 - cious |
| 57 | |
| 58 | |
| 59 | def diou(bboxes1, bboxes2): |