Beispiel #1
0
def prep_metrics(ap_data, ids_p, classes_p, boxes_p, masks_p, gt, gt_masks,
                 height, width, iou_thres):
    gt_boxes = gt[:, :4]
    gt_boxes[:, [0, 2]] *= width
    gt_boxes[:, [1, 3]] *= height
    gt_classes = gt[:, 4].int().tolist()
    gt_masks = gt_masks.reshape(-1, height * width)
    masks_p = masks_p.reshape(-1, height * width)

    mask_iou_cache = mask_iou(masks_p, gt_masks)
    bbox_iou_cache = box_iou(boxes_p.float(), gt_boxes.float()).cpu()

    for _class in set(ids_p + gt_classes):
        num_gt_per_class = gt_classes.count(_class)

        for iouIdx in range(len(iou_thres)):
            iou_threshold = iou_thres[iouIdx]

            for iou_type, iou_func in zip(['box', 'mask'],
                                          [bbox_iou_cache, mask_iou_cache]):
                gt_used = [False] * len(gt_classes)
                ap_obj = ap_data[iou_type][iouIdx][_class]
                ap_obj.add_gt_positives(num_gt_per_class)

                for i, pred_class in enumerate(ids_p):
                    if pred_class != _class:
                        continue

                    max_iou_found = iou_threshold
                    max_match_idx = -1
                    for j, gt_class in enumerate(gt_classes):
                        if gt_used[j] or gt_class != _class:
                            continue

                        iou = iou_func[i, j].item()

                        if iou > max_iou_found:
                            max_iou_found = iou
                            max_match_idx = j

                    if max_match_idx >= 0:
                        gt_used[max_match_idx] = True
                        ap_obj.push(classes_p[i], True)
                    else:
                        ap_obj.push(classes_p[i], False)
Beispiel #2
0
def prep_metrics(ap_data, nms_outs, gt, gt_masks, h, w, num_crowd, image_id, make_json, cocoapi):
    """ Returns a list of APs for this image, with each element being for a class  """

    with timer.env('After NMS'):
        class_ids, classes, boxes, masks = after_nms(nms_outs, h, w)

        if class_ids.size(0) == 0:
            return

        class_ids = list(class_ids.cpu().numpy().astype(int))
        classes = list(classes.cpu().numpy().astype(float))
        masks = masks.view(-1, h * w).cuda() if cuda else masks.view(-1, h * w)
        boxes = boxes.cuda() if cuda else boxes

    if cocoapi:
        with timer.env('Output json'):
            boxes = boxes.cpu().numpy()
            masks = masks.view(-1, h, w).cpu().numpy()

            for i in range(masks.shape[0]):
                # Make sure that the bounding box actually makes sense and a mask was produced
                if (boxes[i, 3] - boxes[i, 1]) * (boxes[i, 2] - boxes[i, 0]) > 0:
                    make_json.add_bbox(image_id, class_ids[i], boxes[i, :], classes[i])
                    make_json.add_mask(image_id, class_ids[i], masks[i, :, :], classes[i])
        return

    with timer.env('Prepare gt'):
        gt_boxes = torch.Tensor(gt[:, :4])
        gt_boxes[:, [0, 2]] *= w
        gt_boxes[:, [1, 3]] *= h
        gt_classes = list(gt[:, 4].astype(int))
        gt_masks = torch.Tensor(gt_masks).view(-1, h * w)

        if num_crowd > 0:
            split = lambda x: (x[-num_crowd:], x[:-num_crowd])
            crowd_boxes, gt_boxes = split(gt_boxes)
            crowd_masks, gt_masks = split(gt_masks)
            crowd_classes, gt_classes = split(gt_classes)

    with timer.env('Eval Setup'):
        num_pred = len(class_ids)
        num_gt = len(gt_classes)

        mask_iou_cache = mask_iou(masks, gt_masks)
        bbox_iou_cache = bbox_iou(boxes.float(), gt_boxes.float())

        if num_crowd > 0:
            crowd_mask_iou_cache = mask_iou(masks, crowd_masks, iscrowd=True)
            crowd_bbox_iou_cache = bbox_iou(boxes.float(), crowd_boxes.float(), iscrowd=True)
        else:
            crowd_mask_iou_cache = None
            crowd_bbox_iou_cache = None

        iou_types = [('box', lambda i, j: bbox_iou_cache[i, j].item(), lambda i, j: crowd_bbox_iou_cache[i, j].item()),
                     ('mask', lambda i, j: mask_iou_cache[i, j].item(), lambda i, j: crowd_mask_iou_cache[i, j].item())]

    timer.start('Main loop')
    for _class in set(class_ids + gt_classes):
        num_gt_for_class = sum([1 for x in gt_classes if x == _class])

        for iouIdx in range(len(iou_thresholds)):
            iou_threshold = iou_thresholds[iouIdx]

            for iou_type, iou_func, crowd_func in iou_types:
                gt_used = [False] * len(gt_classes)
                ap_obj = ap_data[iou_type][iouIdx][_class]
                ap_obj.add_gt_positives(num_gt_for_class)

                for i in range(num_pred):
                    if class_ids[i] != _class:
                        continue

                    max_iou_found = iou_threshold
                    max_match_idx = -1
                    for j in range(num_gt):
                        if gt_used[j] or gt_classes[j] != _class:
                            continue

                        iou = iou_func(i, j)

                        if iou > max_iou_found:
                            max_iou_found = iou
                            max_match_idx = j

                    if max_match_idx >= 0:
                        gt_used[max_match_idx] = True
                        ap_obj.push(classes[i], True)
                    else:
                        # If the detection matches a crowd, we can just ignore it
                        matched_crowd = False

                        if num_crowd > 0:
                            for j in range(len(crowd_classes)):
                                if crowd_classes[j] != _class:
                                    continue

                                iou = crowd_func(i, j)

                                if iou > iou_threshold:
                                    matched_crowd = True
                                    break

                        # All this crowd code so that we can make sure that our eval code gives the
                        # same result as COCOEval. There aren't even that many crowd annotations to
                        # begin with, but accuracy is of the utmost importance.
                        if not matched_crowd:
                            ap_obj.push(classes[i], False)
    timer.stop('Main loop')
