github roboflow/supervision 0.30.8
supervision-0.30.8

2 hours ago

v0.30.8 — Sharper video, cleaner labels

Video, YOLO labels, masks, VLM parsing and mAP all get more accurate.

  • VideoSink keeps OpenCV's video quality when OpenCV isn't installed.
  • from_yolo reads pose labels as boxes instead of polygons.
  • MeanAveragePrecision scores class-agnostic runs right when only one side has class IDs.
  • from_vlm returns one Florence-2 detection per object, not one per polygon.
  • from_inference masks no longer drift up to a pixel up and left.

Drop-in upgrade. Without OpenCV, videos get larger; YOLO labels with a negative width or height now raise ValueError.

✨ Spotlights / highlights

sv.VideoSink and sv.process_video keep quality without OpenCV

The PyAV fallback left the encoder bit rate unset, so mp4v and MJPG files came out at under half of what cv2.VideoWriter writes. It now uses OpenCV's rate settings for every codec except H.264. Files get larger and vp09 may encode more slowly; codec="avc1" keeps files small where an H.264 encoder is available. (#2661)

import supervision as sv

video_info = sv.VideoInfo.from_video_path("in.mp4")
with sv.VideoSink("out.mp4", video_info) as sink:  # OpenCV not installed
    for frame in sv.get_video_frames_generator("in.mp4"):
        sink.write_frame(frame)
# before: mp4v written at under half OpenCV's bit rate, visibly softer
# now:    same bit rate OpenCV's writer uses

YOLO pose labels load as boxes

A pose row is a box followed by keypoints. from_yolo used to parse the whole row as a polygon, giving wrong boxes and masks nobody asked for. It now reads the box and skips the keypoints that kpt_shape declares. (#2655)

ds = sv.DetectionDataset.from_yolo(
    images_directory_path="pose/images",
    annotations_directory_path="pose/labels",
    data_yaml_path="pose/data.yaml",  # kpt_shape: [17, 3]
)
# before: polygon-parsed boxes and masks
# now:    one box per row

Class-agnostic mAP with one-sided class IDs

A perfect match scored zero when only one side carried class IDs, such as SAM proposals checked against labeled ground truth. With class_agnostic=True, both sides now count as one class.

One Florence-2 detection per object (#2648)

Florence-2 returns a segmented object as a list of polygons, one per connected region. An object split in two used to come back as two detections; the polygons now merge into one mask with one box around all of them.

Roboflow masks sit on the right pixels (#2649)

from_inference truncated sub-pixel polygon vertices, shifting each mask up and left by up to a pixel. Vertices are now rounded, the way the COCO, YOLO, LabelMe and Pascal VOC loaders already do.

🔄 Migration guide

No migration required for this release.

📝 Notable changes

🌱 Changed

  • sv.DetectionDataset.from_yolo raises ValueError naming the annotation file when a label has a negative width or height; it used to load a box with x_min past x_max, which made Detections.area negative and skewed IoU and NMS. as_yolo now orders the corners of a reversed box before measuring, so it no longer writes a file the loader refuses. (#2663)

🔧 Fixed

  • sv.VideoSink and sv.process_video write mp4v, MJPG and other non-H.264 video at OpenCV's bit rate when OpenCV isn't installed. A frame rate of zero or less now raises RuntimeError in sv.VideoSink, as it does with OpenCV. (#2661)
  • sv.DetectionDataset.from_yolo reads the box of Ultralytics pose labels and skips their keypoints; a kpt_shape other than [K, 2] or [K, 3] raises ValueError. (#2655)
  • sv.DetectionDataset.from_yolo names a malformed annotation line, one with too few values or, for OBB, not nine, in a ValueError instead of failing on an array shape. (#2665)
  • sv.metrics.MeanAveragePrecision(class_agnostic=True) treats detections without class IDs as the same class as labeled ones, and unsigned class ID arrays no longer raise OverflowError on NumPy 2. (#2650)
  • sv.Detections.from_vlm with sv.VLM.FLORENCE_2 merges the polygons of one instance into one detection for <REFERRING_EXPRESSION_SEGMENTATION> and <REGION_TO_SEGMENTATION>, and skips instances with no usable polygon. (#2648)
  • sv.Detections.from_vlm with sv.VLM.QWEN_2_5_VL or sv.VLM.QWEN_3_VL recovers complete detections from a response cut off inside a bbox_2d array or right after a complete object. (#2666)
  • sv.Detections.from_inference rounds polygon vertices to the nearest pixel before rasterising masks, and raises ValueError for NaN or infinite vertices. (#2649)
  • sv.xyxy_to_mask returns an empty mask for a box entirely left of or above the image when its maximum coordinate is a negative fraction. (#2646)
  • sv.Detections.get_anchors_coordinates computes axis-aligned midpoint anchors without integer overflow. (#2660)
  • sv.LineZone.trigger ages crossing history on frames whose detections lack tracker_id, so a reused track ID no longer creates a false crossing after the track expired. (#2644)
  • sv.LineZoneAnnotator(text_orient_to_line=True) no longer raises TypeError without OpenCV for lines drawn right to left. (#2659)
  • The Ultralytics, Inference and YOLO-NAS speed estimation examples measure elapsed time from frame indices; a vehicle missed in one frame of three was reported about 44% too fast. (#2654)
  • examples/speed_estimation/rfdetr_example.py no longer raises AttributeError: supervision._cv2 now provides getPerspectiveTransform and perspectiveTransform. (#2652)

🏆 Contributors

  • Mohammad Hijjawi (@MohammadHijjawi97, LinkedIn) — fixed video quality without OpenCV, Florence-2 instance merging and Roboflow mask rounding.
  • Kari Pikkarainen (@kari-pikkarainen, LinkedIn) — fixed speed estimation timing, the NumPy flip fallback and the perspective-transform fallbacks.
  • Miral Amin (@aminmiral) — made YOLO loading reject negative extents and name malformed lines.
  • NIKHIL (@Nikhi00718) — fixed LineZone history expiry and anchor overflow.
  • kevin (@kevin9327) — made Qwen parsing recover from cut-off responses.
  • A Aswanth Raj (@aswanth-07, LinkedIn) — fixed class-agnostic mAP.
  • Devulapalli Naga Sri Vaishnavi (@Vaishnavi220506) — fixed masks for off-frame fractional boxes.
  • JANG BYUNGKUN (@8rulerstar) — fixed YOLO pose label loading.

Automated contributions: @dependabot


Full changelog: 0.30.7...0.30.8

Don't miss a new supervision release

NewReleases is sending notifications on new releases.