0.29.0
parruda/swarm0.29.0Jun 15, 2026by SkalskiP
AI Summary
Adds comprehensive support for Oriented Bounding Boxes (OBB) including NMS/NMM, new keypoint ellipse annotators for uncertainty visualization, and video audio preservation features.
Key Highlights
- New VertexEllipseAnnotators (Area, Outline, Halo) for keypoint uncertainty
- OBB support for NMS/NMM and ConfusionMatrix metrics
- Preserve audio stream in video processing
- Per-class skeleton definitions for multi-topology rendering
New Features
- VertexEllipseAreaAnnotator, OutlineAnnotator, and HaloAnnotator
- oriented_box_non_max_suppression and oriented_box_non_max_merge
- ConfusionMatrix support for MetricTarget.ORIENTED_BOUNDING_BOXES
- preserve_audio parameter for process_video
- is_obb parameter for DetectionDataset.as_yolo
Full Release Notes
## 🚀 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("<SOURCE_IMAGE_PATH>")
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("<SOURCE_IMAGE_PATH>")
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("<SOURCE_IMAGE_PATH>")
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/#supervision.key_points.annotators.EdgeAnnotator) and [`sv.VertexAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.VertexAnnotator) now respect the `visible` mask. Invisible keypoints and their edges are skipped during rendering. ([#2286](https://github.com/roboflow/supervision/pull/2286))
- [`sv.EdgeAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.EdgeAnnotator) and [`sv.VertexLabelAnnotator`](https://supervision.roboflow.com/0.29.0/keypoint/annotators/#supervision.key_points.annotators.VertexLabelAnnotator) now support per-class skeleton definitions, enabling correct rendering when multiple skeleton topologies (e.g. person + animal) coexist in one frame. ([#2286](https://github.com/roboflow/supervision/pull/2286))
- [`sv.Detections.with_nms`](https://supervision.roboflow.com/0.29.0/detection/core/#supervision.detection.core.Detections.with_nms) and [`sv.Detections.with_nmm`](https://supervision.roboflow.com/0.29.0/detection/core/#supervision.detection.core.Detections.with_nmm) are now OBB-aware. When `data[ORIENTED_BOX_COORDINATES]` is present, oriented-box IoU is used automatically instead of axis-aligned box IoU. ([#2303](https://github.com/roboflow/supervision/pull/2303))
<img width="1703" height="889" alt="box_nms_demo" src="https://github.com/user-attachments/assets/1845d110-040f-4ee1-9f92-a69dde6ed748" />
<img width="1703" height="889" alt="box_nmm_demo" src="https://github.com/user-attachments/assets/a7a21f62-17ef-4e20-8d78-d0cf12dae339" />
<img width="1703" height="889" alt="obb_nms_demo" src="https://github.com/user-attachments/assets/400ab62b-0202-47f3-929b-89d04160ff88" />
<img width="1703" height="889" alt="obb_nmm_demo" src="https://github.com/user-attachments/assets/18267478-2428-4052-946a-89607e97cb64" />
- [`sv.Detections.area`](https://supervision.roboflow.com/0.29.0/detection/core/#supervision.detection.core.Detections.area) is now OBB-aware. When oriented box coordinates are present, the property returns the polygon area of the rotated bounding box (via the shoelace formula) instead of the axis-aligned box area. ([#2306](https://github.com/roboflow/supervision/pull/2306))
- [`sv.InferenceSlicer`](https://supervision.roboflow.com/0.29.0/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) now detects OBB outputs from callbacks and automatically falls back to sequential processing to avoid thread-safety issues when `thread_workers > 1`. ([#2256](https://github.com/roboflow/supervision/pull/2256))
- Fixed [`sv.oriented_box_iou_batch`](https://supervision.roboflow.com/0.29.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.oriented_box_iou_batch) to correctly handle non-square canvases. Previously, rasterization assumed square dimensions, leading to incorrect IoU values for tall or wide images. ([#2282](https://github.com/roboflow/supervision/pull/2282))
## 🔧 Fixed
- Fixed [`sv.process_video`](https://supervision.roboflow.com/0.29.0/utils/video/#supervision.utils.video.process_video) audio stream handling. The audio muxing path now correctly creates temp files on the same filesystem, decodes ffmpeg errors, and avoids muxing incomplete output. ([#2252](https://github.com/roboflow/supervision/pull/2252))
- Fixed [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.29.0/detection/core/#supervision.detection.core.Detections.from_vlm) returning `None` for `class_id` on empty VLM parses. Now returns an empty int ndarray. ([#2239](https://github.com/roboflow/supervision/pull/2239))
- Fixed [`sv.Detections.from_inference`](https://supervision.roboflow.com/0.29.0/detection/core/#supervision.detection.core.Detections.from_inference) to preserve `class_name` as a string-dtype array when predictions are empty. Previously it returned an untyped empty array. ([#2270](https://github.com/roboflow/supervision/pull/2270))
- Fixed [`sv.HeatMapAnnotator`](https://supervision.roboflow.com/0.29.0/annotators/#supervision.annotators.core.HeatMapAnnotator) divide-by-zero crash when called with empty detections. ([#2269](https://github.com/roboflow/supervision/pull/2269))
- Fixed COCO export emitting 0-indexed `category_id` values. Now correctly emits 1-indexed IDs as per the COCO specification. ([#2276](https://github.com/roboflow/supervision/pull/2276))
- Fixed COCO annotation and image IDs not being chainable across dataset splits. IDs are now sequential across train/val/test. ([#2267](https://github.com/roboflow/supervision/pull/2267))
- Fixed [`sv.DetectionDataset.as_yolo`](https://supervision.roboflow.com/0.29.0/datasets/#supervision.dataset.core.DetectionDataset.as_yolo) losing OBB rotation when exporting oriented bounding boxes. ([#2289](https://github.com/roboflow/supervision/pull/2289))
- Fixed YOLO dataset loading to sort class names by numeric keys when the `data.yaml` uses integer class IDs. ([#2296](https://github.com/roboflow/supervision/pull/2296))
- Fixed letterbox utility to support grayscale images. ([#2297](https://github.com/roboflow/supervision/pull/2297))
- Fixed file extension filters to normalize casing (e.g. `.JPG` now matches `.jpg`). ([#2298](https://github.com/roboflow/supervision/pull/2298))
## ⚠️ Deprecated
| Deprecated | Removal | Replacement |
|---|---|---|
| `KeyPoints.confidence` | `0.32.0` | `KeyPoints.keypoint_confidence` |
| `merge_inner_detection_object_pair` | `0.32.0` | None (internal use only) |
| `merge_inner_detections_objects` | `0.32.0` | None (internal use only) |
| `merge_inner_detections_objects_without_iou` | `0.32.0` | None (internal use only) |
| `validate_detections_fields` | `0.32.0` | None (internal use only) |
| `validate_vlm_parameters` | `0.32.0` | None (internal use only) |
| `validate_fields_both_defined_or_none` | `0.32.0` | None (internal use only) |
| `validate_xyxy` | `0.32.0` | None (internal use only) |
| `validate_mask` | `0.32.0` | None (internal use only) |
| `validate_class_id` | `0.32.0` | None (internal use only) |
| `validate_confidence` | `0.32.0` | None (internal use only) |
| `validate_tracker_id` | `0.32.0` | None (internal use only) |
| `validate_data` | `0.32.0` | None (internal use only) |
| `validate_xy` | `0.32.0` | None (internal use only) |
| `validate_key_point_confidence` | `0.32.0` | None (internal use only) |
| `validate_key_points_fields` | `0.32.0` | None (internal use only) |
| `validate_resolution` | `0.32.0` | None (internal use only) |
| `validate_custom_values` | `0.32.0` | None (internal use only) |
| `validate_input_tensors` | `0.32.0` | None (internal use only) |
| `validate_labels` | `0.32.0` | None (internal use only) |
## 🏆 Contributors
@SkalskiP ([Piotr Skalski](https://www.linkedin.com/in/skalskip92/)), @Borda ([Jirka Borovec](https://github.com/Borda)), @kounelisagis ([Agis Kounelis](https://github.com/kounelisagis)), @RitwijParmar ([Ritwij Aryan Parmar](https://github.com/RitwijParmar)), @Khanz9664 ([Shahid Ul Islam](https://github.com/Khanz9664)), @satishkc7 ([SATISH K C](https://github.com/satishkc7)), @Ace3Z ([Mahbod Tajdini](https://github.com/Ace3Z)), @Madhav-C, @RubenHaisma ([Ruben Haisma](https://github.com/RubenHaisma)), @adhavan18 ([Tamil Adhavan](https://github.com/adhavan18)), @Bortlesboat ([Andrew Barnes](https://github.com/Bortlesboat)), @Lourdhu02, @tarunbommawar27, @YousefZahran1 ([Youssef Ibrahim](https://github.com/YousefZahran1)), @JFrench-Enterprise, @Patel-Prem ([Premkumar Patel](https://github.com/Patel-Prem))