Skip to content

chore(deps-dev): bump supervision from 0.30.6 to 0.31.1 - #16

Closed
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/uv/supervision-0.31.1
Closed

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/uv/supervision-0.31.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 24, 2026

Copy link
Copy Markdown
Contributor

Bumps supervision from 0.30.6 to 0.31.1.

Release notes

Sourced from supervision's releases.

supervision-0.31.1

v0.31.1 — Recall that matches COCO, boxes that don't overflow

A bug-fix release: recall scores now agree with COCO, and half-precision boxes stop overflowing.

  • MeanAverageRecall skips crowd regions and matches predictions in confidence order, like pycocotools.
  • COCO segmentations loaded without an area field no longer make mAP return -1.
  • float16 boxes keep finite areas, and mAP and with_nmm stop overflowing on narrow coordinate types.
  • Mask and halo annotators draw on grayscale scenes, and vertex annotators accept (x, y, z) points.
  • Without OpenCV, ellipses and thick circles render like OpenCV 5, and grayscale images save correctly.

Drop-in upgrade, no code changes. mAR values can move: up on COCO data with crowd annotations, and in either direction where confidence order now decides which prediction claims a target.

✨ Spotlights / highlights

Recall that matches COCO

sv.metrics.MeanAverageRecall used to count COCO crowd regions as missed objects and to pair predictions with the highest-IoU target first. It now leaves out targets with data["iscrowd"] or data["ignore"] set, the same rule MeanAveragePrecision uses. It also matches predictions in descending confidence order with COCO's tie rule, and counts an oriented-box IoU of exactly 0.55, 0.6, 0.8 or 0.85 as a match at that threshold. One target, one crowd target and a perfect prediction now score 1.0 instead of 0.5. (#2750, #2758, #2752)

import numpy as np
import supervision as sv
from supervision.metrics import MeanAverageRecall
targets = sv.Detections(
xyxy=np.array([[0, 0, 10, 10], [20, 20, 30, 30]], dtype=float),
class_id=np.array([0, 0]),
data={"iscrowd": np.array([0, 1])},
)
predictions = sv.Detections(
xyxy=np.array([[0, 0, 10, 10]], dtype=float),
class_id=np.array([0]),
confidence=np.array([0.9]),
)
MeanAverageRecall().update(predictions, targets).compute().mAR_at_100  # 1.0

Half-precision boxes that stay finite

A 256×256 box in float16 has an area of 65,536, which is past float16's maximum, so Detections.box_area returned inf and area filters dropped it. Box areas of float16 detections are now computed and returned in float32, and MeanAveragePrecision and with_nmm no longer overflow on float16 or narrow integer coordinates either. COCO segmentations loaded with masks but without an area field now get it from the decoded mask, so those targets stay in their size bucket instead of turning mAP into -1. (#2764, #2743, #2753, #2763)

import numpy as np
import supervision as sv
detections = sv.Detections(
xyxy=np.array([[0, 0, 256, 256], [0, 0, 0.01, 0.01]], dtype=np.float16)
)
detections.box_area  # array([6.5536000e+04, 1.0004273e-04], dtype=float32)

... (truncated)

Changelog

Sourced from supervision's changelog.

