Source code for draugr.opencv_utilities.bounding_boxes.evaluation

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

__author__ = "Christian Heider Nielsen"
__doc__ = r"""

           Created on 23/04/2020
           """

from typing import Sequence, Tuple

import numpy

__all__ = ["intersect_numpy", "jaccard_overlap_numpy", "remove_null_boxes"]


[docs]def intersect_numpy(box_a: Sequence, box_b: Sequence) -> numpy.ndarray: """ :param box_a: :type box_a: :param box_b: :type box_b: :return: :rtype:""" max_xy = numpy.minimum(box_a[:, 2:], box_b[2:]) min_xy = numpy.maximum(box_a[:, :2], box_b[:2]) inter = numpy.clip((max_xy - min_xy), a_min=0, a_max=numpy.inf) return inter[:, 0] * inter[:, 1]
[docs]def jaccard_overlap_numpy(box_a: numpy.ndarray, box_b: numpy.ndarray) -> numpy.ndarray: """Compute the jaccard overlap of two sets of boxes. The jaccard overlap is simply the intersection over union of two boxes. E.g.: A ∩ B / A ∪ B = A ∩ B / (area(A) + area(B) - A ∩ B) Args: box_a: Multiple bounding boxes, Shape: [num_boxes,4] box_b: Single bounding box, Shape: [4] Return: jaccard overlap: Shape: [box_a.shape[0], box_a.shape[1]]""" inter = intersect_numpy(box_a, box_b) area_a = (box_a[:, 2] - box_a[:, 0]) * (box_a[:, 3] - box_a[:, 1]) # [A,B] area_b = (box_b[2] - box_b[0]) * (box_b[3] - box_b[1]) # [A,B] union = area_a + area_b - inter return inter / union # [A,B]
[docs]def remove_null_boxes( boxes: numpy.ndarray, labels: numpy.ndarray ) -> Tuple[numpy.ndarray, numpy.ndarray]: """Removes bounding boxes of W or H equal to 0 and its labels Args: boxes (ndarray): NP Array with bounding boxes as lines * BBOX[x1, y1, x2, y2] labels (labels): Corresponding labels with boxes Returns: ndarray: Valid bounding boxes ndarray: Corresponding labels""" del_boxes = [] for idx, box in enumerate(boxes): if box[0] == box[2] or box[1] == box[3]: del_boxes.append(idx) return numpy.delete(boxes, del_boxes, 0), numpy.delete(labels, del_boxes)