Skip to content

Changelog

0.26.0 Jul 16, 2025

Removed

supervision-0.26.0 放弃了对 python3.8 的支持,并将所有代码升级为 python3.9 语法风格。

提示

Supervision 的文档主题现已焕然一新,符合所有 Roboflow 开源项目的文档风格。(#1858)

  • Added #1774: 支持 IOS (Intersection over Smallest) 重叠度量,该度量用于衡量在 sv.Detections.with_nms, sv.Detections.with_nmm, sv.box_iou_batchsv.mask_iou_batch 中,较大对象覆盖了多少较小对象。

    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 #1874: sv.box_iou,可高效计算两个独立边界框之间的 IoU (Intersection over Union)。

  • Added #1816: sv.process_video 支持帧限制和进度条。

  • Added #1788: 通过 sv.KeyPoints.from_transformers 支持从 ViTPoseViTPose++ 推理结果创建 sv.KeyPoints 对象。

  • Added #1823: sv.xyxy_to_xcycarh 函数,用于将边界框坐标从 (x_min, y_min, x_max, y_max) 转换为测量空间格式 (center x, center y, aspect ratio, height),其中宽高比为 width / height

  • Added #1788: sv.xyxy_to_xywh 函数,用于将边界框坐标从 (x_min, y_min, x_max, y_max) 格式转换为 (x, y, width, height) 格式。

  • Changed #1820: sv.LabelAnnotator 现在支持 smart_position 参数,可以自动将标签保持在帧边界内,以及 max_line_length 参数来控制长标签或多行标签的文本换行。

  • Changed #1825: sv.LabelAnnotator 现在支持非字符串标签。

  • Changed #1792: sv.Detections.from_vlm 现在支持解析 Google Gemini 模型 生成的响应中的边界框和分割掩码。

    import supervision as sv
    
    gemini_response_text = """```json
        [
            {"box_2d": [543, 40, 728, 200], "label": "cat", "id": 1},
            {"box_2d": [653, 352, 820, 522], "label": "dog", "id": 2}
        ]
    ```"""
    
    detections = sv.Detections.from_vlm(
        sv.VLM.GOOGLE_GEMINI_2_5,
        gemini_response_text,
        resolution_wh=(1000, 1000),
        classes=['cat', 'dog'],
    )
    
    detections.xyxy
    # array([[543., 40., 728., 200.], [653., 352., 820., 522.]])
    
    detections.data
    # {'class_name': array(['cat', 'dog'], dtype='<U26')}
    
    detections.class_id
    # array([0, 1])
    
  • Changed #1878: sv.Detections.from_vlm 现在支持解析 Moondream 生成的响应中的边界框。

    import supervision as sv
    
    moondream_result = {
        'objects': [
            {
                'x_min': 0.5704046934843063,
                'y_min': 0.20069346576929092,
                'x_max': 0.7049859315156937,
                'y_max': 0.3012596592307091
            },
            {
                'x_min': 0.6210969910025597,
                'y_min': 0.3300672620534897,
                'x_max': 0.8417936339974403,
                'y_max': 0.4961046129465103
            }
        ]
    }
    
    detections = sv.Detections.from_vlm(
        sv.VLM.MOONDREAM,
        moondream_result,
        resolution_wh=(1000, 1000),
    )
    
    detections.xyxy
    # array([[1752.28,  818.82, 2165.72, 1229.14],
    #        [1908.01, 1346.67, 2585.99, 2024.11]])
    
  • Changed #1709: sv.Detections.from_vlm 现在支持解析 Qwen-2.5 VL 生成的响应中的边界框。

    import supervision as sv
    
    qwen_2_5_vl_result = """```json
    [
        {"bbox_2d": [139, 768, 315, 954], "label": "cat"},
        {"bbox_2d": [366, 679, 536, 849], "label": "dog"}
    ]
    ```"""
    
    detections = sv.Detections.from_vlm(
        sv.VLM.QWEN_2_5_VL,
        qwen_2_5_vl_result,
        input_wh=(1000, 1000),
        resolution_wh=(1000, 1000),
        classes=['cat', 'dog'],
    )
    
    detections.xyxy
    # array([[139., 768., 315., 954.], [366., 679., 536., 849.]])
    
    detections.class_id
    # array([0, 1])
    
    detections.data
    # {'class_name': array(['cat', 'dog'], dtype='<U10')}
    
    detections.class_id
    # array([0, 1])
    
  • Changed #1786: 显著提高了 sv.HeatMapAnnotator 中 HSV 颜色映射的速度,在 1920x1080 帧上实现了约 28 倍的性能提升。

  • Fix #1834: Supervision 的 sv.MeanAveragePrecision现已与官方 COCO 评估工具 pycocotools 完全对齐,确保了准确性和标准化指标。此更新使我们能够启动新版本的 Computer Vision Model Leaderboard

    import supervision as sv
    from supervision.metrics import MeanAveragePrecision
    
    predictions = sv.Detections(...)
    targets = sv.Detections(...)
    
    map_metric = MeanAveragePrecision()
    map_metric.update(predictions, targets).compute()
    
    # Average Precision (AP) @[ IoU=0.50:0.95 | area=   all | maxDets=100 ] = 0.464
    # Average Precision (AP) @[ IoU=0.50      | area=   all | maxDets=100 ] = 0.637
    # Average Precision (AP) @[ IoU=0.75      | area=   all | maxDets=100 ] = 0.203
    # Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.284
    # Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.497
    # Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.629
    
  • Fix #1767: 修复了在过滤検出时丢失 sv.Detections.data 的问题。

0.25.0 Nov 12, 2024

  • 本次发布没有移除或弃用任何内容!

  • LineZone 的重要更新:在计算线交叉时,可能抖动的检测会重复计算(或多次计算)。现在可以通过 minimum_crossing_threshold 参数解决此问题。如果将其设置为 2 或更高,将使用额外的帧来确认交叉,从而显著提高准确性。(#1540)

  • 现在可以跟踪被检测为 KeyPoints 的对象。请参阅 Object Tracking Guide 中的完整分步指南。(#1658)

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
)
  • KeyPoints 添加了 is_empty 方法,用于检查对象中是否包含任何关键点。(#1658)

  • KeyPoints 添加了 as_detections 方法,该方法将 KeyPoints 转换为 Detections。(#1658)

  • supervision[assets] 添加了一个新视频。(#1657)

from supervision.assets import download_assets, VideoAssets

path_to_video = download_assets(VideoAssets.SKIING)
  • Supervision 现在可以与 Python 3.13 一起使用。最值得称道的更新是能够 在没有全局解释器锁 (GIL) 的情况下 运行 Python。我们预计依赖项对它的支持将不一致,但如果您尝试了——请告诉我们结果!(#1595)

  • 添加了 Mean Average Recall mAR 指标,该指标返回一个召回率分数,平均了 IoU 阈值、检测目标类别以及对最多考虑检测次数的限制。(#1661)

import supervision as sv
from supervision.metrics import MeanAverageRecall

predictions = sv.Detections(...)
targets = sv.Detections(...)

map_metric = MeanAverageRecall()
map_result = map_metric.update(predictions, targets).compute()

map_result.plot()
  • 添加了 PrecisionRecall 指标,为比较模型输出与地面真实值或另一个模型提供了基准 (#1609)
import supervision as sv
from supervision.metrics import Recall

predictions = sv.Detections(...)
targets = sv.Detections(...)

recall_metric = Recall()
recall_result = recall_metric.update(predictions, targets).compute()

recall_result.plot()
  • 所有 Metrics 现在都支持定向边界框 (OBB) (#1593)
import supervision as sv
from supervision.metrics import F1_Score

predictions = sv.Detections(...)
targets = sv.Detections(...)

f1_metric = MeanAverageRecall(metric_target=sv.MetricTarget.ORIENTED_BOUNDING_BOXES)
f1_result = f1_metric.update(predictions, targets).compute()
import supervision as sv
from ultralytics import YOLO

image = cv2.imread("image.jpg")

label_annotator = sv.LabelAnnotator(smart_position=True)

model = YOLO("yolo11m.pt")
results = model(image)[0]
detections = sv.Detections.from_ultralytics(results)

annotated_frame = label_annotator.annotate(first_frame.copy(), detections)
sv.plot_image(annotated_frame)
  • Detections 添加了 metadata 变量。它允许您为每个图像存储自定义数据,而不是像使用 data 变量那样为每个检测对象存储。例如,metadata 可用于存储源视频路径、摄像机型号或摄像机参数。(#1589)
import supervision as sv
from ultralytics import YOLO

model = YOLO("yolov8m")

result = model("image.png")[0]
detections = sv.Detections.from_ultralytics(result)

# `data` 中的项必须与检测的长度匹配
object_ids = [num for num in range(len(detections))]
detections.data["object_number"] = object_ids

# `metadata` 中的项可以为任何长度。
detections.metadata["camera_model"] = "Luxonis OAK-D"
  • 添加了 py.typed 类型提示元文件。它应该为类型注解器和 IDE 提供更强的信号,表明类型支持可用。(#1586)

  • ByteTrack 不再需要 detections 具有 class_id (#1637)

  • draw_line, draw_rectangle, draw_filled_rectangle, draw_polygon, draw_filled_polygonPolygonZoneAnnotator 现在带有默认颜色 (#1591)
  • 在合并多个数据集时,将数据集类视为区分大小写。 (#1643)
  • 扩展了 Metrics 文档,包含示例图表和打印结果 (#1660)
  • 为多边形区域添加了用法示例 (#1608)
  • 对多边形错误处理进行了小型改进:(#1602)

  • 更新了 ByteTrack,移除了共享变量。以前,多个 ByteTrack 实例会共享一些数据,需要大量使用 tracker.reset()。(#1603), (#1528)

  • 修复了 MeanAveragePrecisionclass_agnostic 设置无效的错误。(#1577) hacktoberfest
  • 从我们的 CI 系统中移除了欢迎工作流。(#1596)

  • ByteTrack 进行了大量重构:将 STrack 移至单独的类,移除了多余的 BaseTrack 类,移除了未使用的变量 (#1603)

  • RichLabelAnnotator 进行了大量重构,将其内容与 LabelAnnotator 匹配。(#1625)

0.24.0 Oct 4, 2024

import supervision as sv
from supervision.metrics import F1Score

predictions = sv.Detections(...)
targets = sv.Detections(...)

f1_metric = F1Score()
f1_result = f1_metric.update(predictions, targets).compute()

print(f1_result)
print(f1_result.f1_50)
print(f1_result.small_objects.f1_50)
import supervision as sv
import cv2

image = cv2.imread("<SOURCE_IMAGE_PATH>")

line_zone = sv.LineZone(
    start=sv.Point(0, 100),
    end=sv.Point(50, 200)
)
line_zone_annotator = sv.LineZoneAnnotator(
    text_orient_to_line=True,
    display_text_box=False,
    text_centered=False
)

annotated_frame = line_zone_annotator.annotate(
    frame=image.copy(), line_counter=line_zone
)

sv.plot_image(annotated_frame)
  • LineZone 添加了每类计数功能,并为 LineZoneAnnotatorMulticlass 引入了用于可视化每类计数的Annotator。此功能允许跟踪穿过线条的单个类别,增强了交通监控或人群分析等用例的灵活性。 #1555
import supervision as sv
import cv2

image = cv2.imread("<SOURCE_IMAGE_PATH>")

line_zone = sv.LineZone(
    start=sv.Point(0, 100),
    end=sv.Point(50, 200)
)
line_zone_annotator = sv.LineZoneAnnotatorMulticlass()

frame = line_zone_annotator.annotate(
    frame=frame, line_zones=[line_zone]
)

sv.plot_image(frame)
  • 添加了 from_easyocr,允许将 OCR 结果集成到 supervision 框架中。EasyOCR 是一个开源光学字符识别 (OCR) 库,可以从图像中读取文本。 #1515
import supervision as sv
import easyocr
import cv2

image = cv2.imread("<SOURCE_IMAGE_PATH>")

reader = easyocr.Reader(["en"])
result = reader.readtext("<SOURCE_IMAGE_PATH>", paragraph=True)
detections = sv.Detections.from_easyocr(result)

box_annotator = sv.BoxAnnotator(color_lookup=sv.ColorLookup.INDEX)
label_annotator = sv.LabelAnnotator(color_lookup=sv.ColorLookup.INDEX)

annotated_image = image.copy()
annotated_image = box_annotator.annotate(scene=annotated_image, detections=detections)
annotated_image = label_annotator.annotate(scene=annotated_image, detections=detections)

sv.plot_image(annotated_image)
import numpy as np

boxes_true = np.array([[[1, 0], [0, 1], [3, 4], [4, 3]]])
boxes_detection = np.array([[[1, 1], [2, 0], [4, 2], [3, 3]]])
ious = sv.oriented_box_iou_batch(boxes_true, boxes_detection)
print("IoU between true and detected boxes:", ious)
  • 扩展了 PolygonZoneAnnotator 以允许在绘制区域时设置不透明度,通过可调透明度填充区域来增强可视化。 #1527
import cv2
from ncnn.model_zoo import get_model
import supervision as sv

image = cv2.imread("<SOURCE_IMAGE_PATH>")
model = get_model(
    "yolov8s",
    target_size=640,
    prob_threshold=0.5,
    nms_threshold=0.45,
    num_threads=4,
    use_gpu=True,
)
result = model(image)
detections = sv.Detections.from_ncnn(result)

Removed

已移除 PolygonZone 中的 frame_resolution_wh 参数。

Removed

移除了 Supervision 安装方法 "headless""desktop",因为它们不再需要。pip install supervision[headless] 将安装基础库并无害地警告不存在的附加组件。

  • Supervision 现在依赖 opencv-python 而不是 opencv-python-headless#1530

  • 修正了 COCO 101 点平均精度算法,以正确插值精度,从而无需平均掉中间值即可更精确地计算平均精度。 #1500

  • 解决了构建文档时突出显示的其他问题。主要包括空格调整和类型不一致。更新了文档以提高清晰度并修复了格式问题。为 mkdocstrings-python 添加了显式版本。 #1549

  • 为代码格式化启用了 Ruff 规则并进行了修复,包括避免不必要的迭代器分配和为默认可变参数使用 Optional 等更改。 #1526

0.23.0 Aug 28, 2024

  • Added #930: IconAnnotator,一个 新 Annotator,允许在每个检测上绘制图标。如果你想为每个类别绘制特定的图标,这个功能会很有用。
import supervision as sv
from inference import get_model

image = <SOURCE_IMAGE_PATH>
icon_dog = <DOG_PNG_PATH>
icon_cat = <CAT_PNG_PATH>

model = get_model(model_id="yolov8n-640")
results = model.infer(image)[0]
detections = sv.Detections.from_inference(results)

icon_paths = []
for class_name in detections.data["class_name"]:
    if class_name == "dog":
        icon_paths.append(icon_dog)
    elif class_name == "cat":
        icon_paths.append(icon_cat)
    else:
        icon_paths.append("")

icon_annotator = sv.IconAnnotator()
annotated_frame = icon_annotator.annotate(
    scene=image.copy(),
    detections=detections,
    icon_path=icon_paths
)
import supervision as sv
from inference import get_model

image = <SOURCE_IMAGE_PATH>

model = get_model(model_id="yolov8n-640")
results = model.infer(image)[0]
detections = sv.Detections.from_inference(results)

background_overlay_annotator = sv.BackgroundOverlayAnnotator()
annotated_frame = background_overlay_annotator.annotate(
    scene=image.copy(),
    detections=detections
)
  • Added #1386: 支持 sv.Detections.from_transformers 中的 Transformers v5 函数。这包括 DetrImageProcessor 的方法 post_process_object_detectionpost_process_panoptic_segmentationpost_process_semantic_segmentationpost_process_instance_segmentation
import torch
import supervision as sv
from PIL import Image
from transformers import DetrImageProcessor, DetrForObjectDetection

processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")

image = Image.open(<SOURCE_IMAGE_PATH>)
inputs = processor(images=image, return_tensors="pt")

with torch.no_grad():
    outputs = model(**inputs)

width, height = image.size
target_size = torch.tensor([[height, width]])
results = processor.post_process_object_detection(
    outputs=outputs, target_sizes=target_size)[0]
detections = sv.Detections.from_transformers(
    transformers_results=results,
    id2label=model.config.id2label)
import supervision as sv
from segment_anything import (
    sam_model_registry,
    SamAutomaticMaskGenerator
)
sam_model_reg = sam_model_registry[MODEL_TYPE]
sam = sam_model_reg(checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
mask_generator = SamAutomaticMaskGenerator(sam)
sam_result = mask_generator.generate(IMAGE)
detections = sv.Detections.from_sam(sam_result=sam_result)
import supervision as sv

for frame in sv.get_video_frames_generator(
    source_path=<SOURCE_VIDEO_PATH>,
    start=60,
    iterative_seek=True
):
    ...
  • Fix #1424: plot_image 函数现在清楚地表明尺寸单位是英寸。

Removed

ByteTrack 中的 track_buffer, track_thresh, 和 match_thresh 参数已被弃用,并已在 supervision-0.23.0 中移除。请使用 lost_track_buffer, track_activation_threshold, 和 minimum_matching_threshold

Removed

sv.PolygonZone 中的 triggering_position 参数已在 supervision-0.23.0 中移除。请使用 triggering_anchors

Deprecated

InferenceSlicer.__init__ 中的 overlap_filter_strategy 已弃用,将在 supervision-0.27.0 中移除。请使用 overlap_strategy

Deprecated

InferenceSlicer.__init__ 中的 overlap_ratio_wh 已弃用,将在 supervision-0.27.0 中移除。请使用 overlap_wh

0.22.0 Jul 12, 2024

Deprecated

使用参数 images 作为 Dict[str, np.ndarray] 来构造 DetectionDataset 已弃用,并将于 supervision-0.26.0 中移除。请改为传递路径列表 List[str]

Deprecated

DetectionDataset.images 属性已弃用,并将于 supervision-0.26.0 中移除。请使用 for path, image, annotation in dataset: 循环加载图像,因为这不需要将所有图像加载到内存中。

import roboflow
from roboflow import Roboflow
import supervision as sv

roboflow.login()
rf = Roboflow()

project = rf.workspace(<WORKSPACE_ID>).project(<PROJECT_ID>)
dataset = project.version(<PROJECT_VERSION>).download("coco")

ds_train = sv.DetectionDataset.from_coco(
    images_directory_path=f"{dataset.location}/train",
    annotations_path=f"{dataset.location}/train/_annotations.coco.json",
)

path, image, annotation = ds_train[0]
    # 按需加载图像

for path, image, annotation in ds_train:
    # 按需加载图像
import supervision as sv
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
import cv2

image = cv2.imread(<SOURCE_IMAGE_PATH>)
cfg = get_cfg()
cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
predictor = DefaultPredictor(cfg)

result = predictor(image)
detections = sv.Detections.from_detectron2(result)

mask_annotator = sv.MaskAnnotator()
annotated_frame = mask_annotator.annotate(scene=image.copy(), detections=detections)
  • Added #1277: 如果您提供支持某种语言符号的字体,sv.RichLabelAnnotator 将在您的图像上绘制它们。
  • 各种其他 Annotator 已经过修改,以确保在使用 numpy 数组时能够正常进行就地操作。此外,我们修复了 sv.ColorAnnotator 在就地使用时用纯色填充框的错误。
import cv2
import supervision as sv
import

image = cv2.imread(<SOURCE_IMAGE_PATH>)

model = get_model(model_id="yolov8n-640")
results = model.infer(image)[0]
detections = sv.Detections.from_inference(results)

rich_label_annotator = sv.RichLabelAnnotator(font_path=<TTF_FONT_PATH>)
annotated_image = rich_label_annotator.annotate(scene=image.copy(), detections=detections)
  • Added #1227: 添加了加载 YOLO 格式的定向边界框数据集的支持。
import supervision as sv

train_ds = sv.DetectionDataset.from_yolo(
    images_directory_path="/content/dataset/train/images",
    annotations_directory_path="/content/dataset/train/labels",
    data_yaml_path="/content/dataset/data.yaml",
    is_obb=True,
)

_, image, detections in train_ds[0]

obb_annotator = OrientedBoxAnnotator()
annotated_image = obb_annotator.annotate(scene=image.copy(), detections=detections)

Removed

移除了 BoxAnnotator,但 BoundingBoxAnnotator 已重命名为 BoxAnnotator。请使用 BoxAnnotatorLabelAnnotator 的组合来模拟旧的 BoundingBox 行为。

Deprecated

BoundingBoxAnnotator 名称已被弃用,将在 supervision-0.26.0 中移除。它已被重命名为 BoxAnnotator

  • Added #975 📝 New Cookbooks: 将检测序列化为 jsoncsv

  • Added #1290: 大部分是内部更改,我们的文件实用函数现在同时支持 strpathlib 路径。

  • Added #1340: 两个新的边界框格式转换方法 - xywh_to_xyxyxcycwh_to_xyxy

Removed

from_roboflow 方法已因弃用而被移除。请改用 from_inference

Removed

Color.white() 已因弃用而被移除。请改用 color.WHITE

Removed

Color.black() 已因弃用而被移除。请改用 color.BLACK

Removed

Color.red() 已因弃用而被移除。请改用 color.RED

Removed

Color.green() 已因弃用而被移除。请改用 color.GREEN

Removed

Color.blue() 已因弃用而被移除。请改用 color.BLUE

Removed

ColorPalette.default() 已因弃用而被移除。请改用 ColorPalette.DEFAULT

Removed

FPSMonitor.__call__ 已因弃用而被移除。请改用属性 FPSMonitor.fps

0.21.0 Jun 5, 2024

import supervision as sv

paligemma_result = "<loc0256><loc0256><loc0768><loc0768> cat"
detections = sv.Detections.from_lmm(
    sv.LMM.PALIGEMMA,
    paligemma_result,
    resolution_wh=(1000, 1000),
    classes=["cat", "dog"],
)
detections.xyxy
# array([[250., 250., 750., 750.]])

detections.class_id
# array([0])
import supervision as sv

image = ...
key_points = sv.KeyPoints(...)

edge_annotator = sv.EdgeAnnotator(
    color=sv.Color.GREEN,
    thickness=5
)
annotated_frame = edge_annotator.annotate(
    scene=image.copy(),
    key_points=key_points
)
import cv2
import numpy as np
import supervision as sv
from inference import get_model

model = get_model(model_id="yolov8x-seg-640")
image = cv2.imread(<SOURCE_IMAGE_PATH>)

def callback(image_slice: np.ndarray) -> sv.Detections:
    results = model.infer(image_slice)[0]
    return sv.Detections.from_inference(results)

slicer = sv.InferenceSlicer(callback = callback)
detections = slicer(image)

mask_annotator = sv.MaskAnnotator()
label_annotator = sv.LabelAnnotator()

annotated_image = mask_annotator.annotate(
    scene=image, detections=detections)
annotated_image = label_annotator.annotate(
    scene=annotated_image, detections=detections)

0.20.0 April 24, 2024

import cv2
import supervision as sv
from ultralytics import YOLO

image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO('yolov8l-pose')

result = model(image, verbose=False)[0]
keypoints = sv.KeyPoints.from_ultralytics(result)

edge_annotators = sv.EdgeAnnotator(color=sv.Color.GREEN, thickness=5)
annotated_image = edge_annotators.annotate(image.copy(), keypoints)
  • Changed #1037: sv.LabelAnnotator 添加了一个额外的 corner_radius 参数,允许圆角化边界框的角落。

  • Changed #1109: sv.PolygonZone 使初始化 sv.PolygonZone 时不再需要 frame_resolution_wh 参数。

Deprecated

sv.PolygonZone 中的 frame_resolution_wh 参数已被弃用,将在 supervision-0.24.0 中移除。

import torch
import supervision as sv
from PIL import Image
from transformers import DetrImageProcessor, DetrForSegmentation

processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50-panoptic")
model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50-panoptic")

image = Image.open(<SOURCE_IMAGE_PATH>)
inputs = processor(images=image, return_tensors="pt")

with torch.no_grad():
    outputs = model(**inputs)

width, height = image.size
target_size = torch.tensor([[height, width]])
results = processor.post_process_segmentation(
    outputs=outputs, target_sizes=target_size)[0]
detections = sv.Detections.from_transformers(results, id2label=model.config.id2label)

mask_annotator = sv.MaskAnnotator()
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER)

annotated_image = mask_annotator.annotate(
    scene=image, detections=detections)
annotated_image = label_annotator.annotate(
    scene=annotated_image, detections=detections)

0.19.0 March 15, 2024

  • Added #818: sv.CSVSink 允许将图像、视频或流推理结果直接保存到 .csv 文件中。
import supervision as sv
from ultralytics import YOLO

model = YOLO(<SOURCE_MODEL_PATH>)
csv_sink = sv.CSVSink(<RESULT_CSV_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)

with csv_sink:
    for frame in frames_generator:
        result = model(frame)[0]
        detections = sv.Detections.from_ultralytics(result)
        csv_sink.append(detections, custom_data={<CUSTOM_LABEL>:<CUSTOM_DATA>})
  • Added #819: sv.JSONSink 允许将图像、视频或流推理结果直接保存到 .json 文件中。
import supervision as sv
from ultralytics import YOLO

model = YOLO(<SOURCE_MODEL_PATH>)
json_sink = sv.JSONSink(<RESULT_JSON_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)

with json_sink:
    for frame in frames_generator:
        result = model(frame)[0]
        detections = sv.Detections.from_ultralytics(result)
        json_sink.append(detections, custom_data={<CUSTOM_LABEL>:<CUSTOM_DATA>})
import cv2
import supervision as sv
from inference import get_model

image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = get_model(model_id="yolov8n-640")

result = model.infer(image)[0]
detections = sv.Detections.from_inference(result)

crop_annotator = sv.CropAnnotator()
annotated_frame = crop_annotator.annotate(
    scene=image.copy(),
    detections=detections
)
  • Changed #827: sv.ByteTrack.reset 允许用户清除跟踪器状态,从而可以连续处理多个视频文件。

  • Changed #802: sv.LineZoneAnnotator 允许使用 display_in_countdisplay_out_count 属性隐藏进/出计数。

  • Changed #787: 更新了 sv.ByteTrack 的输入参数和文档字符串,以提高可读性和易用性。

Deprecated

sv.ByteTrack 中的 track_buffer, track_thresh, 和 match_thresh 参数已被弃用,将在 supervision-0.23.0 中移除。请使用 lost_track_buffer, track_activation_threshold, 和 minimum_matching_threshold

  • Changed #910: sv.PolygonZone 现在接受一个特定边界框锚点列表,这些锚点必须在区域内才能计入检测。此更新标志着与先前要求(当时所有四个边界框角都必须存在)相比的重大改进。用户现在可以指定一个锚点,例如 sv.Position.BOTTOM_CENTER,或任何其他由 List[sv.Position] 定义的锚点组合。

Deprecated

sv.PolygonZone 中的 triggering_position 参数已被弃用,将在 supervision-0.23.0 中移除。请使用 triggering_anchors

  • Changed #875: Annotators 添加了 Pillow 图像支持。所有 supervision Annotators 现在都可以接受 numpy 数组或 Pillow Image 作为图像。它们会自动检测其类型,绘制注释,并以与输入相同的格式返回输出。

  • Fixed #944: sv.DetectionsSmoothersv.Detections 中移除了 tracking_id

0.18.0 Jan 25, 2024

>>> import supervision as sv

>>> image = ...
>>> detections = sv.Detections(...)

>>> percentage_bar_annotator = sv.PercentageBarAnnotator()
>>> annotated_frame = percentage_bar_annotator.annotate(
...     scene=image.copy(),
...     detections=detections
... )
import cv2
import supervision as sv
from ultralytics import YOLO

image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO("yolov8n-obb.pt")

result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)

oriented_box_annotator = sv.OrientedBoxAnnotator()
annotated_frame = oriented_box_annotator.annotate(
    scene=image.copy(),
    detections=detections
)
>>> import supervision as sv

>>> sv.ColorPalette.from_matplotlib('viridis', 5)
ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
  • Changed #770: sv.Detections.from_ultralytics 添加了对 OBB(定向边界框)的支持。

  • Changed #735: sv.LineZone 现在接受一个特定边界锚点的列表,检测需要穿过这些锚点才能被计数。此更新标志着从先前要求(需要所有四个边界框角)的重大改进。用户现在可以指定一个锚点,例如 sv.Position.BOTTOM_CENTER,或 List[sv.Position] 定义的任何其他锚点组合。

  • Changed #756: sv.Colorsv.ColorPalette 访问预定义颜色的方法,从基于函数的实现 (sv.Color.red()) 转换为更直观和惯用的基于属性的方法 (sv.Color.RED)。

Deprecated

sv.ColorPalette.default() 已弃用,将在 supervision-0.22.0 中移除。请改用 sv.ColorPalette.DEFAULT

Deprecated

Detections.from_roboflow() 已弃用,将在 supervision-0.22.0 中移除。请使用 Detections.from_inference

  • Fixed #735: 修复了 sv.LineZone 的功能,使其能够准确地更新对象从任何方向(包括侧面)穿过线条时的计数器。此增强功能支持更精确的跟踪和分析,例如计算道路每条车道的独立进/出计数。

0.17.0 Dec 06, 2023

>>> import supervision as sv

>>> image = ...
>>> detections = sv.Detections(...)

>>> polygon_annotator = sv.PolygonAnnotator()
>>> annotated_frame = polygon_annotator.annotate(
...     scene=image.copy(),
...     detections=detections
... )
  • Added #476: sv.assets 允许下载视频文件,您可以在演示中使用这些文件。
>>> from supervision.assets import download_assets, VideoAssets
>>> download_assets(VideoAssets.VEHICLES)
"vehicles.mp4"

0.16.0 Oct 19, 2023

>>> import supervision as sv

>>> image = ...
>>> detections = sv.Detections(...)

>>> halo_annotator = sv.HaloAnnotator()
>>> annotated_frame = halo_annotator.annotate(
...     scene=image.copy(),
...     detections=detections
... )
  • Added #466: sv.HeatMapAnnotator 允许用热图注释视频。

  • Added #492: sv.DotAnnotator 允许用点注释图像和视频。

  • Added #449: sv.draw_image 允许在给定场景中绘制图像,具有指定的不透明度和尺寸。

  • Added #280: sv.FPSMonitor 用于监视每秒帧数 (FPS) 以评估延迟。

  • Added #454: 🤗 Hugging Face Annotators space

  • Changed #482: sv.LineZone.trigger 现在返回 Tuple[np.ndarray, np.ndarray]。第一个数组指示哪些检测从外部交叉到内部。第二个数组指示哪些检测从内部交叉到外部。

  • Changed #465: 将 Annotator 参数名称从 color_map: str 更改为 color_lookup: ColorLookup 枚举,以提高类型安全性。

  • Changed #426: sv.MaskAnnotator 可实现 2 倍更快的注释。

  • Fixed #477: Poetry 环境定义允许正确的本地安装。

  • Fixed #430: 修复了 sv.ByteTrack 返回 np.array([], dtype=int) 的情况,当 svDetections 为空时。

Deprecated

sv.Detections.from_yolov8sv.Classifications.from_yolov8 已被 sv.Detections.from_ultralyticssv.Classifications.from_ultralytics 取代。

0.15.0 Oct 5, 2023

>>> import supervision as sv

>>> image = ...
>>> detections = sv.Detections(...)

>>> bounding_box_annotator = sv.BoundingBoxAnnotator()
>>> annotated_frame = bounding_box_annotator.annotate(
...     scene=image.copy(),
...     detections=detections
... )

0.14.0 Aug 31, 2023

>>> import cv2
>>> import supervision as sv
>>> from ultralytics import YOLO

>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = YOLO(...)

>>> def callback(image_slice: np.ndarray) -> sv.Detections:
...     result = model(image_slice)[0]
...     return sv.Detections.from_ultralytics(result)

>>> slicer = sv.InferenceSlicer(callback = callback)

>>> detections = slicer(image)

Deprecated

sv.Detections.from_yolov8sv.Classifications.from_yolov8 已被弃用,将在 supervision-0.16.0 版本中移除。

0.13.0 Aug 8, 2023

>>> import supervision as sv
>>> from ultralytics import YOLO

>>> dataset = sv.DetectionDataset.from_yolo(...)

>>> model = YOLO(...)
>>> def callback(image: np.ndarray) -> sv.Detections:
...     result = model(image)[0]
...     return sv.Detections.from_yolov8(result)

>>> mean_average_precision = sv.MeanAveragePrecision.benchmark(
...     dataset = dataset,
...     callback = callback
... )

>>> mean_average_precision.map50_95
0.433

Deprecated

sv.Detections.from_yolov8 已被弃用,将在 supervision-0.15.0 版本中移除。

0.12.0 Jul 24, 2023

Python 3.7. Support Terminated

随着 supervision-0.12.0 版本的发布,我们终止了对 Python 3.7 的官方支持。

>>> import supervision as sv
>>> from ultralytics import YOLO

>>> dataset = sv.DetectionDataset.from_yolo(...)

>>> model = YOLO(...)
>>> def callback(image: np.ndarray) -> sv.Detections:
...     result = model(image)[0]
...     return sv.Detections.from_yolov8(result)

>>> confusion_matrix = sv.ConfusionMatrix.benchmark(
...     dataset = dataset,
...     callback = callback
... )

>>> confusion_matrix.matrix
array([
    [0., 0., 0., 0.],
    [0., 1., 0., 1.],
    [0., 1., 1., 0.],
    [1., 1., 0., 0.]
])

0.11.1 Jun 29, 2023

0.11.0 Jun 28, 2023

>>> import supervision as sv

>>> ds = sv.DetectionDataset.from_coco(
...     images_directory_path='...',
...     annotations_path='...'
... )

>>> ds.as_coco(
...     images_directory_path='...',
...     annotations_path='...'
... )
>>> import supervision as sv

>>> ds_1 = sv.DetectionDataset(...)
>>> len(ds_1)
100
>>> ds_1.classes
['dog', 'person']

>>> ds_2 = sv.DetectionDataset(...)
>>> len(ds_2)
200
>>> ds_2.classes
['cat']

>>> ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
>>> len(ds_merged)
300
>>> ds_merged.classes
['cat', 'dog', 'person']
  • Added #162: 向 sv.get_video_frames_generator 添加了额外的 startend 参数,允许仅为视频的选定部分生成帧。

  • Fix #157: 从 data.yaml 错误加载 YOLO 数据集类名。

0.10.0 Jun 14, 2023

>>> import supervision as sv

>>> cs = sv.ClassificationDataset.from_folder_structure(
...     root_directory_path='...'
... )

>>> cs.as_folder_structure(
...     root_directory_path='...'
... )

0.9.0 Jun 7, 2023

  • Added #118: 能够通过索引、索引列表或切片来选择 sv.Detections。以下示例说明了新的选择方法。
>>> import supervision as sv

>>> detections = sv.Detections(...)
>>> len(detections[0])
1
>>> len(detections[[0, 1]])
2
>>> len(detections[0:2])
2
  • Added #101: 能够使用 sv.Detections.from_yolov8 从 YOLOv8 结果中提取掩码。以下示例说明了如何从 YOLOv8 模型推理结果中提取布尔掩码。

  • Added #122: 能够使用 sv.crop 来裁剪图像。以下示例显示了如何为 sv.Detections 中的每个检测获取单独的裁剪。

  • Added #120: 能够使用 sv.ImageSink 将多个图像方便地保存到目录中。以下示例显示了如何将每十个视频帧保存为单独的图像。

>>> import supervision as sv

>>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:
...     for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=10):
...         sink.save_image(image=image)
  • Fixed #106: 修复了 sv.PolygonZone 坐标处理不方便的问题。现在 sv.PolygonZone 接受 [[x1, y1], [x2, y2], ...] 形式的坐标,可以是整数或浮点数。

0.8.0 May 17, 2023

  • Added #100: 支持数据集继承。当前的 Dataset 已重命名为 DetectionDataset。现在 DetectionDataset 继承自 BaseDataset。此更改是为了强制未来不同类型计算机视觉数据集 API 的一致性。
  • Added #100: 能够使用 DetectionDataset.as_yolo 将数据集保存为 YOLO 格式。
>>> import roboflow
>>> from roboflow import Roboflow
>>> import supervision as sv

>>> roboflow.login()

>>> rf = Roboflow()

>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("yolov5")

>>> ds = sv.DetectionDataset.from_yolo(
...     images_directory_path=f"{dataset.location}/train/images",
...     annotations_directory_path=f"{dataset.location}/train/labels",
...     data_yaml_path=f"{dataset.location}/data.yaml"
... )

>>> ds.classes
['dog', 'person']
>>> import supervision as sv

>>> ds = sv.DetectionDataset(...)
>>> train_ds, test_ds = ds.split(split_ratio=0.7, random_state=42, shuffle=True)

>>> len(train_ds), len(test_ds)
(700, 300)
  • Changed #100: DetectionDataset.as_yoloDetectionDataset.as_pascal_vocapproximation_percentage 参数的默认值从 0.75 更改为 0.0

0.7.0 May 11, 2023

  • Added #91: Detections.from_yolo_nas 以实现与 YOLO-NAS 模型的无缝集成。
  • Added #86: 能够使用 Dataset.from_yolo 以 YOLO 格式加载数据集。
  • Added #84: Detections.merge 用于将多个 Detections 对象合并在一起。
  • Fixed #81: LineZoneAnnotator.annotate 未返回带注释的帧。
  • Changed #44: LineZoneAnnotator.annotate 以允许自定义进出标签文本。

0.6.0 April 19, 2023

  • Added #71: 初始 Dataset 支持以及将 Detections 保存为 Pascal VOC XML 格式的能力。
  • Added #71: 新的 mask_to_polygons, filter_polygons_by_area, polygon_to_xyxyapproximate_polygon 工具。
  • Added #72: 能够将 Pascal VOC XML 对象检测 数据集加载为 Dataset
  • Changed #70: Detections 属性的顺序,以使其与 __iter__ 元组中的对象顺序一致。
  • Changed #71: generate_2d_mask 改为 polygon_to_mask

0.5.2 April 13, 2023

  • Fixed #63: LineZone.trigger 函数期望 4 个值而不是 5 个。

0.5.1 April 12, 2023

  • Fixed Detections.__getitem__ 方法未返回选定项目的掩码。
  • Fixed Detections.area 因掩码检测而崩溃。

0.5.0 April 10, 2023

  • Added #58: Detections.mask 以支持分割。
  • Added #58: MaskAnnotator 以允许轻松注释 Detections.mask
  • Added #58: Detections.from_sam 以支持原生的 Segment Anything Model (SAM)。
  • Changed #58: Detections.area 的行为,使其不仅可以处理边界框,还可以处理掩码。

0.4.0 April 5, 2023

  • Added #46: Detections.empty 以允许轻松创建空的 Detections 对象。
  • Added #56: Detections.from_roboflow 以允许从 Roboflow API 推理结果轻松创建 Detections 对象。
  • Added #56: plot_images_grid 以允许轻松地将多个图像绘制在单个图上。
  • Added #56: 使用 detections_to_voc_xml 方法对 Pascal VOC XML 格式的初始支持。
  • Changed #56: 将 show_frame_in_notebook 重构并重命名为 plot_image

0.3.2 March 23, 2023

  • Changed #50: 允许 Detections.class_idNone

0.3.1 March 6, 2023

  • Fixed #41: PolygonZone 在对象接触图像底部边缘时抛出异常。
  • Fixed #42: Detections.wth_nms 方法在 Detections 为空时抛出异常。
  • Changed #36: Detections.wth_nms 支持类别无关和非类别无关情况。

0.3.0 March 6, 2023

  • Changed: 允许 Detections.confidenceNone
  • Added: Detections.from_transformersDetections.from_detectron2 以启用与 Transformers 和 Detectron2 模型的无缝集成。
  • Added: Detections.area 以动态计算边界框面积。
  • Added: Detections.wth_nms 以使用 NMS 过滤掉重复检测。初始实现为类别无关。

0.2.0 Feb 2, 2023

  • Added: 高级的 Detections 过滤,使用类似 pandas 的 API。
  • Added: Detections.from_yolov5Detections.from_yolov8 以实现与 YOLOv5 和 YOLOv8 模型的无缝集成。

0.1.0 Jan 19, 2023

欢迎 Supervision 👋