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)