0.31.1 Oct 20, 2026

  • MeanAverageRecall and COCO: recall evaluation follows pycocotools more closely.
    • sv.metrics.MeanAverageRecall now leaves COCO ignore regions out of recall: targets with data["iscrowd"] set, as sv.DetectionDataset.from_coco loads them, or with data["ignore"] set, the same rule MeanAveragePrecision applies. They were counted as missed objects, so mAR on COCO data with crowd annotations was lower than pycocotools AR: one target, one crowd target and a perfect prediction scored mAR_at_100 0.5 instead of 1.0. A class whose only targets are crowd regions no longer counts as zero recall. (#2750)
    • sv.metrics.MeanAverageRecall now matches predictions in descending confidence order, as COCO does, instead of choosing globally highest-IoU pairs first. When a high-confidence prediction overlaps two targets and a lower-confidence prediction overlaps only the first, the lower-confidence prediction no longer takes that target first. (#2750)
    • sv.metrics.MeanAverageRecall now follows COCO's last-target tie rule when multiple eligible targets have the same IoU. This preserves confidence-ordered matching and the crowd/ignore handling added in #2750. (#2758)
    • sv.metrics.MeanAverageRecall, Precision, Recall and F1Score with metric_target=MetricTarget.ORIENTED_BOUNDING_BOXES now count a prediction whose IoU is exactly 0.55, 0.6, 0.8 or 0.85 as a match at that threshold, as they do for boxes and masks. The oriented-box IoU was float64 while the thresholds are float32, which rounds those four values up. (#2752)
  • Overflow-safe boxes: half-precision and narrow-integer coordinates no longer overflow.
    • Detections.box_area and box-based Detections.area now compute float16 coordinates in float32. Ordinary 256×256 boxes no longer overflow to infinity, tiny boxes retain nonzero areas, and area filtering works for half-precision detections. Integer and wider floating-point results retain their existing dtypes. (#2764)
    • sv.metrics.MeanAveragePrecision now computes box extents and areas without overflowing float16 or narrow integer coordinate dtypes. Perfect large boxes no longer score -1 or enter the wrong size bucket, and unmatched predictions are included or ignored according to their actual area. (#2743)
    • sv.Detections.with_nmm now computes area-weighted confidence without overflowing integer, float16 or float32 box extents. (#2753)
  • COCO loading now derives a segmented annotation's missing area from its decoded mask. Missing areas previously became NaN, causing MeanAveragePrecision to exclude those targets from every size bucket and return -1 even for perfect predictions. Explicit areas and box-only annotations retain their existing behavior. (#2763)
  • Masks and polygons: degenerate inputs no longer come back empty or raise.
    • resize_masks retains at least one pixel on each spatial axis when downscaling narrow masks, instead of returning an empty array. (#2762)
    • sv.filter_polygons_by_area and sv.polygon_to_xyxy now accept empty polygons instead of raising a ValueError. Empty polygons evaluate to zero area when filtering, and polygon_to_xyxy returns an all-zero bounding box while preserving the input NumPy array dtype. (#2761)
  • Annotators: more scene and key point inputs are drawn instead of rejected.
    • sv.MaskAnnotator and sv.HaloAnnotator now annotate grayscale scenes, shaped (H, W) or (H, W, 1) or given as a Pillow "L" image, instead of raising ValueError. Masks and halos take the first (blue) channel of their color, the gray value OpenCV writes for boxes and polygons on the same scene. (#2755)
    • Keypoint annotators use x/y when drawing accepted three-coordinate keypoints. Vertex and ellipse drawing no longer raises a tuple-unpacking error, and edge and label visibility checks ignore the extra coordinate. Rendering matches equivalent two-coordinate input, including missing-point and explicit-visibility handling. (#2759)
    • sv.MaskAnnotator no longer widens its blend region to the boxes of all-False masks, for dense masks and CompactMask alike, and skips blending when every CompactMask is all-False. Empty masks previously contributed their full bounding boxes, causing unnecessary image copies and blending outside the foreground region. CompactMask foreground counts are read from RLE without decoding; nonempty mask bounds and painted pixels are unchanged. (#2741)
  • cv2-free fallback: the NumPy fallback follows OpenCV more closely.
    • The NumPy fallback for ellipse now matches OpenCV's Ellipse2Poly / EllipseEx rasterization for full ellipses, partial arcs, rotation, thick strokes, fills and geometry that leaves the canvas. A (25, 15) ellipse at thickness=2 previously painted 308 pixels against OpenCV's 380, and filled arcs differed at their boundary. The fallback now ports OpenCV's sine table, fixed-point ellipse sampling, ThickLine and FillEdgeCollection paths. (#2740)
    • The NumPy fallback for circle now centres a thick outline on the radius, like OpenCV, instead of growing it inward from the bounding box. Every thick circle the fallback drew (CircleAnnotator, DotAnnotator outlines, key points) was shrunk by half its thickness: thickness=5 at radius 10 covered radii 5–10 instead of about 7.5–12.5. Thick outlines now go through the fallback ellipse, which matches cv2.circle pixel for pixel. Filled circles and 1-pixel outlines are unchanged. (#2765)
    • Image writing without OpenCV now accepts explicit single-channel grayscale arrays and saves BGRA images as JPEG by discarding alpha. In-memory dataset exports no longer lose these JPEG images. (#2754)
    • Video reading without OpenCV now handles files with audio streams before the first video stream. Frame decoding, metadata, frame counting and seeking select the first video stream independently of its container index. (#2746)

0.31.0 Oct 16, 2026

  • Depth maps: the new sv.DepthMap module loads, measures and draws depth.
    • Added sv.DepthMap and sv.DepthAnnotator, which colour a stereo disparity, metric depth or relative depth map over a NumPy or Pillow image: near objects warm, pixels without depth unpainted, in Turbo, Viridis, Cividis, Inferno, Magma or grayscale. It does not require OpenCV. (#2691)
    • Added sv.DepthClipRange, which keeps the colour scale of sv.DepthAnnotator fixed across a video. DepthClipRange.from_depth_maps computes one percentile range over a clip's maps, read once from a list or a generator, with bounded memory. (#2692)
    • sv.DepthMap now measures distance: sv.DepthCamera turns disparity into metres (to_depth), and measure_detections stores the median depth under each object in detections.data["depth_m"], also from a map of another size than the image with resolution_wh. Also adds resize, crop, value_at and sv.DepthAnnotator(scale="metric"). (#2693)
    • Added sv.DepthMap loaders: from_inference (depth models served by Roboflow Inference, such as Depth Anything and YOLO26 depth), from_ultralytics (YOLO26 depth, in metres), from_transformers, and from_png16 and from_pfm for dataset files such as KITTI and Middlebury. (#2694)
  • sv.PolygonZone.trigger and sv.LineZone.trigger accept an optional per-frame coord_transform, which maps detection anchors into the frame the zone was drawn on before testing them, so counts stay attached to the scene while the camera moves. It is any object with abs_to_rel and rel_to_abs, typed by the new sv.CoordinatesTransformation protocol, such as the transformations returned by the trackers motion estimator. Only the in-zone and line-crossing checks change: drawing with sv.PolygonZoneAnnotator and sv.LineZoneAnnotator is unchanged, each zone expects transforms into one consistent reference frame, and coord_transform=None, the default, keeps current results. (#2657)
  • Transformed sv.PolygonZone anchors just outside the mask remain outside even when rounding would move a fractional coordinate onto the edge pixel. (#2657)
  • sv.Detections.from_ultralytics now removes letterbox padding using the rounded content dimensions. Fractional padding no longer shifts or truncates segmentation masks when restoring the original image resolution. (#2739)
  • sv.Detections indexed with a Python list of booleans, such as detections[[c == 0 for c in detections.class_id]], now selects list-valued data with the same mask as its arrays. The list was read as positions, so True and False became the indices 1 and 0: an all-True mask returned the second item for every row (["cat", "dog", "bird"] became ["dog", "dog", "dog"]), any other mask failed with ValueError: Length of list for key ... must be ..., and a list of np.bool_ values raised TypeError. Integer lists, slices and NumPy index arrays are unchanged. (#2737) Integer-list selection allocates only for requested rows, avoiding quadratic position-array allocation when the smoother selects rows repeatedly.
  • sv.move_boxes and InferenceSlicer translations no longer wrap integer coordinates when an offset crosses the input dtype's bounds. A uint8 box at [250, 0, 255, 10] shifted by [10, 0] previously became [4, 0, 9, 10]; translations now promote integer results to int64, or float64 when the result exceeds the int64 range, while floating-point behavior is unchanged. (#2734)
  • Performance: sv.metrics.MeanAveragePrecision and sv.metrics.KeyPointMeanAveragePrecision now run COCO greedy matching with NumPy over all IoU thresholds and targets at once, instead of a Python loop over every threshold, prediction and target. Dense scenes evaluate much faster: one image with 1000 predictions and 1000 targets at max_detection_thresholds=(1, 10, 1000) drops from 35.9 s to 0.5 s. No output changes. (#2733)
  • sv.Detections.box_aspect_ratio now subtracts integer corners without overflow or loss of narrow widths at large coordinate origins. Floating-coordinate arithmetic and zero-height NaN results are unchanged. (#2729)
  • BlurAnnotator and PixelateAnnotator preserve an explicit grayscale channel axis. Images shaped (H, W, 1) no longer fail with a broadcasting error when OpenCV returns a two-dimensional filtered region. (#2725)
  • cv2-free fallback: the NumPy fallback follows OpenCV more closely.
    • The NumPy resize fallback now samples the same source pixel as OpenCV for INTER_NEAREST when dsize is given. It used the exact integer ratio x * src // dst, while OpenCV steps through the source with the reciprocal of the size ratio. At some whole-number positions of x * src / dst, reciprocal multiplication rounds below the integer: a 6-pixel ramp resized to 34 wide picks pixel 2 at x = 17, not 3. These differences also made sv.CompactMask.resize, which derives its grid from this call, give different masks with and without OpenCV installed. (#2722)
    • The NumPy fallback line, polylines and drawContours outline now match OpenCV's LINE_8 rasterization for thickness 2 or more, including segments that leave the canvas. The fallback used Pillow's square-ended wide lines, while OpenCV draws each segment as a fixed-point quadrilateral with round caps; on 2,000 random lines every one differed, by a median 24% of OpenCV's pixels. The fallback now ports OpenCV's ThickLine, FillConvexPoly and Line2. Consumers using LINE_8, such as sv.draw_line and sv.draw_polygon, receive the corrected pixels. Antialiased drawing (LINE_AA) remains unsupported by the fallback, including calls from LineZoneAnnotator. thickness=1 lines are unchanged. (#2727)
    • The NumPy fallback for cv2.fillPoly now uses OpenCV-compatible line and scanline rasterization, so polygon_to_mask, polygon drawing, and PolygonZone paint the same boundary pixels with or without OpenCV installed for polygons within the image bounds. (#2730)
  • sv.process_video now stops its reader when a callback or frame write fails, including callback interruption, instead of decoding the rest of the source before raising the error. Shutdown releases the source capture and waits for queued writes unless the writer itself fails; an active backend decode or write is allowed to finish. Decoding and callback errors retain their original exceptions when capture or output-writer release also fails; secondary cleanup failures are logged. (#2720)
  • sv.LabelAnnotator, sv.RichLabelAnnotator and sv.VertexLabelAnnotator with smart_position=True now separate labels whose boxes share a center. spread_out_boxes pushes overlapping boxes away from each other's centers, and boxes with the same center got no direction, so they stayed exactly on top of each other and only the last label was visible: two detections with the same box and same-width labels, or two key points at the same position. Such boxes are now pushed apart vertically, the earlier one upward. (#2718)
  • mypy now type checks the test helpers and the assets, classification, cv2, depth, draw, geometry and validators test packages under the project's strict settings, the first slice of removing the tests.* ignore_errors override. The 75 errors these packages had are fixed with annotations and narrowing only, no test behaviour changes. The remaining test packages stay exempt for now. (#2728)
  • Oriented-box MeanAveragePrecision now preserves corner precision and computes polygon areas relative to a local origin. Boxes at large coordinates no longer collapse during matching or enter the wrong object-size bucket through cancellation in the area calculation. (#2717)
  • Added keyword-only max_detection_thresholds to MeanAveragePrecision for dense-scene evaluation. The COCO default (1, 10, 100) is unchanged; custom limits are recorded in results, text summaries, plot titles and DataFrame attributes. (#2716)
  • sv.KeyPoints now preserves all three coordinates when selecting a single keypoint with a NumPy integer or zero-dimensional array row index and an integer anchor index. The result keeps shape (1, 1, 3) instead of raising a reshape error. Two-coordinate points and the selected confidence, visibility, class IDs, and custom data are unchanged. (#2715)

... (truncated)

Commits
  • f2adfad releasing 0.31.1
  • 2f01d90 fix(cv2): centre a thick fallback circle on its radius like OpenCV (#2765)
  • 473712b fix(detection): prevent float16 overflow in box areas (#2764)
  • 0a5f759 fix(dataset): derive missing COCO areas from decoded masks (#2763)
  • 8bbb092 fix(detection): preserve narrow mask dimensions when resizing (#2762)
  • 1726b1b fix(detection): handle empty polygons in filter_polygons_by_area and `polyg...
  • b3a1b96 fix(key_points): render three-coordinate points using x and y (#2759)
  • a1aaef1 fix(metrics): match COCO target ties in mAR (#2758)
  • ebb1b25 fix(annotators): draw masks and halos on grayscale scenes (#2755)
  • c0e2b93 fix(cv2): preserve grayscale and BGRA images when encoding (#2754)
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [supervision](https://github.com/roboflow/supervision) from 0.30.6 to 0.31.1.
- [Release notes](https://github.com/roboflow/supervision/releases)
- [Changelog](https://github.com/roboflow/supervision/blob/develop/docs/changelog.md)
- [Commits](roboflow/supervision@0.30.6...0.31.1)

---
updated-dependencies:
- dependency-name: supervision
  dependency-version: 0.31.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file python:uv Pull requests that update python:uv code labels Oct 24, 2026
@8rulerstar

Copy link
Copy Markdown
Owner

#18 에서 함께 올림

@8rulerstar 8rulerstar closed this Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file python:uv Pull requests that update python:uv code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant