目标检测 计算召回率和准确率(recall and precision)

其中传入的pred_bboxes格式为3维的数组的list格式,也就是说每个list都是一个3维数组(有batch的考量),为一个样本的所有bbox。
其他的同理如pred_labels 同理。

list化可以参考下面代码

pred_bboxes, pred_labels, pred_scores = list(), list(), list()
gt_bboxes, gt_labels, gt_difficults = list(), list(), list()
bbox1=np.expand_dims(bbox, axis=0)
label1=np.expand_dims(label, axis=0)
labels1=np.expand_dims(labels, axis=0)
bounding1=np.expand_dims(bounding, axis=0)
confidence1=np.expand_dims(confidence, axis=0)

gt_bboxes += list(bbox1)
gt_labels += list(labels1)
# gt_difficults += list(gt_difficults_.numpy())
pred_bboxes += list(bounding1)
pred_labels += list(label1)
pred_scores += list(confidence1)

下面就是本文所要使用的,其中bbox_iou函数参考:https://blog.csdn.net/a362682954/article/details/82896242

#计算的召回率和准确率,每一种都包含类别个数大小的数组,每一个代表一个类别的召回率或者准确率
def calc_detection_voc_prec_rec(
        pred_bboxes, pred_labels, pred_scores, gt_bboxes, gt_labels,
        gt_difficults=None,
        iou_thresh=0.5):

    pred_bboxes = iter(pred_bboxes)
    pred_labels = iter(pred_labels)
    pred_scores = iter(pred_scores)
    gt_bboxes = iter(gt_bboxes)
    gt_labels = iter(gt_labels)
    if gt_difficults is None:
        gt_difficults = itertools.repeat(None)
    else:
        gt_difficults = iter(gt_difficults)

    n_pos = defaultdict(int)
    score = defaultdict(list)
    match = defaultdict(list)

    for pred_bbox, pred_label, pred_score, gt_bbox, gt_label, gt_difficult in \
            six.moves.zip(
                pred_bboxes, pred_labels, pred_scores,
                gt_bboxes, gt_labels, gt_difficults):
        
#         print pred_bbox
        if gt_difficult is None:
            gt_difficult = np.zeros(gt_bbox.shape[0], dtype=bool)

        for l in np.unique(np.concatenate((pred_label, gt_label)).astype(int)):
            # 在真实标签中选出标签为某值的boundingbox
            pred_mask_l = pred_label == l
            pred_bbox_l = pred_bbox[pred_mask_l]
            pred_score_l = pred_score[pred_mask_l]
            
            # sort by score 对分数排序
            order = pred_score_l.argsort()[::-1]
            pred_bbox_l = pred_bbox_l[order]
            pred_score_l = pred_score_l[order]
 
            # 在真实标签中选出标签为某值的boundingbox
            gt_mask_l = gt_label == l
            gt_bbox_l = gt_bbox[gt_mask_l]
            gt_difficult_l = gt_difficult[gt_mask_l]

            n_pos[l] += np.logical_not(gt_difficult_l).sum()
#             print n_pos[l]
            #list.extend 追加一行
            score[l].extend(pred_score_l)

            if len(pred_bbox_l) == 0:
                continue
            if len(gt_bbox_l) == 0:
                match[l].extend((0,) * pred_bbox_l.shape[0])
                continue

            # VOC evaluation follows integer typed bounding boxes.VOC评价遵循整数bounding boxes
            pred_bbox_l = pred_bbox_l.copy()
#             print pred_bbox_l
            pred_bbox_l[:, 2:] += 1
#             print pred_bbox_l
            gt_bbox_l = gt_bbox_l.copy()
            gt_bbox_l[:, 2:] += 1

        #找到所有gt和pred的重叠面积,总共gt.shape*pred.shape 个重叠面积
            iou = bbox_iou(pred_bbox_l, gt_bbox_l)
#找到最大的和真实样本bbox的重叠面积的索引
            gt_index = iou.argmax(axis=1)
            print gt_index
            # set -1 if there is no matching ground truth
            #小于阈值的就去除掉
            gt_index[iou.max(axis=1) < iou_thresh] = -1
            del iou

            #计算匹配的个数
            selec = np.zeros(gt_bbox_l.shape[0], dtype=bool)
            for gt_idx in gt_index:
                if gt_idx >= 0:
                    if gt_difficult_l[gt_idx]:
                        match[l].append(-1)
                    else:
                        if not selec[gt_idx]:
                            match[l].append(1)
                        else:
                            match[l].append(0)
                    selec[gt_idx] = True
                else:
                    match[l].append(0)

    for iter_ in (
            pred_bboxes, pred_labels, pred_scores,
            gt_bboxes, gt_labels, gt_difficults):
        if next(iter_, None) is not None:
            raise ValueError('Length of input iterables need to be same.')

    n_fg_class = max(n_pos.keys()) + 1
    prec = [None] * n_fg_class
    rec = [None] * n_fg_class

    for l in n_pos.keys():
        score_l = np.array(score[l])
        match_l = np.array(match[l], dtype=np.int8)

        order = score_l.argsort()[::-1]
        match_l = match_l[order]

        tp = np.cumsum(match_l == 1)
        fp = np.cumsum(match_l == 0)

        # If an element of fp + tp is 0,
        # the corresponding element of prec[l] is nan.
        prec[l] = tp / (fp + tp)
        # If n_pos[l] is 0, rec[l] is None.
        if n_pos[l] > 0:
            rec[l] = tp / n_pos[l]

#     print prec,rec
    return prec, rec

猜你喜欢

转载自blog.csdn.net/a362682954/article/details/82897739