Beispiel #1
0
def compute_num_overlap(gts, img):
    if len(gts) > 1:
        for i in range(len(gts)):
            bboxA = list(map(float, gts[i][:4]))
            for j in range(i + 1, len(gts)):
                bboxB = list(map(float, gts[j][:4]))
                print(img, bbox_iou(bboxA, bboxB))
def get_correspondence_IoU(det_0, det_1, correspondences):
    closer_det = match_correspondence(det_0, correspondences)
    if closer_det:
        closer_det_1 = closer_det[1]
        IoU = bbox_iou(closer_det_1, det_1.bbox)
        return IoU
    return 0
def get_homography_IoU(det_0, det_1, homography1, homography2):

    predicted_correspondence = transform_detection(det_0, homography1,
                                                   homography2)
    predicted_bbox_1 = predicted_correspondence.bbox
    IoU = bbox_iou(det_1.bbox, predicted_bbox_1)

    return IoU
def get_IoU_relation(image, track, last_bbox, unused_detections, IoU_relation):
    for detection in unused_detections:
        IoU = bbox_iou(last_bbox, detection.bbox)
        #print("IoU: " + str(IoU))
        if IoU > 0.1 and color_check(image, last_bbox, detection.bbox):
            if IoU > 0.5 or bbox_touching_border(image, last_bbox) or bbox_touching_border(image, detection.bbox) or ratio_check(last_bbox, detection.bbox):
                IoU_relation.append((track, detection, IoU))
                #print("ID append: " + str(track.id))
    return IoU_relation
def compute_IoU(video_path, groundtruth_list, detections_list):

    capture = cv2.VideoCapture(video_path)
    n = 0
    TP = 0
    FN = 0
    FP = 0
    IoU = 0
    IoUFrames = []
    F1_frames = []
    while capture.isOpened():
        valid, image = capture.read()
        if not valid:
            break

        # Get grountruth and detections from frame n
        gt_on_frame = [x for x in groundtruth_list if x.frame == n]
        gt_bboxes = [o.bbox for o in gt_on_frame]
        #print("groundtruth: {}".format(gt_bboxes))

        detections_on_frame = [x for x in detections_list if x.frame == n]
        detections_bboxes = [o.bbox for o in detections_on_frame]
        #print("detections: {}".format(detections_bboxes))

        TP_temp, FN_temp, FP_temp = performance_accumulation_window(
            detections_bboxes, gt_bboxes)
        IoU_temp = 0
        precision = 0
        recall = 0
        F1_score = 0
        if TP_temp is not 0:
            IoU_temp_detections = []
            for det_bbox in detections_bboxes:
                IoU_temp_detections.append(
                    np.max([
                        bbox_iou(det_bbox, gt_bbox) for gt_bbox in gt_bboxes
                    ]))
            IoU_temp = np.mean(IoU_temp_detections)
            precision = float(TP_temp) / float(TP_temp + FP_temp)
            recall = float(TP_temp) / float(TP_temp + FN_temp)
            F1_score = 2 * recall * precision / (recall + precision)

        TP += TP_temp
        FN += FN_temp
        FP += FP_temp
        IoU += IoU_temp
        IoUFrames.append([TP_temp, FN_temp, FP_temp, IoU_temp])
        F1_frames.append([F1_score, precision, recall])
        n += 1
    IoU = IoU / n
    precision = float(TP) / float(TP + FP)
    recall = float(TP) / float(TP + FN)
    F1_score = 2 * recall * precision / (recall + precision)
    print("TP={} FN={} FP={}".format(TP, FN, FP))
    print("IoU={}".format(IoU))
    print("F1={}".format(F1_score))
    return IoUFrames, F1_frames
def match_next_bbox(image, last_bbox, unused_detections):
    highest_IoU = 0
    for detection in unused_detections:
        IoU = bbox_iou(last_bbox, detection.bbox)

        if IoU > highest_IoU and color_check(image, last_bbox, detection.bbox) and ratio_check(last_bbox, detection.bbox):
            highest_IoU = IoU
            best_match = detection

    if highest_IoU > 0:
        return best_match
    else:
        return None
def match_correspondence(detection, correspondences):
    highest_IoU = 0
    for correspondence in correspondences:
        IoU = bbox_iou(correspondence[0], detection.bbox)

        if IoU > highest_IoU:
            highest_IoU = IoU
            best_match = correspondence

    if highest_IoU > 0:
        return best_match
    else:
        return None