Beispiel #3
0
def _mask_iou(mask1, mask2, iscrowd=False):
    ret = mask_iou(mask1, mask2, iscrowd)
    return ret.cpu()
def prep_metrics(ap_data, classes_p, confs_p, boxes_p, masks_p, gt, gt_masks,
                 num_crowd, height, width):
    gt_boxes = gt[:, :4]
    gt_boxes[:, [0, 2]] *= width
    gt_boxes[:, [1, 3]] *= height
    gt_classes = gt[:, 4].int().tolist()
    gt_masks = gt_masks.reshape(-1, height * width)
    masks_p = masks_p.reshape(-1, height * width)

    if num_crowd > 0:
        split = lambda x: (x[-num_crowd:], x[:-num_crowd])
        crowd_boxes, gt_boxes = split(gt_boxes)
        crowd_masks, gt_masks = split(gt_masks)
        crowd_classes, gt_classes = split(gt_classes)

    mask_iou_cache = mask_iou(masks_p, gt_masks)
    bbox_iou_cache = bbox_iou(boxes_p.float(), gt_boxes.float())

    if num_crowd > 0:
        crowd_mask_iou_cache = mask_iou(masks_p, crowd_masks, iscrowd=True)
        crowd_bbox_iou_cache = bbox_iou(boxes_p.float(),
                                        crowd_boxes.float(),
                                        iscrowd=True)
    else:
        crowd_mask_iou_cache = None
        crowd_bbox_iou_cache = None

    iou_types = [('box', lambda i, j: bbox_iou_cache[i, j].item(),
                  lambda i, j: crowd_bbox_iou_cache[i, j].item()),
                 ('mask', lambda i, j: mask_iou_cache[i, j].item(),
                  lambda i, j: crowd_mask_iou_cache[i, j].item())]

    for _class in set(classes_p + gt_classes):
        num_gt_per_class = gt_classes.count(_class)

        for iouIdx in range(len(iou_thresholds)):
            iou_threshold = iou_thresholds[iouIdx]

            for iou_type, iou_func, crowd_func in iou_types:
                gt_used = [False] * len(gt_classes)
                ap_obj = ap_data[iou_type][iouIdx][_class]
                ap_obj.add_gt_positives(num_gt_per_class)

                for i, pred_class in enumerate(classes_p):
                    if pred_class != _class:
                        continue

                    max_iou_found = iou_threshold
                    max_match_idx = -1
                    for j, gt_class in enumerate(gt_classes):
                        if gt_used[j] or gt_class != _class:
                            continue

                        iou = iou_func(i, j)

                        if iou > max_iou_found:
                            max_iou_found = iou
                            max_match_idx = j

                    if max_match_idx >= 0:
                        gt_used[max_match_idx] = True
                        ap_obj.push(confs_p[i], True)
                    else:
                        # If the detection matches a crowd, we can just ignore it
                        matched_crowd = False

                        if num_crowd > 0:
                            for j in range(len(crowd_classes)):
                                if crowd_classes[j] != _class:
                                    continue

                                iou = crowd_func(i, j)

                                if iou > iou_threshold:
                                    matched_crowd = True
                                    break

                        # All this crowd code so that we can make sure that our eval code gives the
                        # same result as COCOEval. There aren't even that many crowd annotations to
                        # begin with, but accuracy is of the utmost importance.
                        if not matched_crowd:
                            ap_obj.push(confs_p[i], False)