Merge pull request #2016 from roboflow/feature/make_box_aspect_ratio_part_of_detections_api
add `box_aspect_ratio` property to `sv.Detections`
This commit is contained in:
4 files changed
+38
-53
No files matched your search
@@ -52,7 +52,6 @@ from supervision.detection.tools.json_sink import JSONSink
|
||||
from supervision.detection.tools.polygon_zone import PolygonZone, PolygonZoneAnnotator
|
||||
from supervision.detection.tools.smoother import DetectionsSmoother
|
||||
from supervision.detection.utils.boxes import (
|
||||
box_aspect_ratio,
|
||||
clip_boxes,
|
||||
denormalize_boxes,
|
||||
move_boxes,
|
||||
@@ -200,7 +199,6 @@ __all__ = [
|
||||
"VideoInfo",
|
||||
"VideoSink",
|
||||
"approximate_polygon",
|
||||
"box_aspect_ratio",
|
||||
"box_iou",
|
||||
"box_iou_batch",
|
||||
"box_iou_batch_with_jaccard",
|
||||
|
||||
@@ -2088,6 +2088,43 @@ class Detections:
|
||||
"""
|
||||
return (self.xyxy[:, 3] - self.xyxy[:, 1]) * (self.xyxy[:, 2] - self.xyxy[:, 0])
|
||||
|
||||
@property
|
||||
def box_aspect_ratio(self) -> np.ndarray:
|
||||
"""
|
||||
Compute the aspect ratio (width divided by height) for each bounding box.
|
||||
|
||||
Returns:
|
||||
np.ndarray: Array of shape `(N,)` containing aspect ratios, where `N` is the
|
||||
number of boxes (width / height for each box).
|
||||
|
||||
Examples:
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
|
||||
xyxy = np.array([
|
||||
[10, 10, 50, 50],
|
||||
[60, 10, 180, 50],
|
||||
[10, 60, 50, 180],
|
||||
])
|
||||
|
||||
detections = sv.Detections(xyxy=xyxy)
|
||||
|
||||
detections.box_aspect_ratio
|
||||
# array([1.0, 3.0, 0.33333333])
|
||||
|
||||
ar = detections.box_aspect_ratio
|
||||
detections[(ar < 2.0) & (ar > 0.5)].xyxy
|
||||
# array([[10., 10., 50., 50.]])
|
||||
```
|
||||
"""
|
||||
widths = self.xyxy[:, 2] - self.xyxy[:, 0]
|
||||
heights = self.xyxy[:, 3] - self.xyxy[:, 1]
|
||||
|
||||
aspect_ratios = np.full_like(widths, np.nan, dtype=np.float64)
|
||||
np.divide(widths, heights, out=aspect_ratios, where=heights != 0)
|
||||
return aspect_ratios
|
||||
|
||||
def with_nms(
|
||||
self,
|
||||
threshold: float = 0.5,
|
||||
|
||||
@@ -6,57 +6,6 @@ import numpy.typing as npt
|
||||
from supervision.detection.utils.iou_and_nms import box_iou_batch
|
||||
|
||||
|
||||
def box_aspect_ratio(xyxy: np.ndarray) -> np.ndarray:
|
||||
"""
|
||||
Calculate aspect ratios of bounding boxes given in xyxy format.
|
||||
|
||||
Computes the width divided by height for each bounding box. Returns NaN
|
||||
for boxes with zero height to avoid division errors.
|
||||
|
||||
Args:
|
||||
xyxy (`numpy.ndarray`): Array of bounding boxes in
|
||||
`(x_min, y_min, x_max, y_max)` format with shape `(N, 4)`.
|
||||
|
||||
Returns:
|
||||
`numpy.ndarray`: Array of aspect ratios with shape `(N,)`, where each element is
|
||||
the width divided by height of a box. Elements are NaN if height is zero.
|
||||
|
||||
Examples:
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
|
||||
xyxy = np.array([
|
||||
[10, 20, 30, 50],
|
||||
[0, 0, 40, 10],
|
||||
])
|
||||
|
||||
sv.box_aspect_ratio(xyxy)
|
||||
# array([0.66666667, 4. ])
|
||||
|
||||
xyxy = np.array([
|
||||
[10, 10, 30, 10],
|
||||
[5, 5, 25, 25],
|
||||
])
|
||||
|
||||
sv.box_aspect_ratio(xyxy)
|
||||
# array([ nan, 1. ])
|
||||
```
|
||||
"""
|
||||
widths = xyxy[:, 2] - xyxy[:, 0]
|
||||
heights = xyxy[:, 3] - xyxy[:, 1]
|
||||
|
||||
aspect_ratios = np.full_like(widths, np.nan, dtype=np.float64)
|
||||
np.divide(
|
||||
widths,
|
||||
heights,
|
||||
out=aspect_ratios,
|
||||
where=heights != 0,
|
||||
)
|
||||
|
||||
return aspect_ratios
|
||||
|
||||
|
||||
def clip_boxes(xyxy: np.ndarray, resolution_wh: tuple[int, int]) -> np.ndarray:
|
||||
"""
|
||||
Clips bounding boxes coordinates to fit within the frame resolution.
|
||||
|
||||
@@ -145,6 +145,7 @@ class MockDataclass:
|
||||
"metadata",
|
||||
"area",
|
||||
"box_area",
|
||||
"box_aspect_ratio",
|
||||
},
|
||||
DoesNotRaise(),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user