Skip to content

Commit 7ecfc9f

Browse files
authored
Merge pull request #1908 from roboflow/develop
`supervision-0.26.1` release
2 parents d8de58d + 317ac08 commit 7ecfc9f

File tree

10 files changed

+575
-45
lines changed

10 files changed

+575
-45
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
# These owners will be the default owners for everything in
22
# the repo. They will be requested for review when someone
33
# opens a pull request.
4-
* @SkalskiP @onuralpszr
4+
* @SkalskiP @soumik12345

docs/changelog.md

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
### 0.26.1 <small>Jul 22, 2025</small>
4+
5+
- Fixed [1894](https://github.com/roboflow/supervision/pull/1894): Error in [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) where the area used for size-specific evaluation (small / medium / large) was always zero unless explicitly provided in `sv.Detections.data`.
6+
7+
- Fixed [1895](https://github.com/roboflow/supervision/pull/1895): `ID=0` bug in [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) where objects were getting `0.0` mAP despite perfect IoU matches due to a bug in annotation ID assignment.
8+
9+
- Fixed [1898](https://github.com/roboflow/supervision/pull/1898): Issue where [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) could return negative values when certain object size categories have no data.
10+
11+
- Fixed [1901](https://github.com/roboflow/supervision/pull/1901): `match_metric` support for [`sv.Detections.with_nms`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.detection.core.Detections.with_nms).
12+
13+
- Fixed [1906](https://github.com/roboflow/supervision/pull/1906): `border_thickness` parameter usage for [`sv.PercentageBarAnnotator`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.annotators.core.PercentageBarAnnotator).
14+
315
### 0.26.0 <small>Jul 16, 2025</small>
416

517
!!! failure "Removed"
@@ -153,7 +165,7 @@
153165

154166
- Changed [#1786](https://github.com/roboflow/supervision/pull/1786): Significantly improved the speed of HSV color mapping in [`sv.HeatMapAnnotator`](https://supervision.roboflow.com/0.26.0/detection/annotators/#supervision.annotators.core.HeatMapAnnotator), achieving approximately 28x faster performance on 1920x1080 frames.
155167

156-
- Fix [#1834](https://github.com/roboflow/supervision/pull/1834): Supervision’s [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.0/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) is now fully aligned with [pycocotools](https://github.com/ppwwyyxx/cocoapi), the official COCO evaluation tool, ensuring accurate and standardized metrics. This update enabled us to launch a new version of the [Computer Vision Model Leaderboard](https://leaderboard.roboflow.com/).
168+
- Fixed [#1834](https://github.com/roboflow/supervision/pull/1834): Supervision’s [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.0/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) is now fully aligned with [pycocotools](https://github.com/ppwwyyxx/cocoapi), the official COCO evaluation tool, ensuring accurate and standardized metrics. This update enabled us to launch a new version of the [Computer Vision Model Leaderboard](https://leaderboard.roboflow.com/).
157169

158170
```python
159171
import supervision as sv
@@ -173,7 +185,7 @@
173185
# Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.629
174186
```
175187

176-
- Fix [#1767](https://github.com/roboflow/supervision/pull/1767): Fixed losing `sv.Detections.data` when detections filtering.
188+
- Fixed [#1767](https://github.com/roboflow/supervision/pull/1767): Fixed losing `sv.Detections.data` when detections filtering.
177189

178190
### 0.25.0 <small>Nov 12, 2024</small>
179191

@@ -557,9 +569,9 @@ detections = sv.Detections.from_sam(sam_result=sam_result)
557569

558570
- Changed [#1434](https://github.com/roboflow/supervision/pull/1434): [`InferenceSlicer`](https://supervision.roboflow.com/0.23.0/detection/tools/inference_slicer/) now features an `overlap_wh` parameter, making it easier to compute slice sizes when handling overlapping slices.
559571

560-
- Fix [#1448](https://github.com/roboflow/supervision/pull/1448): Various annotator type issues have been resolved, supporting expanded error handling.
572+
- Fixed [#1448](https://github.com/roboflow/supervision/pull/1448): Various annotator type issues have been resolved, supporting expanded error handling.
561573

562-
- Fix [#1348](https://github.com/roboflow/supervision/pull/1348): Introduced a new method for [seeking to a specific video frame](https://supervision.roboflow.com/0.23.0/utils/video/#supervision.utils.video.get_video_frames_generator), addressing cases where traditional seek methods were failing. It can be enabled with `iterative_seek=True`.
574+
- Fixed [#1348](https://github.com/roboflow/supervision/pull/1348): Introduced a new method for [seeking to a specific video frame](https://supervision.roboflow.com/0.23.0/utils/video/#supervision.utils.video.get_video_frames_generator), addressing cases where traditional seek methods were failing. It can be enabled with `iterative_seek=True`.
563575

564576
```python
565577
import supervision as sv
@@ -572,7 +584,7 @@ for frame in sv.get_video_frames_generator(
572584
...
573585
```
574586

575-
- Fix [#1424](https://github.com/roboflow/supervision/pull/1424): `plot_image` function now clearly indicates that the size is in inches.
587+
- Fixed [#1424](https://github.com/roboflow/supervision/pull/1424): `plot_image` function now clearly indicates that the size is in inches.
576588

577589
!!! failure "Removed"
578590

@@ -1285,7 +1297,7 @@ array([
12851297

12861298
### 0.11.1 <small>June 29, 2023</small>
12871299

1288-
- Fix [#165](https://github.com/roboflow/supervision/pull/165): [`as_folder_structure`](/0.11.1/dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure) fails to save [`sv.ClassificationDataset`](/0.11.1/dataset/core/#classificationdataset) when it is result of inference.
1300+
- Fixed [#165](https://github.com/roboflow/supervision/pull/165): [`as_folder_structure`](/0.11.1/dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure) fails to save [`sv.ClassificationDataset`](/0.11.1/dataset/core/#classificationdataset) when it is result of inference.
12891301

12901302
### 0.11.0 <small>June 28, 2023</small>
12911303

@@ -1331,7 +1343,7 @@ array([
13311343

13321344
- Added [#162](https://github.com/roboflow/supervision/pull/162): additional `start` and `end` arguments to [`sv.get_video_frames_generator`](/0.11.0/utils/video/#get_video_frames_generator) allowing to generate frames only for a selected part of the video.
13331345

1334-
- Fix [#157](https://github.com/roboflow/supervision/pull/157): incorrect loading of YOLO dataset class names from `data.yaml`.
1346+
- Fixed [#157](https://github.com/roboflow/supervision/pull/157): incorrect loading of YOLO dataset class names from `data.yaml`.
13351347

13361348
### 0.10.0 <small>June 14, 2023</small>
13371349

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
name = "supervision"
33
description = "A set of easy-to-use utils that will come in handy in any Computer Vision project"
44
license = { text = "MIT" }
5-
version = "0.26.0"
5+
version = "0.26.1"
66
readme = "README.md"
77
requires-python = ">=3.9"
88
authors = [

supervision/annotators/core.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2239,8 +2239,11 @@ def __init__(
22392239
self.position: Position = position
22402240
self.color_lookup: ColorLookup = color_lookup
22412241

2242-
if border_thickness is None:
2243-
self.border_thickness = int(0.15 * self.height)
2242+
self.border_thickness = (
2243+
border_thickness
2244+
if border_thickness is not None
2245+
else int(0.15 * self.height)
2246+
)
22442247

22452248
@ensure_cv2_image_for_annotation
22462249
def annotate(

supervision/detection/core.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1939,8 +1939,8 @@ def with_nms(
19391939
class_agnostic (bool): Whether to perform class-agnostic
19401940
non-maximum suppression. If True, the class_id of each detection
19411941
will be ignored. Defaults to False.
1942-
overlap_metric (OverlapMetric): Metric used for measuring overlap between
1943-
detections in slices.
1942+
overlap_metric (OverlapMetric): Metric used to compute the degree of
1943+
overlap between pairs of masks or boxes (e.g., IoU, IoS).
19441944
19451945
Returns:
19461946
Detections: A new Detections object containing the subset of detections
@@ -2003,8 +2003,8 @@ def with_nmm(
20032003
class_agnostic (bool): Whether to perform class-agnostic
20042004
non-maximum merging. If True, the class_id of each detection
20052005
will be ignored. Defaults to False.
2006-
overlap_metric (OverlapMetric): Metric used for measuring overlap between
2007-
detections in slices.
2006+
overlap_metric (OverlapMetric): Metric used to compute the degree of
2007+
overlap between pairs of masks or boxes (e.g., IoU, IoS).
20082008
20092009
Returns:
20102010
Detections: A new Detections object containing the subset of detections

supervision/detection/tools/inference_slicer.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from supervision.config import ORIENTED_BOX_COORDINATES
1010
from supervision.detection.core import Detections
1111
from supervision.detection.utils.boxes import move_boxes, move_oriented_boxes
12-
from supervision.detection.utils.iou_and_nms import OverlapFilter
12+
from supervision.detection.utils.iou_and_nms import OverlapFilter, OverlapMetric
1313
from supervision.detection.utils.masks import move_masks
1414
from supervision.utils.image import crop_image
1515
from supervision.utils.internal import (
@@ -75,8 +75,8 @@ class InferenceSlicer:
7575
filtering or merging overlapping detections in slices.
7676
iou_threshold (float): Intersection over Union (IoU) threshold
7777
used when filtering by overlap.
78-
match_metric (str): Metric used for matching detections in slices.
79-
"IOU" or "IOS". Defaults "IOU".
78+
overlap_metric (Union[OverlapMetric, str]): Metric used for matching detections
79+
in slices.
8080
callback (Callable): A function that performs inference on a given image
8181
slice and returns detections.
8282
thread_workers (int): Number of threads for parallel execution.
@@ -96,7 +96,7 @@ def __init__(
9696
overlap_wh: tuple[int, int] | None = None,
9797
overlap_filter: OverlapFilter | str = OverlapFilter.NON_MAX_SUPPRESSION,
9898
iou_threshold: float = 0.5,
99-
match_metric: str = "IOU",
99+
overlap_metric: OverlapMetric | str = OverlapMetric.IOU,
100100
thread_workers: int = 1,
101101
):
102102
if overlap_ratio_wh is not None:
@@ -112,7 +112,7 @@ def __init__(
112112

113113
self.slice_wh = slice_wh
114114
self.iou_threshold = iou_threshold
115-
self.match_metric = match_metric
115+
self.overlap_metric = OverlapMetric.from_value(overlap_metric)
116116
self.overlap_filter = OverlapFilter.from_value(overlap_filter)
117117
self.callback = callback
118118
self.thread_workers = thread_workers
@@ -173,11 +173,11 @@ def callback(image_slice: np.ndarray) -> sv.Detections:
173173
return merged
174174
elif self.overlap_filter == OverlapFilter.NON_MAX_SUPPRESSION:
175175
return merged.with_nms(
176-
threshold=self.iou_threshold, match_metric=self.match_metric
176+
threshold=self.iou_threshold, overlap_metric=self.overlap_metric
177177
)
178178
elif self.overlap_filter == OverlapFilter.NON_MAX_MERGE:
179179
return merged.with_nmm(
180-
threshold=self.iou_threshold, match_metric=self.match_metric
180+
threshold=self.iou_threshold, overlap_metric=self.overlap_metric
181181
)
182182
else:
183183
warnings.warn(

supervision/detection/utils/iou_and_nms.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,8 @@ def box_iou_batch(
164164
`shape = (N, 4)` where `N` is number of true objects.
165165
boxes_detection (np.ndarray): 2D `np.ndarray` representing detection boxes.
166166
`shape = (M, 4)` where `M` is number of detected objects.
167-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
167+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
168+
between pairs of boxes (e.g., IoU, IoS).
168169
169170
Returns:
170171
np.ndarray: Pairwise IoU of boxes from `boxes_true` and `boxes_detection`.
@@ -381,7 +382,8 @@ def _mask_iou_batch_split(
381382
Args:
382383
masks_true (np.ndarray): 3D `np.ndarray` representing ground-truth masks.
383384
masks_detection (np.ndarray): 3D `np.ndarray` representing detection masks.
384-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
385+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
386+
between pairs of masks (e.g., IoU, IoS).
385387
386388
Returns:
387389
np.ndarray: Pairwise IoU of masks from `masks_true` and `masks_detection`.
@@ -433,7 +435,8 @@ def mask_iou_batch(
433435
Args:
434436
masks_true (np.ndarray): 3D `np.ndarray` representing ground-truth masks.
435437
masks_detection (np.ndarray): 3D `np.ndarray` representing detection masks.
436-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
438+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
439+
between pairs of masks (e.g., IoU, IoS).
437440
memory_limit (int): memory limit in MB, default is 1024 * 5 MB (5GB).
438441
439442
Returns:
@@ -492,7 +495,8 @@ def mask_non_max_suppression(
492495
dimensions of each mask.
493496
iou_threshold (float): The intersection-over-union threshold
494497
to use for non-maximum suppression.
495-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
498+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
499+
between pairs of masks (e.g., IoU, IoS).
496500
mask_dimension (int): The dimension to which the masks should be
497501
resized before computing IOU values. Defaults to 640.
498502
@@ -543,7 +547,8 @@ def box_non_max_suppression(
543547
or `(x_min, y_min, x_max, y_max, score, class)`.
544548
iou_threshold (float): The intersection-over-union threshold
545549
to use for non-maximum suppression.
546-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
550+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
551+
between pairs of boxes (e.g., IoU, IoS).
547552
548553
Returns:
549554
np.ndarray: A boolean array indicating which predictions to keep after n
@@ -603,7 +608,8 @@ def _group_overlapping_masks(
603608
the predictions.
604609
iou_threshold (float): The intersection-over-union threshold
605610
to use for non-maximum suppression. Defaults to 0.5.
606-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
611+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
612+
between pairs of masks (e.g., IoU, IoS).
607613
608614
Returns:
609615
list[list[int]]: Groups of prediction indices be merged.
@@ -664,7 +670,8 @@ def mask_non_max_merge(
664670
to use for non-maximum suppression.
665671
mask_dimension (int): The dimension to which the masks should be
666672
resized before computing IOU values. Defaults to 640.
667-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
673+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
674+
between pairs of masks (e.g., IoU, IoS).
668675
669676
Returns:
670677
np.ndarray: A boolean array indicating which predictions to keep after
@@ -717,7 +724,8 @@ def _group_overlapping_boxes(
717724
and the confidence scores.
718725
iou_threshold (float): The intersection-over-union threshold
719726
to use for non-maximum suppression. Defaults to 0.5.
720-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
727+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
728+
between pairs of boxes (e.g., IoU, IoS).
721729
722730
Returns:
723731
list[list[int]]: Groups of prediction indices be merged.
@@ -765,7 +773,8 @@ def box_non_max_merge(
765773
detections of different classes to be merged.
766774
iou_threshold (float): The intersection-over-union threshold
767775
to use for non-maximum suppression. Defaults to 0.5.
768-
overlap_metric (OverlapMetric): Metric used for matching detections in slices.
776+
overlap_metric (OverlapMetric): Metric used to compute the degree of overlap
777+
between pairs of boxes (e.g., IoU, IoS).
769778
770779
Returns:
771780
list[list[int]]: Groups of prediction indices be merged.

0 commit comments

Comments
 (0)