Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/detection/utils.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ comments: true

:::supervision.detection.utils.mask_iou_batch

<div class="md-typeset">
<h2><a href="#supervision.detection.utils.oriented_box_iou_batch">oriented_box_iou_batch</a></h2>
</div>

:::supervision.detection.utils.oriented_box_iou_batch

<div class="md-typeset">
<h2><a href="#supervision.detection.utils.polygon_to_mask">polygon_to_mask</a></h2>
</div>
Expand Down
1 change: 1 addition & 0 deletions supervision/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
mask_to_xyxy,
move_boxes,
move_masks,
oriented_box_iou_batch,
pad_boxes,
polygon_to_mask,
polygon_to_xyxy,
Expand Down
39 changes: 39 additions & 0 deletions supervision/detection/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,45 @@ def mask_iou_batch(
return np.vstack(ious)


def oriented_box_iou_batch(
boxes_true: np.ndarray, boxes_detection: np.ndarray
) -> np.ndarray:
"""
Compute Intersection over Union (IoU) of two sets of oriented bounding boxes -
`boxes_true` and `boxes_detection`. Both sets
of boxes are expected to be in `(x1, y1, x2, y2, x3, y3, x4, y4)` format.
Comment thread
LinasKo marked this conversation as resolved.
Outdated

Args:
boxes_true (np.ndarray): 2D `np.ndarray` representing ground-truth boxes.
`shape = (N, 8)` where `N` is number of true objects.
boxes_detection (np.ndarray): 2D `np.ndarray` representing detection boxes.
`shape = (M, 8)` where `M` is number of detected objects.
Comment thread
LinasKo marked this conversation as resolved.
Outdated

Returns:
np.ndarray: Pairwise IoU of boxes from `boxes_true` and `boxes_detection`.
`shape = (N, M)` where `N` is number of true objects and
`M` is number of detected objects.
"""

boxes_true = boxes_true.reshape(-1, 4, 2)
boxes_detection = boxes_detection.reshape(-1, 4, 2)

max_height = max(boxes_true[:, :, 0].max(), boxes_detection[:, :, 0].max()) + 1
# adding 1 because we are 0-indexed
max_width = max(boxes_true[:, :, 1].max(), boxes_detection[:, :, 1].max()) + 1

mask_true = np.zeros((boxes_true.shape[0], max_height, max_width))
for i, box_true in enumerate(boxes_true):
mask_true[i] = polygon_to_mask(box_true, (max_width, max_height))

mask_detection = np.zeros((boxes_detection.shape[0], max_height, max_width))
for i, box_detection in enumerate(boxes_detection):
mask_detection[i] = polygon_to_mask(box_detection, (max_width, max_height))

ious = mask_iou_batch(mask_true, mask_detection)
return ious


def clip_boxes(xyxy: np.ndarray, resolution_wh: Tuple[int, int]) -> np.ndarray:
"""
Clips bounding boxes coordinates to fit within the frame resolution.
Expand Down