mmrotate: Interpret the code for calculating TP and FP in eval_map.py in detail, and calculate the false alarm rate and missed alarm rate

        If you need to calculate the false alarm rate and missed alarm rate, you need to understand this function in detail: tpfp_default.

        I wrote a comment in the original code for everyone to read:

def tpfp_default(det_bboxes,
                 gt_bboxes,
                 gt_bboxes_ignore=None,
                 iou_thr=0.5,
                 area_ranges=None):
    """Check if detected bboxes are true positive or false positive.
	先明白,这里的det已经是检测框了!这里的框已经经过了nms,也就是已经被nms的阈值过了一遍了,已经是最终结果了!所以这里的框要不就是对的,要不就是错的,不存在没用的这个选项!
    Args:
        det_bboxes (ndarray): Detected bboxes of this image, of shape (m, 6).
        gt_bboxes (ndarray): GT bboxes of this image, of shape (n, 5).
        gt_bboxes_ignore (ndarray): Ignored gt bboxes of this image,
            of shape (k, 5). Default: None
        iou_thr (float): IoU threshold to be considered as matched.
            Default: 0.5.
        area_ranges (list[tuple] | None): Range of bbox areas to be evaluated,
            in the format [(min1, max1), (min2, max2), ...]. Default: None.

    Returns:
        tuple[np.ndarray]: (tp, fp) whose elements are 0 and 1. The shape of
            each array is (num_scales, m).
    """
    # an indicator of ignored gts
    det_bboxes = np.array(det_bboxes)
    gt_ignore_inds = np.concatenate(
        (np.zeros(gt_bboxes.shape[0], dtype=np.bool),
         np.ones(gt_bboxes_ignore.shape[0], dtype=np.bool)))
    # stack gt_bboxes and gt_bboxes_ignore for convenience
    gt_bboxes = np.vstack((gt_bboxes, gt_bboxes_ignore))

    num_dets = det_bboxes.shape[0]
    num_gts = gt_bboxes.shape[0]
    if area_ranges is None:
        area_ranges = [(None, None)]
    num_scales = len(area_ranges)
    # tp and fp are of shape (num_scales, num_gts), each row is tp or fp of
    # a certain scale
    tp = np.zeros((num_scales, num_dets), dtype=np.float32) #这个float类型!之后会变成0和1-----tp
    fp = np.zeros((num_scales, num_dets), dtype=np.float32) #这个float类型!之后会变成0和1-----fp

    # if there is no gt bboxes in this image, then all det bboxes
    # within area range are false positives
    if gt_bboxes.shape[0] == 0:
        if area_ranges == [(None, None)]:
            fp[...] = 1
        else:
            raise NotImplementedError
        return tp, fp

    ious = box_iou_rotated(
        torch.from_numpy(det_bboxes).float(),
        torch.from_numpy(gt_bboxes).float()).numpy() # 这个就是计算IOU,IOU是一个位于(0,1)之间的float类型的东西
    ious_max = ious.max(axis=1) # 每一个检测框与所有gt比较,得到的最大IOU,这个是一个位于(0,1)之间的float类型的东西,也就是说,对于第i个det的最大iou就是ious[i]
    ious_argmax = ious.argmax(axis=1) # 对于找到的那个最大的IOU,看看是哪个gt与之匹配,这应该是那个gt对应的id,反正就是一个指示是哪一个gt的identity,长度和gt一样
    sort_inds = np.argsort(-det_bboxes[:, -1]) # 对于所有的预测框,按照分数进行降序排序,先从分最高的开始
    for k, (min_area, max_area) in enumerate(area_ranges):
        gt_covered = np.zeros(num_gts, dtype=bool) # 这个是某一个gt是否为cover到,也就是是否被预测到了,是一个bool类型的,与之前的gt_bboxes一一对应
        # if no area range is specified, gt_area_ignore is all False
        if min_area is None:
            gt_area_ignore = np.zeros_like(gt_ignore_inds, dtype=bool) 
        else:
            raise NotImplementedError
        for i in sort_inds:
            if ious_max[i] >= iou_thr:  #就是,能进入这个if的,都已经是positive了,如果小于,那就认为是negetive(包括TN和PN)
			matched_gt = ious_argmax[i] # 这个是匹配的gt的identity,这里是det匹配上的那【一个】gt,一个det只能有一个gt匹配上,但是一个gt可能不止被一个det盯上
                if not (gt_ignore_inds[matched_gt]
                        or gt_area_ignore[matched_gt]):
							if not gt_covered[matched_gt]: # 把当前的gt的id(也就是matched_gt)所对应的gt找到,如果这个gt没被标注过
							gt_covered[matched_gt] = True # 那么这个gt就是和det匹配的,并记下这个gt是被匹配上了,后面的det如果也想找它匹配的话就都是FP!
                        tp[k, i] = 1 # 这个k是1,记录下当前这个det是TP
                    else: # 如果之前score更大的det已经找到了这个gt了(之前那个已经被标注成TP),那么这个就不对了,那就是FP!
                        fp[k, i] = 1 # 这个k是1,记录下当前这个det是FP
            elif min_area is None:
                fp[k, i] = 1
            else:
                bbox = det_bboxes[i, :5]
                area = bbox[2] * bbox[3]
                if area >= min_area and area < max_area:
                    fp[k, i] = 1
    return tp, fp

        To put it simply: if the IOU of a det is greater than the threshold, then it is considered True first, but it is possible that in the nms step, the score is not screened very well, so that several dets are framed on a gt at the same time. Therefore, those dets that are not well framed will be classified as fp even if they are greater than the iou threshold; in addition, for those dets that are less than the iou threshold, they will all be classified as fp. For those dets whose confidence is lower than the score, they are considered to be negative, that is, both fp and tp are assigned to 0. If you need to calculate fn, just subtract tp from the number of gt~

Guess you like

Origin blog.csdn.net/weixin_46812066/article/details/129868818