Skip to content

Commit 6119f20

Browse files
authored
Merge pull request #2016 from roboflow/feature/make_box_aspect_ratio_part_of_detections_api
add `box_aspect_ratio` property to `sv.Detections`
2 parents 373fbae + bbc37b4 commit 6119f20

File tree

4 files changed

+38
-53
lines changed

4 files changed

+38
-53
lines changed

supervision/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
from supervision.detection.tools.polygon_zone import PolygonZone, PolygonZoneAnnotator
5353
from supervision.detection.tools.smoother import DetectionsSmoother
5454
from supervision.detection.utils.boxes import (
55-
box_aspect_ratio,
5655
clip_boxes,
5756
denormalize_boxes,
5857
move_boxes,
@@ -200,7 +199,6 @@
200199
"VideoInfo",
201200
"VideoSink",
202201
"approximate_polygon",
203-
"box_aspect_ratio",
204202
"box_iou",
205203
"box_iou_batch",
206204
"box_iou_batch_with_jaccard",

supervision/detection/core.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,43 @@ def box_area(self) -> np.ndarray:
20882088
"""
20892089
return (self.xyxy[:, 3] - self.xyxy[:, 1]) * (self.xyxy[:, 2] - self.xyxy[:, 0])
20902090

2091+
@property
2092+
def box_aspect_ratio(self) -> np.ndarray:
2093+
"""
2094+
Compute the aspect ratio (width divided by height) for each bounding box.
2095+
2096+
Returns:
2097+
np.ndarray: Array of shape `(N,)` containing aspect ratios, where `N` is the
2098+
number of boxes (width / height for each box).
2099+
2100+
Examples:
2101+
```python
2102+
import numpy as np
2103+
import supervision as sv
2104+
2105+
xyxy = np.array([
2106+
[10, 10, 50, 50],
2107+
[60, 10, 180, 50],
2108+
[10, 60, 50, 180],
2109+
])
2110+
2111+
detections = sv.Detections(xyxy=xyxy)
2112+
2113+
detections.box_aspect_ratio
2114+
# array([1.0, 3.0, 0.33333333])
2115+
2116+
ar = detections.box_aspect_ratio
2117+
detections[(ar < 2.0) & (ar > 0.5)].xyxy
2118+
# array([[10., 10., 50., 50.]])
2119+
```
2120+
"""
2121+
widths = self.xyxy[:, 2] - self.xyxy[:, 0]
2122+
heights = self.xyxy[:, 3] - self.xyxy[:, 1]
2123+
2124+
aspect_ratios = np.full_like(widths, np.nan, dtype=np.float64)
2125+
np.divide(widths, heights, out=aspect_ratios, where=heights != 0)
2126+
return aspect_ratios
2127+
20912128
def with_nms(
20922129
self,
20932130
threshold: float = 0.5,

supervision/detection/utils/boxes.py

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6,57 +6,6 @@
66
from supervision.detection.utils.iou_and_nms import box_iou_batch
77

88

9-
def box_aspect_ratio(xyxy: np.ndarray) -> np.ndarray:
10-
"""
11-
Calculate aspect ratios of bounding boxes given in xyxy format.
12-
13-
Computes the width divided by height for each bounding box. Returns NaN
14-
for boxes with zero height to avoid division errors.
15-
16-
Args:
17-
xyxy (`numpy.ndarray`): Array of bounding boxes in
18-
`(x_min, y_min, x_max, y_max)` format with shape `(N, 4)`.
19-
20-
Returns:
21-
`numpy.ndarray`: Array of aspect ratios with shape `(N,)`, where each element is
22-
the width divided by height of a box. Elements are NaN if height is zero.
23-
24-
Examples:
25-
```python
26-
import numpy as np
27-
import supervision as sv
28-
29-
xyxy = np.array([
30-
[10, 20, 30, 50],
31-
[0, 0, 40, 10],
32-
])
33-
34-
sv.box_aspect_ratio(xyxy)
35-
# array([0.66666667, 4. ])
36-
37-
xyxy = np.array([
38-
[10, 10, 30, 10],
39-
[5, 5, 25, 25],
40-
])
41-
42-
sv.box_aspect_ratio(xyxy)
43-
# array([ nan, 1. ])
44-
```
45-
"""
46-
widths = xyxy[:, 2] - xyxy[:, 0]
47-
heights = xyxy[:, 3] - xyxy[:, 1]
48-
49-
aspect_ratios = np.full_like(widths, np.nan, dtype=np.float64)
50-
np.divide(
51-
widths,
52-
heights,
53-
out=aspect_ratios,
54-
where=heights != 0,
55-
)
56-
57-
return aspect_ratios
58-
59-
609
def clip_boxes(xyxy: np.ndarray, resolution_wh: tuple[int, int]) -> np.ndarray:
6110
"""
6211
Clips bounding boxes coordinates to fit within the frame resolution.

test/utils/test_internal.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ def __private_property(self):
145145
"metadata",
146146
"area",
147147
"box_area",
148+
"box_aspect_ratio",
148149
},
149150
DoesNotRaise(),
150151
),

0 commit comments

Comments
 (0)