示例#1
0
def combine_all_detections(detections, iou_threshold):
    """
    Input: m by n_i by 5, where m is the number of models and n_i is the number
    of detections from model i

    Output: n by 5
    """
    if len(detections) == 1:
        return detections[0]
    else:
        resulting_detections = []
        for reference_detection in detections[0]:
            if len(detections[1]) == 0:
                resulting_detections.append(reference_detection)
                continue
            overlaps = compute_overlap(
                np.expand_dims(reference_detection, axis=0), detections[1])
            if len(overlaps) == 0:
                resulting_detections.append(reference_detection)
                continue
            best_index = np.argmax(overlaps, axis=1)
            # print("Assigned annotation:")
            # print(assigned_annotation)
            max_overlap = overlaps[0, best_index][0]
            if max_overlap > 0 or max_overlap >= iou_threshold:
                combined_box = _combine_bounding_boxes(
                    reference_detection, detections[1][best_index][0])
                resulting_detections.append(combined_box)
        return resulting_detections
示例#2
0
def combine_detections(all_detections, image_number, label, iou_threshold):
    """
    all_detections = [
        detections_from_model
        for model in all_models
    ]
    :param all_detections:
    :param image_number:
    :param label:
    :return:
    """
    if len(all_detections) == 1:
        return all_detections[0][0]

    resulting_detections = []
    for detection in all_detections[0][image_number][label]:
        overlaps = compute_overlap(np.expand_dims(detection, axis=0),
                                   all_detections[1][image_number][label])
        assigned_annotation = np.argmax(overlaps, axis=1)
        # print("Assigned annotation:")
        # print(assigned_annotation)
        max_overlap = overlaps[0, assigned_annotation][0]
        # print("Max overlap:")
        # print(max_overlap)
        if max_overlap > 0 or max_overlap >= iou_threshold:
            combined_box = _combine_bounding_boxes(
                detection,
                all_detections[1][image_number][label][assigned_annotation[0]])
            resulting_detections.append(combined_box)

    return resulting_detections
示例#3
0
def compute_annotations(anchors,
                        annotations,
                        negative_overlap=0.2,
                        positive_overlap=0.5):
    """ Obtain indices of gt annotations with the greatest overlap.

    Args
        anchors: np.array of annotations of shape (N, 4) for (x1, y1, x2, y2).
        annotations: np.array of shape (N, 5) for (x1, y1, x2, y2, label).
        negative_overlap: IoU overlap for negative anchors (all anchors with overlap < negative_overlap are negative).
        positive_overlap: IoU overlap or positive anchors (all anchors with overlap > positive_overlap are positive).

    Returns
        positive_indices: indices of positive anchors
        ignore_indices: indices of ignored anchors
        argmax_overlaps_inds: ordered overlaps indices
    """

    overlaps = compute_overlap(anchors.astype(np.float64),
                               annotations.astype(np.float64))
    argmax_overlaps_inds = np.argmax(overlaps, axis=1)
    max_overlaps = overlaps[np.arange(overlaps.shape[0]), argmax_overlaps_inds]

    # assign "dont care" labels
    positive_indices = max_overlaps >= positive_overlap
    negative_indices = max_overlaps < negative_overlap

    return positive_indices, negative_indices
示例#4
0
def anchor_targets_bbox(anchors,
                        annotations,
                        num_classes,
                        mask_shape=None,
                        negative_overlap=0.4,
                        positive_overlap=0.5,
                        **kwargs):
    """ Generate anchor targets for bbox detection.

    Args
        anchors: np.array of annotations of shape (N, 4) for (x1, y1, x2, y2).
        annotations: np.array of shape (N, 5) for (x1, y1, x2, y2, label).
        num_classes: Number of classes to predict.
        mask_shape: If the image is padded with zeros, mask_shape can be used to mark the relevant part of the image.
        negative_overlap: IoU overlap for negative anchors (all anchors with overlap < negative_overlap are negative).
        positive_overlap: IoU overlap or positive anchors (all anchors with overlap > positive_overlap are positive).

    Returns
        labels: np.array of shape (A, num_classes) where a row consists of 0 for negative and 1 for positive for a certain class.
        annotations: np.array of shape (A, 5) for (x1, y1, x2, y2, label) containing the annotations corresponding to each anchor or 0 if there is no corresponding anchor.
        anchor_states: np.array of shape (N,) containing the state of an anchor (-1 for ignore, 0 for bg, 1 for fg).
    """
    # anchor states: 1 is positive, 0 is negative, -1 is dont care
    anchor_states = np.zeros((anchors.shape[0], ))
    labels = np.zeros((anchors.shape[0], num_classes))

    if annotations.shape[0]:
        # obtain indices of gt annotations with the greatest overlap
        overlaps = compute_overlap(anchors.astype(np.float64),
                                   annotations.astype(np.float64))
        argmax_overlaps_inds = np.argmax(overlaps, axis=1)
        max_overlaps = overlaps[np.arange(overlaps.shape[0]),
                                argmax_overlaps_inds]

        # assign "dont care" labels
        positive_indices = max_overlaps >= positive_overlap
        ignore_indices = (max_overlaps > negative_overlap) & ~positive_indices
        anchor_states[ignore_indices] = -1
        anchor_states[positive_indices] = 1

        # compute box regression targets
        annotations = annotations[argmax_overlaps_inds]

        # compute target class labels
        labels[positive_indices, annotations[positive_indices,
                                             4].astype(int)] = 1
    else:
        # no annotations? then everything is background
        annotations = np.zeros((anchors.shape[0], annotations.shape[1]))

    # ignore annotations outside of image
    if mask_shape:
        anchors_centers = np.vstack([(anchors[:, 0] + anchors[:, 2]) / 2,
                                     (anchors[:, 1] + anchors[:, 3]) / 2]).T
        indices = np.logical_or(anchors_centers[:, 0] >= mask_shape[1],
                                anchors_centers[:, 1] >= mask_shape[0])
        anchor_states[indices] = -1

    return labels, annotations, anchor_states
