web123456

【Technical Summary】Common indicators mAP, mIoU, mDice, mFscore, aAcc implementation

class BBox(object): def __init__(self, img_name, bbox, conf): self.name = img_name self.bbox = bbox self.conf = conf @staticmethod def IoU(bbox_a, bbox_b): bbox_a = bbox_a.bbox bbox_b = bbox_b.bbox area1 = (bbox_a[0] - bbox_a[2]) * (bbox_a[1] - bbox_b[3]) area2 = (bbox_b[0] - bbox_b[2]) * (bbox_b[1] - bbox_b[3]) tx = min(bbox_a[0], bbox_b[0]) ty = min(bbox_a[1], bbox_b[1]) bx = max(bbox_a[2], bbox_b[2]) by = max(bbox_a[3], bbox_b[3]) inter_area = (bx - tx) * (by - ty) return inter_area / (area1 + area2 - inter_area) def compute_AP(prds, gts, IoU_threshold=0.5): """Given the prediction and ground truth to calculate the AP value Args: prds (List[]): Model prediction results gts (_type_): True value IoU_threshold (float, optional): _description_. Defaults to 0.5. """ # sort the prds using conf prds = sorted(prds, key=lambda x: x.conf, reverse=True) # collect the gts name2gt_idx = dict() for i, gt in enumerate(gts): name2gt_idx[gt.name] = name2gt_idx.get(gt.name, []) + [i] # compute the TP and FP TP = np.zeros(len(prds)) FP = np.zeros(len(prds)) # initial used_gt used_gt = np.zeros(len(gts)) for pred_idx, prd in enumerate(prds): gt_idxs = name2gt_idx[prd.name] # find the gt with max iou max_iou_idx = -1 max_iou = 0 for gt_idx in gt_idxs: gt = gts[gt_idx] # If this GT bbox has been used, skip it if used_gt[gt_idx]: continue iou = BBox.IoU(gt, prd) if iou > IoU_threshold and iou > max_iou: max_iou = iou max_iou_idx = gt_idx if max_iou_idx != -1: TP[pred_idx] = 1 # Tag this GT bbox already in use, and it cannot match this GT bbox next time used_gt[max_iou_idx] = 1 else: FP[pred_idx] = 1 # compute the AP acc_TP = np.cumsum(TP) acc_FP = np.cumsum(FP) n_total = len(gts) Pr = acc_TP / (acc_TP + acc_FP) Rc = acc_TP / n_total return _compute_AP(Pr, Rc) def _compute_AP(Pr, Rc): Rc = np.concatenate(([0], Rc, [1])) Pr = np.concatenate(([0], Pr, [0])) # compute the real Pr # Pr curve is not strictly decreasing, so the actual calculation only takes the maximum value on the right for i in range(len(Pr) - 1, 0, -1): Pr[i-1] = max(Pr[i-1], Pr[i]) # compute the AP index = np.where(Rc[1:] != Rc[:-1])[0] AP = np.sum(Pr[index + 1] * (Rc[index+1] - Rc[index])) return AP