# supervision changelog > supervision release notes. - Vendor: supervision - Category: AI - Official site: https://supervision.roboflow.com/ - Tracked by: What's New (https://whatsnew.fyi/product/supervision) - Harvested from: GitHub (roboflow/supervision) - Entries below: 10 (newest first) What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. ## Releases ### 0.29.1 — supervision-0.29.1 - Date: 2026-06-23 - Version: 0.29.1 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.29.1 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.29.1 - **added** — Add `KeyPoints.with_nms()` method to remove duplicate skeletons using non-maximum suppression on axis-aligned bounding boxes derived from keypoints, supporting `class_agnostic` mode and any `OverlapMetric` - **fixed** — Fix `sv.DetectionDataset.as_pascal_voc` mutating bounding boxes by shifting them +1 px in-place on each export - **fixed** — Fix `sv.Precision` and `sv.F1Score` to correctly count background false positives under `MICRO` and `MACRO` averaging modes - **fixed** — Fix `sv.DetectionsSmoother` raising when detections have no confidence scores - **fixed** — Fix `sv.Detections.from_vlm` to degrade gracefully on malformed Gemini and Qwen output instead of raising `TypeError` - **fixed** — Fix `sv.JSONSink` serializing NumPy scalars in `custom_data` by converting them to JSON-compatible types - **fixed** — Fix `sv.approximate_polygon` exceeding the point-count budget and validate `epsilon_step` to be positive - **fixed** — Fix COCO export to preserve all polygon segments for multi-part masks instead of writing only the first polygon - **changed** — Optimize `sv.HaloAnnotator` to use the same optimized CompactMask paint path as `MaskAnnotator`, reducing memory materialization - **changed** — Optimize mask IoU computation to use matrix multiplication on flattened masks instead of explicit tensor allocation - **changed** — Vectorize `sv.mask_to_xyxy` and `sv.KeyPoints.as_detections` to use batched NumPy operations instead of per-element loops ##### What's new ###### 🚀 `KeyPoints.with_nms()` — NMS for pose estimation ```python import supervision as sv key_points = model.predict(image) # sv.KeyPoints key_points = key_points.with_nms(threshold=0.5) # removes duplicate skeletons ``` Derives axis-aligned bounding boxes from each skeleton's valid (non-zero and visible) keypoints, then applies standard box NMS. Supports `class_agnostic` mode and any `OverlapMetric` (`IOU`, `IOS`). Raises `ValueError` if `detection_confidence` is not set. https://github.com/user-attachments/assets/ed7bd310-4868-4275-ae04-c88e7a0c2561 --- ##### Notable changes ###### Bug fixes - **`sv.DetectionDataset.as_pascal_voc` no longer mutates bounding boxes** (#2341) Previously, every export shifted every bounding box by +1 px in-place. A second call compounded the shift. Fixed by rebinding to a new array; on-disk XML output is unchanged. - **`sv.Precision` and `sv.F1Score` correctly count background false positives** (#2331) Predictions on images with no ground-truth objects, and predictions of classes absent from any annotation, were previously ignored. Under `MICRO` and `MACRO` averaging they are now counted as false positives. `WEIGHTED` averaging is unchanged. **Users should re-evaluate existing metric results after upgrading.** - **`sv.DetectionsSmoother` works with confidence-free detections** (#2333) The smoother no longer raises when detections have no confidence scores. Confidence is averaged over the frames that carry it; tracks without any confidence produce `None`. - **`sv.Detections.from_vlm` is robust to malformed Gemini/Qwen output** (#2342) Valid JSON that is not a list, or whose elements are not dicts, now degrades to empty `Detections` instead of raising `TypeError`. A malformed mask value in Gemini 2.5 responses no longer misaligns the `xyxy`/`confidence`/`masks` arrays. - **`sv.JSONSink` serializes NumPy scalars in `custom_data`** (#2334) `np.int64` frame indices and other NumPy scalars in `custom_data` no longer raise `TypeError` at flush time. NumPy arrays are serialized as lists. The file handle closes even when serialization fails. - **`sv.approximate_polygon` respects the point-count budget** (#2332) The function now returns at most `floor(N * (1 - percentage))` points (minimum 3). Previously it could return more points than requested. `epsilon_step` is now validated to be positive. - **COCO export preserves all segments for multi-part masks** (#2322) Previously, only the first polygon was written when a non-crowd detection had disjoint mask segments. All polygon parts are now written. ###### Performance - **`sv.HaloAnnotator` is ~4× faster with `CompactMask` detections** (#2339) `HaloAnnotator` now uses the same optimized CompactMask paint path as `MaskAnnotator`. Previously it materialized each mask full-frame; now it operates on the bounding-box crop. Annotated output is unchanged. - **Mask IoU uses less peak memory** (#2323) Mask IoU computation now uses matrix multiplication on flattened masks instead of an explicit `(N, M, H, W)` tensor. For masks larger than 4096×4096 px, computation promotes to float64 automatically. Results are numerically identical. - **`sv.mask_to_xyxy` and `sv.KeyPoints.as_detections` vectorized** (#2330) Both functions now use batched NumPy operations instead of per-element loops. Outputs are bit-identical. --- ##### Contributors - **Ruben Haisma** ([@RubenHaisma](https://github.com/RubenHaisma), [LinkedIn](https://www.linkedin.com/in/rubenhaisma/)) — VLM robustness, Pascal VOC export fix, DetectionsSmoother, JSONSink, metrics correctness, polygon budgeting, vectorization - **Agis Kounelis** ([@kounelisagis](https://github.com/kounelisagis), [LinkedIn](https://www.linkedin.com/in/kounelisagis/)) — HaloAnnotator perf, mask IoU matmul, mask_to_xyxy/KeyPoints.as_detections vectorization, OBB cookbook - **Piotr Skalski** ([@SkalskiP](https://github.com/SkalskiP), [LinkedIn] _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.29.1]_ ### 0.29.0.post0 — supervision-0.29.0.post - Date: 2026-06-17 - Version: 0.29.0.post0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.29.0.post0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.29.0.post0 **Full Changelog**: https://github.com/roboflow/supervision/compare/0.29.0...0.29.0.post0 ### 0.29.0 — supervision-0.29.0 - Date: 2026-06-15 - Version: 0.29.0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.29.0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.29.0 - **added** — Added sv.VertexEllipseAreaAnnotator, sv.VertexEllipseOutlineAnnotator, and sv.VertexEllipseHaloAnnotator for visualizing keypoint uncertainty as covariance ellipses - **added** — Added sv.oriented_box_non_max_suppression and sv.oriented_box_non_max_merge for performing NMS and NMM directly on oriented bounding boxes - **added** — Added OBB (Oriented Bounding Box) support to sv.ConfusionMatrix via MetricTarget.ORIENTED_BOUNDING_BOXES - **added** — Added preserve_audio parameter to sv.process_video to mux the audio stream from the source video into the output using ffmpeg - **added** — Added is_obb parameter to sv.DetectionDataset.as_yolo for exporting oriented bounding box annotations in the YOLO OBB format - **changed** — sv.EdgeAnnotator and sv.VertexAnnotator now respect the visible mask, skipping invisible keypoints and their edges during rendering - **changed** — sv.EdgeAnnotator and sv.VertexLabelAnnotator now support per-class skeleton definitions for correct rendering with multiple skeleton topologies - **changed** — sv.Detections.with_nms and sv.Detections.with_nmm are now OBB-aware, using oriented-box IoU automatically when oriented box coordinates are present ##### 🚀 Added - Added [`sv.VertexEllipseAreaAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.VertexEllipseAreaAnnotator), [`sv.VertexEllipseOutlineAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.VertexEllipseOutlineAnnotator), and [`sv.VertexEllipseHaloAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.VertexEllipseHaloAnnotator) for visualizing keypoint uncertainty as covariance ellipses. ([#2277](https://github.com/roboflow/supervision/pull/2277), [#2286](https://github.com/roboflow/supervision/pull/2286)) ```python import cv2 import supervision as sv from rfdetr import RFDETRKeypointPreview image = cv2.imread("") model = RFDETRKeypointPreview() key_points = model.predict(image) annotator = sv.VertexEllipseAreaAnnotator( sigma=[1.0, 2.0, 3.0], color=[sv.Color.GREEN, sv.Color.YELLOW, sv.Color.RED], opacity=0.4, ) annotated = annotator.annotate(image.copy(), key_points) ``` https://github.com/user-attachments/assets/e01322ff-f39c-420c-bf72-81efba8b0fd3 ```python import cv2 import supervision as sv from rfdetr import RFDETRKeypointPreview image = cv2.imread("") model = RFDETRKeypointPreview() key_points = model.predict(image) annotator = sv.VertexEllipseOutlineAnnotator( sigma=[1.0, 2.0, 3.0], color=[sv.Color.GREEN, sv.Color.YELLOW, sv.Color.RED], thickness=2, ) annotated = annotator.annotate(image.copy(), key_points) ``` https://github.com/user-attachments/assets/bce268c4-7e85-477b-b90c-9f12ef8500b2 ```python import cv2 import supervision as sv from rfdetr import RFDETRKeypointPreview image = cv2.imread("") model = RFDETRKeypointPreview() key_points = model.predict(image) annotator = sv.VertexEllipseHaloAnnotator( sigma=[1.0, 2.0, 3.0], color=[sv.Color.GREEN, sv.Color.YELLOW, sv.Color.RED], opacity=0.6, ) annotated = annotator.annotate(image.copy(), key_points) ``` https://github.com/user-attachments/assets/b8662ea4-666a-4ac7-a2fb-11d59c68fd74 - Added [`sv.oriented_box_non_max_suppression`](https://supervision.roboflow.com/0.29.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.oriented_box_non_max_suppression) and [`sv.oriented_box_non_max_merge`](https://supervision.roboflow.com/0.29.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.oriented_box_non_max_merge) for performing NMS and NMM directly on oriented bounding boxes. ([#2303](https://github.com/roboflow/supervision/pull/2303)) - Added OBB (Oriented Bounding Box) support to [`sv.ConfusionMatrix`](https://supervision.roboflow.com/0.29.0/metrics/detection/#supervision.metrics.detection.ConfusionMatrix) via `MetricTarget.ORIENTED_BOUNDING_BOXES`. ([#2247](https://github.com/roboflow/supervision/pull/2247)) - Added `preserve_audio` parameter to [`sv.process_video`](https://supervision.roboflow.com/0.29.0/utils/video/#supervision.utils.video.process_video). When enabled, the audio stream from the source video is muxed into the output using ffmpeg. ([#2252](https://github.com/roboflow/supervision/pull/2252)) - Added `is_obb` parameter to [`sv.DetectionDataset.as_yolo`](https://supervision.roboflow.com/0.29.0/datasets/#supervision.dataset.core.DetectionDataset.as_yolo) for exporting oriented bounding box annotations in the YOLO OBB format (9-token lines with 4 corner coordinates). ([#2302](https://github.com/roboflow/supervision/pull/2302), [#2289](https://github.com/roboflow/supervision/pull/2289)) ##### 🌱 Changed - [`sv.EdgeAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#super _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.29.0]_ ### 0.29.0rc0 — [RC] supervision - Date: 2026-06-11 - Version: 0.29.0rc0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.29.0rc0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.29.0rc0 - Labels: Pre-release **Full Changelog**: https://github.com/roboflow/supervision/compare/0.28.0...0.29.0rc0 ### 0.28.0 — supervision-0.28.0 - Date: 2026-04-30 - Version: 0.28.0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.28.0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.28.0 - **added** — Add sv.CompactMask for memory-efficient storage of segmentation masks using tight bounding-box crops and RLE encoding, reducing memory usage by 10–100× while maintaining API compatibility with existing mask operations - **added** — Add sv.Detections.from_sam3() to parse SAM3 text-prompted segmentation responses in both PCS (multi-prompt) and PVS (video) formats into standard Detections objects - **added** — Add SAM3 detection and point-video-segmentation output parsing to sv.Detections.from_inference() for both local inference package and Roboflow-hosted server responses - **added** — Add support for compressed COCO RLE masks in sv.Detections.from_inference() to decode RLE or rle_mask fields directly into binary masks - **added** — Replace print-based diagnostic output with standard logging module under the supervision logger - **added** — Add RGBA hex code support to sv.Color.from_hex() for 8-digit hex values and add sv.hex_to_rgba(), sv.rgba_to_hex(), and sv.is_valid_hex() helper functions - **added** — Add dynamic kernel sizing to BlurAnnotator and PixelateAnnotator that computes kernel size per detection as a fraction of the bounding-box side for consistent results across object scales - **changed** — Change sv.VideoInfo.fps from int to float to preserve true NTSC frame rates (23.976, 29.97, 59.94) instead of truncating them - **deprecated** — Deprecate sv.ByteTrack in favor of ByteTrackTracker from the dedicated trackers package, with removal planned for version 0.30.0 ##### 🔦 Spotlight ###### Memory-efficient masks with `sv.CompactMask` Segmentation models produce one full-resolution bitmap per instance. On a 1920×1080 image with 28 detections that is **~55 MB** of mask data. Most pixels are background. `sv.CompactMask` stores only the tight bounding-box crop, RLE-encoded — the same 28 masks drop to **~237 KB** of crops, a **240× reduction** before RLE kicks in. It's a drop-in replacement: annotators, filters, and `area` all work unchanged. supervision-sam3 ```python import supervision as sv #### any segmentation model — RF-DETR Seg, YOLO-Seg, SAM3 detections = model.predict(image) # sv.Detections with dense masks dense_mb = detections.mask.nbytes / 1024 / 1024 compact = sv.CompactMask.from_dense( masks=detections.mask, xyxy=detections.xyxy, image_shape=image.shape[:2], ) detections.mask = compact # swap in — API unchanged #### filter by pixel area without materialising dense masks large = detections[compact.area > 1000] #### annotators call .to_dense() internally annotated = sv.MaskAnnotator().annotate(image.copy(), detections) ``` --- ###### SAM3 text-prompted segmentation SAM3 segments objects by free-text prompt — no class list, no bounding boxes. `sv.Detections.from_sam3()` parses both PCS (multi-prompt) and PVS (video) response formats into a standard `sv.Detections`, with `class_id` set to the prompt index. ```python import requests, base64 import supervision as sv PROMPTS = ["person", "bag"] with open("image.jpg", "rb") as f: img_b64 = base64.b64encode(f.read()).decode() response = requests.post( f"https://api.roboflow.com/inferenceproxy/seg-preview?api_key={API_KEY}", json={ "image": {"type": "base64", "value": img_b64}, "prompts": [{"type": "text", "text": p} for p in PROMPTS], }, headers={"Content-Type": "application/json"}, ) sam3_result = response.json() h, w = cv2.imread("image.jpg").shape[:2] detections = sv.Detections.from_sam3(sam3_result=sam3_result, resolution_wh=(w, h)) #### class_id == 0 → "person", class_id == 1 → "bag" ``` --- ##### 🔄 Migration ###### `VideoInfo.fps` is now `float` NTSC frame rates (23.976, 29.97, 59.94) were silently truncated. `fps` is now the true float — cast at call sites that need an integer.
Before ```python info = sv.VideoInfo.from_video_path("clip.mp4") buf = collections.deque(maxlen=info.fps) trace = sv.TraceAnnotator(trace_length=info.fps) ```
After ```python info = sv.VideoInfo.from_video_path("clip.mp4") buf = collections.deque(maxlen=int(info.fps)) trace = sv.TraceAnnotator(trace_length=int(info.fps)) ```
###### `sv.ByteTrack` deprecated — use `ByteTrackTracker` Tracker implementations now live in the dedicated `trackers` package. `sv.ByteTrack` remains available in 0.28–0.29 with `DeprecationWarning`; removal in 0.30.0.
Before ```python tracker = sv.ByteTrack() detections = tracker.update_with_detections(detections) ```
After ```python #### pip install trackers from trackers import ByteTrackTracker tracker = ByteTrackTracker() detections = tracker.update(detections) ```
--- ##### 🚀 Added - **Memory-efficient masks with `sv.CompactMask`.** Sparse segmentation masks are now stored as a crop region plus RLE-encoded data instead of full-resolution bitmaps, cutting memory use by 10–100× for typical instance-segmentation outputs. It's a drop-in change — `sv.Detections.mask`, filtering, merging, and `area` all keep working without materialising the full array. ([#215 _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.28.0]_ ### 0.27.0.post2 — supervision-0.27.0.post - Date: 2026-03-14 - Version: 0.27.0.post2 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.27.0.post2 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.27.0.post2 **Full Changelog**: https://github.com/roboflow/supervision/compare/0.27.0...0.27.0.post2 ### 0.27.0 — supervision-0.27.0 - Date: 2025-11-16 - Version: 0.27.0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.27.0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.27.0 - **added** — Added sv.filter_segments_by_distance to keep the largest connected component and any nearby components within an absolute or relative distance threshold - **added** — Added sv.edit_distance for Levenshtein distance between two strings supporting insert, delete, and substitute operations - **added** — Added sv.fuzzy_match_index to find the first close match in a list using edit distance - **added** — Added sv.get_image_resolution_wh as a unified way to read image width and height from NumPy and PIL inputs - **added** — Added sv.tint_image to apply a solid color overlay to an image at a specified opacity, supporting both NumPy and PIL inputs - **added** — Added sv.grayscale_image to convert an image to 3-channel grayscale for compatibility with color-based drawing utilities - **added** — Added sv.xyxy_to_mask to convert bounding boxes into 2D boolean masks - **changed** — Added Qwen3-VL support in sv.Detections.from_vlm and legacy from_lmm mapping - **changed** — Added DeepSeek-VL2 support in sv.Detections.from_vlm and legacy from_lmm mapping - **changed** — Improved sv.Detections.from_vlm parsing for Qwen 2.5 VL outputs to handle incomplete or truncated JSON responses - **changed** — sv.InferenceSlicer now uses new offset generation logic that removes redundant tiles and ensures clean border aligned slicing, reducing the number of tiles processed and lowering inference time #### Description ##### 🚀 Added - Added [`sv.filter_segments_by_distance`](https://supervision.roboflow.com/0.27.0/detection/utils/masks/#supervision.detection.utils.masks.filter_segments_by_distance) to keep the largest connected component and any nearby components within an absolute or relative distance threshold. This helps you clean up predictions from segmentation models like SAM, SAM2, YOLO segmentation, and RF-DETR segmentation. ([#2008](https://github.com/roboflow/supervision/pull/2008)) https://github.com/user-attachments/assets/2bdfd45d-b235-414b-91a3-6544d7c2b4ec - Added [`sv.edit_distance`](https://supervision.roboflow.com/0.27.0/detection/utils/vlms/#supervision.detection.utils.vlms.edit_distance) for Levenshtein distance between two strings. Supports insert, delete, substitute. ([#1912](https://github.com/roboflow/supervision/pull/1912)) ```python import supervision as sv sv.edit_distance("hello", "hello") # 0 sv.edit_distance("hello world", "helloworld") # 1 sv.edit_distance("YOLO", "yolo", case_sensitive=True) # 4 ``` - Added [`sv.fuzzy_match_index`](https://supervision.roboflow.com/0.27.0/detection/utils/vlms/#supervision.detection.utils.vlms.fuzzy_match_index) to find the first close match in a list using edit distance. ([#1912](https://github.com/roboflow/supervision/pull/1912)) ```python import supervision as sv sv.fuzzy_match_index(["cat", "dog", "rat"], "dat", threshold=1) # 0 sv.fuzzy_match_index(["alpha", "beta", "gamma"], "bata", threshold=1) # 1 sv.fuzzy_match_index(["one", "two", "three"], "ten", threshold=2) # None ``` - Added [`sv.get_image_resolution_wh`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.get_image_resolution_wh) as a unified way to read image width and height from NumPy and PIL inputs. ([#2014](https://github.com/roboflow/supervision/pull/2014)) - Added [`sv.tint_image`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.tint_image) to apply a solid color overlay to an image at a specified opacity. Works with both NumPy and PIL inputs. ([#1943](https://github.com/roboflow/supervision/pull/1943)) - Added [`sv.grayscale_image`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.tint_image) to convert an image to 3-channel grayscale for compatibility with color-based drawing utilities. ([#1943](https://github.com/roboflow/supervision/pull/1943)) - Added [`sv.xyxy_to_mask`](https://supervision.roboflow.com/0.27.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_mask) to convert bounding boxes into 2D boolean masks. Each mask corresponds to one bounding box. ([#2006](https://github.com/roboflow/supervision/pull/2006)) ##### 🌱 Changed - Added Qwen3-VL support in [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.27.0/detection/core/#supervision.detection.core.Detections.from_vlm) and legacy `from_lmm` mapping. Use `vlm=sv.QWEN_3_VL`. ([#2015](https://github.com/roboflow/supervision/pull/2015)) ```python import supervision as sv response = """```json [ {"bbox_2d": [220, 102, 341, 206], "label": "taxi"}, {"bbox_2d": [30, 606, 171, 743], "label": "taxi"}, {"bbox_2d": [192, 451, 318, 581], "label": "taxi"}, {"bbox_2d": [358, 908, 506, 1000], "label": "taxi"}, {"bbox_2d": [735, 359, 873, 480], "label": "taxi"}, {"bbox_2d": [758, 508, 885, 617], "label": "taxi"}, {"bbox_2d": [857, 263, 988, 374], "label": "taxi"}, {"bbox_2d": [735, 243, 838, 351], "label": "taxi"}, {"bbox_2d": [303, 291, 434, 417], "label": "taxi"}, {"bbox_2d": [426, 273, 552, 382], "label": "taxi"} ] ```""" detections = sv.Detections.from_vlm( vlm=sv.VLM.QWEN_3_VL, result=response, resolution_wh=(1023, 682) ) d _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.27.0]_ ### 0.26.1 — supervision-0.26.1 - Date: 2025-07-23 - Version: 0.26.1 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.26.1 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.26.1 - **fixed** — Fixed error in sv.MeanAveragePrecision where the area used for size-specific evaluation (small / medium / large) was always zero unless explicitly provided in sv.Detections.data - **fixed** — Fixed ID=0 bug in sv.MeanAveragePrecision where objects were getting 0.0 mAP despite perfect IoU matches due to a bug in annotation ID assignment - **fixed** — Fixed issue where sv.MeanAveragePrecision could return negative values when certain object size categories have no data - **fixed** — Fixed match_metric support for sv.Detections.with_nms - **fixed** — Fixed border_thickness parameter usage for sv.PercentageBarAnnotator ##### 🔧 Fixed - Fixed 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`. (https://github.com/roboflow/supervision/pull/1894) - Fixed `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. (https://github.com/roboflow/supervision/pull/1895) - Fixed 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. (https://github.com/roboflow/supervision/pull/1898) - Fixed `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). (https://github.com/roboflow/supervision/pull/1901) - Fixed `border_thickness` parameter usage for [`sv.PercentageBarAnnotator`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.annotators.core.PercentageBarAnnotator). (https://github.com/roboflow/supervision/pull/1906) ##### 🏆 Contributors @balthazur ([Balthasar Huber](https://www.linkedin.com/in/balthasar-huber/)), @onuralpszr ([Onuralp SEZER](https://www.linkedin.com/in/osezer/)), @rafaelpadilla ([Rafael Padilla](https://www.linkedin.com/in/rafael-padilla/)), @soumik12345 ([Soumik Rakshit](https://www.linkedin.com/in/soumikrakshit/)), @SkalskiP ([Piotr Skalski](https://www.linkedin.com/in/skalskip92/)) ### 0.26.0 — supervision-0.26.0 - Date: 2025-07-16 - Version: 0.26.0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.26.0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.26.0 - **removed** — Drop Python 3.8 support - **changed** — Upgrade all code to Python 3.9 syntax style - **added** — Add support for creating sv.KeyPoints objects from ViTPose and ViTPose++ inference results via sv.KeyPoints.from_transformers - **added** — Add support for the IOS (Intersection over Smallest) overlap metric in sv.Detections.with_nms, sv.Detections.with_nmm, sv.box_iou_batch, and sv.mask_iou_batch - **added** — Add sv.box_iou function to efficiently compute the Intersection over Union between two individual bounding boxes - **added** — Add support for frame limitations and progress bar in sv.process_video - **added** — Add sv.xyxy_to_xcycarh function to convert bounding box coordinates from (x_min, y_min, x_max, y_max) to (center x, center y, aspect ratio, height) format - **added** — Add sv.xyxy_to_xywh function to convert bounding box coordinates from (x_min, y_min, x_max, y_max) format to (x, y, width, height) format - **changed** — sv.LabelAnnotator now supports the smart_position parameter to automatically keep labels within frame boundaries and the max_line_length parameter to control text wrapping - **changed** — sv.LabelAnnotator now supports non-string labels - **changed** — sv.Detections.from_vlm now supports parsing bounding boxes and segmentation masks from responses generated by Google Gemini models > [!WARNING] > `supervision-0.26.0` drops `python3.8` support and upgrade all codes to `python3.9` syntax style. > [!TIP] > Our [docs page](https://supervision.roboflow.com/) now has a fresh look that is consistent with the documentations of all Roboflow open-source projects. ([#1858](https://github.com/roboflow/supervision/pull/1858)) ##### 🚀 Added - Added support for creating [`sv.KeyPoints`](https://supervision.roboflow.com/0.26.0/keypoint/core/#supervision.keypoint.core.KeyPoints) objects from [ViTPose](https://huggingface.co/docs/transformers/en/model_doc/vitpose) and [ViTPose++](https://huggingface.co/docs/transformers/en/model_doc/vitpose#vitpose-models) inference results via [`sv.KeyPoints.from_transformers`](https://supervision.roboflow.com/0.26.0/keypoint/core/#supervision.keypoint.core.KeyPoints.from_transformers). ([#1788](https://github.com/roboflow/supervision/pull/1788)) https://github.com/user-attachments/assets/f1917032-29d8-4b88-b871-65c2e28a756e - Added support for the IOS (Intersection over Smallest) overlap metric that measures how much of the smaller object is covered by the larger one in [`sv.Detections.with_nms`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.with_nms), [`sv.Detections.with_nmm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.with_nmm), [`sv.box_iou_batch`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.box_iou_batch), and [`sv.mask_iou_batch`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.mask_iou_batch). ([#1774](https://github.com/roboflow/supervision/pull/1774)) ```python import numpy as np import supervision as sv boxes_true = np.array([ [100, 100, 200, 200], [300, 300, 400, 400] ]) boxes_detection = np.array([ [150, 150, 250, 250], [320, 320, 420, 420] ]) sv.box_iou_batch( boxes_true=boxes_true, boxes_detection=boxes_detection, overlap_metric=sv.OverlapMetric.IOU ) # array([[0.14285714, 0. ], # [0. , 0.47058824]]) sv.box_iou_batch( boxes_true=boxes_true, boxes_detection=boxes_detection, overlap_metric=sv.OverlapMetric.IOS ) # array([[0.25, 0. ], # [0. , 0.64]]) ``` - Added [`sv.box_iou`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.box_iou) that efficiently computes the Intersection over Union (IoU) between two individual bounding boxes. ([#1874](https://github.com/roboflow/supervision/pull/1874)) - Added support for frame limitations and progress bar in [`sv.process_video`](https://supervision.roboflow.com/0.26.0/utils/video/#supervision.utils.video.process_video). ([#1816](https://github.com/roboflow/supervision/pull/1816)) - Added [`sv.xyxy_to_xcycarh`](https://supervision.roboflow.com/0.26.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_xcycarh) function to convert bounding box coordinates from `(x_min, y_min, x_max, y_max)` into measurement space to format `(center x, center y, aspect ratio, height)`, where the aspect ratio is `width / height`. ([#1823](https://github.com/roboflow/supervision/pull/1823)) - Added [`sv.xyxy_to_xywh`](https://supervision.roboflow.com/0.26.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_xywh) function to convert bounding box coordinates from `(x_min, y_min, x_max, y_max)` format to `(x, y, width, height)` format. ([#1788](https://github.com/roboflow/supervision/pull/1788)) ##### 🌱 Changed - [`sv.LabelAnnotator`](https://supervision.roboflow.com/0.26.0/detection/annotators/#supervision.annotators.core.LabelAnnotator) now supports the `smart_positi _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.26.0]_ ### 0.25.0 — supervision-0.25.0 - Date: 2024-11-12 - Version: 0.25.0 - Original notes: https://github.com/roboflow/supervision/releases/tag/0.25.0 - Permalink: https://whatsnew.fyi/product/supervision/releases/0.25.0 - **added** — Add `minimum_crossing_threshold` argument to `LineZone` to confirm crossings over multiple frames and reduce false positives from jittering detections - **added** — Enable tracking of objects detected as `KeyPoints` by converting them to `Detections` - **added** — Add `is_empty` method to `KeyPoints` to check if there are any keypoints in the object - **added** — Add `as_detections` method to `KeyPoints` to convert `KeyPoints` to `Detections` - **added** — Add new skiing video asset to supervision[assets] - **added** — Support Python 3.13 compatibility including execution without Global Interpreter Lock (GIL) - **added** — Add `Mean Average Recall` (mAR) metric that returns a recall score averaged over IoU thresholds, detected object classes, and limits on maximum considered detections - **added** — Add `Precision` metric for comparing model outputs to ground truth or another model - **added** — Add `Recall` metric for comparing model outputs to ground truth or another model - **changed** — All Metrics now support Oriented Bounding Boxes (OBB) **Supervision 0.25.0 is here! Featuring a more robust `LineZone` crossing counter, support for tracking KeyPoints, Python 3.13 compatibility, and 3 new metrics: Precision, Recall and Mean Average Recall. The update also includes smart label positioning, improved Oriented Bounding Box support, and refined error handling. Thank you to all contributors - especially those who answered the call of Hacktoberfest!** #### Changelog ##### 🚀 Added - Essential update to the [`LineZone`](https://supervision.roboflow.com/0.25.0/detection/tools/line_zone/): when computing line crossings, detections that jitter might be counted twice (or more!). This can now be solved with the `minimum_crossing_threshold` argument. If you set it to `2` or more, extra frames will be used to confirm the crossing, improving the accuracy significantly. ([#1540](https://github.com/roboflow/supervision/pull/1540)) https://github.com/user-attachments/assets/89ca2ee6-93c9-41e6-a432-e16c4c69c695 - It is now possible to track objects detected as [`KeyPoints`](https://supervision.roboflow.com/0.25.0/keypoint/core/#supervision.keypoint.core.KeyPoints). See the complete step-by-step guide in the [Object Tracking Guide](https://supervision.roboflow.com/latest/how_to/track_objects/#keypoints). ([#1658](https://github.com/roboflow/supervision/pull/1658)) ```python import numpy as np import supervision as sv from ultralytics import YOLO model = YOLO("yolov8m-pose.pt") tracker = sv.ByteTrack() trace_annotator = sv.TraceAnnotator() def callback(frame: np.ndarray, _: int) -> np.ndarray: results = model(frame)[0] key_points = sv.KeyPoints.from_ultralytics(results) detections = key_points.as_detections() detections = tracker.update_with_detections(detections) annotated_image = trace_annotator.annotate(frame.copy(), detections) return annotated_image sv.process_video( source_path="input_video.mp4", target_path="output_video.mp4", callback=callback ) ``` https://github.com/user-attachments/assets/4c3bdf54-391e-4633-9164-f15878ddfb33 _See [the guide](https://supervision.roboflow.com/0.25.0/how_to/track_objects/#bonus-smoothing) for the full code used to make the video_ - Added `is_empty` method to [`KeyPoints`](https://supervision.roboflow.com/0.25.0/keypoint/core/#supervision.keypoint.core.KeyPoints) to check if there are any keypoints in the object. ([#1658](https://github.com/roboflow/supervision/pull/1658)) - Added `as_detections` method to [`KeyPoints`](https://supervision.roboflow.com/0.25.0/keypoint/core/#supervision.keypoint.core.KeyPoints) that converts `KeyPoints` to `Detections`. ([#1658](https://github.com/roboflow/supervision/pull/1658)) - Added a new video to `supervision[assets]`. ([#1657](https://github.com/roboflow/supervision/pull/1657)) ```python from supervision.assets import download_assets, VideoAssets path_to_video = download_assets(VideoAssets.SKIING) ``` - Supervision can now be used with [`Python 3.13`](https://docs.python.org/3/whatsnew/3.13.html). The most renowned update is the ability to run Python [without Global Interpreter Lock (GIL)](https://docs.python.org/3/whatsnew/3.13.html#whatsnew313-free-threaded-cpython). We expect support for this among our dependencies to be inconsistent, but if you do attempt it - let us know the results! ([#1595](https://github.com/roboflow/supervision/pull/1595)) ![py3-13](https://github.com/user-attachments/assets/447339ff-bdfb-4e0b-a3ab-ee464da4e5dd) - Added [`Mean Average Recall`](https://supervision.roboflow.com/latest/metrics/mean_average_recall/) mAR metric, which returns a recall score, averaged over IoU thresholds, detected object classes, and limits imposed on maximum considered detections. ([#1661](https://github.com/roboflow/supervision/pull/1661)) ```python import supervision as sv from supervision.metrics import MeanAverageRecall predictions = sv.Detections(...) targets = s _[Truncated at 4000 characters — full notes: https://github.com/roboflow/supervision/releases/tag/0.25.0]_