def average_overlap(values):
    global not_matched
    anchor_params = calculate_config(values, args.ratios)

    if args.include_stride:
        anchors = anchors_for_shape(image_shape, anchor_params=anchor_params)
    else:
        anchors = base_anchors_for_shape(anchor_params=anchor_params)

    overlap = compute_overlap(entries, anchors)
    max_overlap = np.amax(overlap, axis=1)
    not_matched = len(np.where(max_overlap < 0.5)[0])

    if args.objective == 'avg':
        result = 1 - np.average(max_overlap)
    elif args.objective == 'ce':
        result = np.average(-np.log(max_overlap))
    elif args.objective == 'focal':
        result = np.average(-(1 - max_overlap) ** 2 * np.log(max_overlap))
    else:
        raise Exception('Invalid mode.')

    if result < state['best_result']:
        state['best_result'] = result

        print('Current best anchor configuration')
        print(f'Ratios: {sorted(np.round(anchor_params.ratios, 3))}')
        print(f'Scales: {sorted(np.round(anchor_params.scales, 3))}')

        if args.include_stride:
            print(f'Average overlap: {np.round(np.average(max_overlap), 3)}')

        print(f'Number of labels that don\'t have any matching anchor: {not_matched}')
        print()

    return result
示例#6
0
def evaluate_dual_memory_model(generator,
                               models,
                               iou_threshold=0.5,
                               score_threshold=0.05,
                               max_detections=100,
                               save_path=None):
    detections_per_model = []
    all_inferences = []

    for model in models:
        current_detections, current_inferences = _get_detections(
            generator,
            model,
            score_threshold=score_threshold,
            max_detections=max_detections,
            save_path=save_path)
        detections_per_model.append(current_detections)
        all_inferences.append(current_inferences)
    average_precisions = {}
    all_annotations = _get_annotations(generator)

    # all_detections = detections_per_model[0]

    # process detections and annotations
    final_detections = {}
    for label in range(generator.num_classes()):
        if not generator.has_label(label):
            continue

        false_positives = np.zeros((0, ))
        true_positives = np.zeros((0, ))
        scores = np.zeros((0, ))
        num_annotations = 0.0

        for i in range(generator.size()):
            detections = [
                all_detections[i][label]
                for all_detections in detections_per_model
            ]
            detections = combine_all_detections(detections, iou_threshold)
            key = f"label={label}, instance_index={i}"
            final_detections[key] = [[d.tolist() for d in detection]
                                     for detection in detections]
            annotations = all_annotations[i][label]
            num_annotations += annotations.shape[0]
            detected_annotations = []

            for d in detections:
                scores = np.append(scores, d[4])

                if annotations.shape[0] == 0:
                    false_positives = np.append(false_positives, 1)
                    true_positives = np.append(true_positives, 0)
                    continue

                overlaps = compute_overlap(np.expand_dims(d, axis=0),
                                           annotations)
                assigned_annotation = np.argmax(overlaps, axis=1)
                max_overlap = overlaps[0, assigned_annotation]

                if max_overlap >= iou_threshold and assigned_annotation not in detected_annotations:
                    false_positives = np.append(false_positives, 0)
                    true_positives = np.append(true_positives, 1)
                    detected_annotations.append(assigned_annotation)
                else:
                    false_positives = np.append(false_positives, 1)
                    true_positives = np.append(true_positives, 0)

        if num_annotations == 0:
            average_precisions[label] = 0, 0
            continue

        # Sort by score:
        indices = np.argsort(-scores)
        false_positives = false_positives[indices]
        true_positives = true_positives[indices]

        # Compute false positives and true positives:
        false_positives = np.cumsum(false_positives)
        true_positives = np.cumsum(true_positives)

        # Compute recall and precision:
        recall = true_positives / num_annotations
        precision = true_positives / np.maximum(
            true_positives + false_positives,
            np.finfo(np.float64).eps)

        # Compute average precision:
        average_precision = _compute_ap(recall, precision)
        average_precisions[label] = average_precision, num_annotations

    # Inference time:
    inference_time = np.sum(all_inferences) / generator.size()

    return average_precisions, inference_time, detections_per_model, final_detections