Documentation for detection_utils.boxes

box_overlaps Return the overlap between two lists of boxes.
generate_targets(anchor_boxes, truth_boxes, …) Generate classification and regression targets from ground-truth boxes.
non_max_suppression(boxes, scores, …) Return the indices of non-suppressed detections after applying non-maximum suppression with the given threshold.
xywh_to_xyxy(boxes) Convert boxes from xywh to xyxy.
xyxy_to_xywh(boxes) Convert boxes from xyxy to xywh.
detection_utils.boxes.box_overlaps[source]

Return the overlap between two lists of boxes.

Calculates the intersection over union between a list of predicted boxes and a list of ground-truth boxes.

Parameters:

boxes : numpy.ndarray, shape=(N, 4)

The predicted boxes, in xyxy format.

truth : numpy.ndarray, shape=(K, 4)

The ground-truth boxes, in xyxy format.

eps : Real, optional (default=1e-12)

The epsilon value to apply to the intersection over union computation for stability.

Returns:

numpy.ndarray, shape=(N, K)

The overlap between the predicted and ground-truth boxes

Notes

The format referred to, xyxy format, indicates (left, top, right, bottom) in pixel space.

Examples

>>> from detection_utils.boxes import box_overlaps
>>> import numpy as np
>>> predicted_boxes = np.array([[0, 0, 10, 10], # left, top, right, bottom (xyxy) format
...                             [3, 3,  7,  7]])
>>> true_boxes = np.array([[2, 3, 6, 7]])
>>> box_overlaps(predicted_boxes, true_boxes)
array([[0.16], [0.6])
detection_utils.boxes.generate_targets(anchor_boxes: numpy.ndarray, truth_boxes: numpy.ndarray, labels: numpy.ndarray, pos_thresh: float = 0.3, neg_thresh: float = 0.2, eps: float = 1e-12) → Tuple[numpy.ndarray, numpy.ndarray][source]

Generate classification and regression targets from ground-truth boxes.

Each regression target is matched to its highest-overlapping ground-truth box. Those targets with less than a pos_thresh IoU are marked as background. Targets with neg_thresh <= IoU < pos_thresh are flagged as ignore boxes. Boxes are regressed based on their centers and widths/heights.

Parameters:

anchor_boxes : numpy.ndarray, shape=(N, 4)

Anchor boxes in xyxy format.

truth_boxes : numpy.ndarray, shape=(K, 4)

Ground-truth boxes in xyxy format.

labels : numpy.ndarray, shape=(K,)

The labels associated with each ground-truth box.

pos_thresh : Real, optional (default=0.3)

The minimum overlap threshold between a truth and anchor box for that truth box to be ‘responsible’ for detecting the anchor.

neg_thresh : Real, optional (default=0.2)

The maximum overlap threshold between a truth and anchor box for that anchor box to be called a negative. Those anchor boxes with overlap greater than this but less than pos_thresh will be marked as ignored.

eps : Real, optional (default=1e-12)

The epsilon to use for numerical stability.

Returns:

Tuple[numpy.ndarray shape=(N,), numpy.ndarray shape=(N, 4)]

The classification and bounding box regression targets for each anchor box. Regressions are of format (x-center, y-center, width, height). Classification targets of 0 indicate background, while targets of -1 indicate that this prediction should be ignored as a difficult case.

Examples

>>> from detection_utils.boxes import generate_targets
>>> import numpy as np
>>> anchors = np.array([[-0.5,   -0.5,   0.5,   0.5],
...                     [ 0.0,   -0.5,   1.0,   1.5],
...                     [ 0.5,    0.0,   1.5,   1.0]])
>>> targets = np.array([[0, 0, 1, 1]])
>>> labels = np.array([1])
>>> generate_targets(anchors, targets, labels)
(array([0, 1]),
 array([[ 5.000000e-01,  5.000000e-01, -1.110223e-16, -1.110223e-16],
    [ 0.000000e+00,  0.000000e+00, -1.110223e-16, -6.931472e-01],
    [-5.000000e-01,  0.000000e+00, -1.110223e-16, -1.110223e-16]]))
detection_utils.boxes.non_max_suppression(boxes: numpy.ndarray, scores: numpy.ndarray, threshold: float = 0.7, clip_value: float = 1000000.0, eps: float = 1e-12) → numpy.ndarray[source]

Return the indices of non-suppressed detections after applying non-maximum suppression with the given threshold.

Parameters:

boxes : np.ndarray[Real], shape=(N, 4)

The detection boxes to which to apply NMS, in (left, top, right, bottom) format.

scores : np.ndarray[Real], shape=(N,)

The detection score for each box.

threshold : float ∈ [0, 1], optional (default=0.7)

The IoU threshold to use for NMS, above which one of two box will be suppressed.

clip_value : Real, optional (default=1e6)

The maximum width or height overlap, for numerical stability.

eps : Real, optional (default=1e-12)

The epsilon value to use in IoU calculation, for numerical stability.

Returns:

np.ndarray[int], shape=(k,)

The (sorted) subset of detections to keep, where k is the number of non-suppressed inputs and k <= N.

Examples

>>> from detection_utils.boxes import non_max_suppression
>>> import numpy as np
>>> boxes = np.array([[  0,   0,   1,   1],
...                   [0.5, 0.5, 0.9, 0.9]])
>>> scores = np.array([0, 1])
>>> non_max_suppression(boxes, scores)
array([0, 1])

# our default threshold is 0.7 and our IoU between these is 0.16; let’s try a lower threshold >>> non_max_suppression(boxes, scores, threshold=0.15) array([1])

detection_utils.boxes.xywh_to_xyxy(boxes: numpy.ndarray) → numpy.ndarray[source]

Convert boxes from xywh to xyxy.

Parameters:

boxes : numpy.ndarray, shape=(N, 4)

Boxes, in xywh format.

Returns:

numpy.ndarray, shape=(N, 4)

Boxes in xyxy format

Examples

>>> from detection_utils.boxes import xywh_to_xyxy
>>> import numpy as np
>>> boxes = np.array([[0, 0, 2, 3],  # left, top, width, height
...                   [5, 6, 7, 8]])
>>> xywh_to_xyxy(boxes)
array([[0, 0,  2, 3],
       [5, 6, 12, 14]])
detection_utils.boxes.xyxy_to_xywh(boxes: numpy.ndarray) → numpy.ndarray[source]

Convert boxes from xyxy to xywh.

Parameters:

boxes : numpy.ndarray, shape=(N, 4)

Boxes, in xyxy format.

Returns:

numpy.ndarray, shape=(N, 4)

Boxes in xywh format

Examples

>>> from detection_utils.boxes import xyxy_to_xywh
>>> import numpy as np
>>> boxes = np.array([[0, 0,  2,  3],  # left, top, right, bottom
...                   [5, 6, 12, 14]])
>>> xyxy_to_xywh(boxes)
array([[0, 0,  2, 3],
       [5, 6, 7, 8]])