def performance_accumulation_window(detections_gt, annotations_gt):
    """
    performance_accumulation_window()

    Function to compute different performance indicators (True Positive,
    False Positive, False Negative) at the object level.

    Objects are defined by means of rectangular windows circumscribing them.
    Window format is [ struct(x,y,w,h)  struct(x,y,w,h)  ... ] in both
    detections and annotations.

    An object is considered to be detected correctly if detection and annotation
    windows overlap by more of 50%

       function [TP,FN,FP] = PerformanceAccumulationWindow(detections, annotations)

       Parameter name      Value
       --------------      -----
       'detections'        List of windows marking the candidate detections
       'annotations'       List of windows with the ground truth positions of the objects

    The function returns the number of True Positive (TP), False Positive (FP),
    False Negative (FN) objects
    """
    detections = []
    for element in detections_gt:
        detections.append([element.top_left[0], element.top_left[1], element.get_bottom_right()[0],
                           element.get_bottom_right()[1]])

    annotations = []
    for element in annotations_gt:
        annotations.append([element.top_left[0], element.top_left[1], element.get_bottom_right()[0],
                            element.get_bottom_right()[1]])

    detections_used = np.zeros(len(detections))
    annotations_used = np.zeros(len(annotations))
    TP = 0
    for ii in range(len(annotations)):
        for jj in range(len(detections)):
            if (detections_used[jj] == 0) & (bbox_iou(annotations[ii], detections[jj]) > 0.5):
                TP = TP + 1
                detections_used[jj] = 1
                annotations_used[ii] = 1

    FN = np.sum(annotations_used == 0)
    FP = np.sum(detections_used == 0)

    return [TP, FN, FP]
Beispiel #9
0
def nms(bboxes, threshold=.4):
    # based on https://github.com/opencv/opencv/blob/master/modules/dnn/src/nms.inl.hpp

    # sort bboxes by area descending
    bboxes.sort(key=lambda x: (x[2] - x[0]) * (x[3] - x[1]), reverse=True)

    indices = []
    for idx in range(len(bboxes)):
        keep = True
        for kept_idx in indices:
            overlap = bbox_iou(bboxes[idx], bboxes[kept_idx])
            contained = is_contained(bboxes[idx],
                                     bboxes[kept_idx]) or is_contained(
                                         bboxes[kept_idx], bboxes[idx])
            if contained or overlap > threshold:
                keep = False
                break
        if keep:
            indices.append(idx)
    return indices
def compute_mAP(groundtruth_list_original,
                detections_list,
                IoU_threshold=0.5,
                verbose=True):

    groundtruth_list = deepcopy(groundtruth_list_original)

    # Sort detections by confidence
    detections_list.sort(key=lambda x: x.confidence, reverse=True)
    # Save number of groundtruth labels
    groundtruth_size = len(groundtruth_list)

    TP = 0
    FP = 0
    FN = 0
    precision = list()
    recall = list()

    # to compute mAP
    max_precision_per_step = list()
    threshold = 1
    checkpoint = 0
    temp = 1000

    for n, detection in enumerate(detections_list):
        match_flag = False
        if threshold != temp:
            #print(threshold)
            temp = threshold

        # Get groundtruth of the target frame
        gt_on_frame = [
            x for x in groundtruth_list if x.frame == detection.frame
        ]
        gt_bboxes = [(o.bbox, o.confidence) for o in gt_on_frame]

        #print(gt_bboxes)
        for gt_bbox in gt_bboxes:
            #print(gt_bbox[0])
            #print(detection.bbox)
            iou = bbox_iou(gt_bbox[0], detection.bbox)
            if iou > IoU_threshold and gt_bbox[1] > 0.9:
                match_flag = True
                TP += 1
                gt_used = next(
                    (x for x in groundtruth_list
                     if x.frame == detection.frame and x.bbox == gt_bbox[0]),
                    None)
                gt_used.confidence = 0
                break

        if match_flag == False:
            FP += 1

        # Save metrics
        precision.append(TP / (TP + FP))
        if groundtruth_size:
            recall.append(TP / groundtruth_size)

    for n, r in enumerate(reversed(recall)):
        if r < threshold or n == len(precision) - 1:
            if r > threshold - 0.1:
                #print(n), print(r)
                if n > 0:
                    max_precision_per_step.append(max(precision[-n:]))
                else:
                    #max_precision_per_step.append(precision[len(precision)-1])
                    max_precision_per_step.append(0)
                threshold -= 0.1
            else:
                max_precision_per_step.append(0)
                threshold -= 0.1

    #plot_precision_recall_curve(precision, recall, max_precision_per_step)

    # Check false negatives
    groups = defaultdict(list)
    for obj in groundtruth_list:
        groups[obj.frame].append(obj)
    grouped_groundtruth_list = groups.values()

    for groundtruth in grouped_groundtruth_list:
        detection_on_frame = [
            x for x in detections_list if x.frame == groundtruth[0].frame
        ]
        detection_bboxes = [o.bbox for o in detection_on_frame]

        groundtruth_bboxes = [o.bbox for o in groundtruth]

        TP_temp, FN_temp, FP_temp = performance_accumulation_window(
            detection_bboxes, groundtruth_bboxes)
        FN += FN_temp

    if verbose:
        print("TP={} FN={} FP={}".format(TP, FN, FP))

    recall = 0
    precision = 0
    F1_score = 0
    if TP > 0:
        precision = float(TP) / float(TP + FP)
        recall = float(TP) / float(TP + FN)
        F1_score = 2 * recall * precision / (recall + precision)
    #print(TP+FP)
    #print("precision:{}".format(precision))
    #print("recall:{}".format(recall))
    #print(max_precision_per_step)
    mAP = sum(max_precision_per_step) / 11
    if verbose:
        print("mAP: {}".format(mAP))

    return precision, recall, max_precision_per_step, F1_score, mAP