Skip to content

Changelog

0.16.0 October 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 allowing to annotate videos with heat maps.

  • Added #492: sv.DotAnnotator allowing to annotate images and videos with dots.

  • Added #449: sv.draw_image allowing to draw an image onto a given scene with specified opacity and dimensions.

  • Added #280: sv.FPSMonitor for monitoring frames per second (FPS) to benchmark latency.

  • Added #454: 🤗 Hugging Face Annotators space.

  • Changed #482: sv.LineZone.tigger now return Tuple[np.ndarray, np.ndarray]. The first array indicates which detections have crossed the line from outside to inside. The second array indicates which detections have crossed the line from inside to outside.

  • Changed #465: Annotator argument name from color_map: str to color_lookup: ColorLookup enum to increase type safety.

  • Changed #426: sv.MaskAnnotator allowing 2x faster annotation.

  • Fixed #477: Poetry env definition allowing proper local installation.

  • Fixed #430: sv.ByteTrack to return np.array([], dtype=int) when svDetections is empty.

Warning

sv.Detections.from_yolov8 and sv.Classifications.from_yolov8 as those are now replaced by sv.Detections.from_ultralytics and sv.Classifications.from_ultralytics.

0.15.0 October 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 August 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)

Warning

sv.Detections.from_yolov8 and sv.Classifications.from_yolov8 are now deprecated and will be removed with supervision-0.16.0 release.

0.13.0 August 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

Warning

sv.Detections.from_yolov8 is now deprecated and will be removed with supervision-0.15.0 release.

0.12.0 July 24, 2023

Warning

With the supervision-0.12.0 release, we are terminating official support for 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 June 29, 2023

0.11.0 June 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: additional start and end arguments to sv.get_video_frames_generator allowing to generate frames only for a selected part of the video.

  • Fix #157: incorrect loading of YOLO dataset class names from data.yaml.

0.10.0 June 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 June 7, 2023

  • Added #118: ability to select sv.Detections by index, list of indexes or slice. Here is an example illustrating the new selection methods.
>>> import supervision as sv

>>> detections = sv.Detections(...)
>>> len(detections[0])
1
>>> len(detections[[0, 1]])
2
>>> len(detections[0:2])
2
  • Added #101: ability to extract masks from YOLOv8 result using sv.Detections.from_yolov8. Here is an example illustrating how to extract boolean masks from the result of the YOLOv8 model inference.

  • Added #122: ability to crop image using sv.crop. Here is an example showing how to get a separate crop for each detection in sv.Detections.

  • Added #120: ability to conveniently save multiple images into directory using sv.ImageSink. Here is an example showing how to save every tenth video frame as a separate image.

>>> 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: inconvenient handling of sv.PolygonZone coordinates. Now sv.PolygonZone accepts coordinates in the form of [[x1, y1], [x2, y2], ...] that can be both integers and floats.

0.8.0 May 17, 2023

  • Added #100: support for dataset inheritance. The current Dataset got renamed to DetectionDataset. Now DetectionDataset inherits from BaseDataset. This change was made to enforce the future consistency of APIs of different types of computer vision datasets.
  • Added #100: ability to save datasets in YOLO format using DetectionDataset.as_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: default value of approximation_percentage parameter from 0.75 to 0.0 in DetectionDataset.as_yolo and DetectionDataset.as_pascal_voc.

0.7.0 May 11, 2023

  • Added #91: Detections.from_yolo_nas to enable seamless integration with YOLO-NAS model.
  • Added #86: ability to load datasets in YOLO format using Dataset.from_yolo.
  • Added #84: Detections.merge to merge multiple Detections objects together.
  • Fixed #81: LineZoneAnnotator.annotate does not return annotated frame.
  • Changed #44: LineZoneAnnotator.annotate to allow for custom text for the in and out tags.

0.6.0 April 19, 2023

  • Added #71: initial Dataset support and ability to save Detections in Pascal VOC XML format.
  • Added #71: new mask_to_polygons, filter_polygons_by_area, polygon_to_xyxy and approximate_polygon utilities.
  • Added #72: ability to load Pascal VOC XML object detections dataset as Dataset.
  • Changed #70: order of Detections attributes to make it consistent with order of objects in __iter__ tuple.
  • Changed #71: generate_2d_mask to polygon_to_mask.

0.5.2 April 13, 2023

  • Fixed #63: LineZone.trigger function expects 4 values instead of 5.

0.5.1 April 12, 2023

  • Fixed Detections.__getitem__ method did not return mask for selected item.
  • Fixed Detections.area crashed for mask detections.

0.5.0 April 10, 2023

  • Added #58: Detections.mask to enable segmentation support.
  • Added #58: MaskAnnotator to allow easy Detections.mask annotation.
  • Added #58: Detections.from_sam to enable native Segment Anything Model (SAM) support.
  • Changed #58: Detections.area behaviour to work not only with boxes but also with masks.

0.4.0 April 5, 2023

  • Added #46: Detections.empty to allow easy creation of empty Detections objects.
  • Added #56: Detections.from_roboflow to allow easy creation of Detections objects from Roboflow API inference results.
  • Added #56: plot_images_grid to allow easy plotting of multiple images on single plot.
  • Added #56: initial support for Pascal VOC XML format with detections_to_voc_xml method.
  • Changed #56: show_frame_in_notebook refactored and renamed to plot_image.

0.3.2 March 23, 2023

  • Changed #50: Allow Detections.class_id to be None.

0.3.1 March 6, 2023

  • Fixed #41: PolygonZone throws an exception when the object touches the bottom edge of the image.
  • Fixed #42: Detections.wth_nms method throws an exception when Detections is empty.
  • Changed #36: Detections.wth_nms support class agnostic and non-class agnostic case.

0.3.0 March 6, 2023

  • Changed: Allow Detections.confidence to be None.
  • Added: Detections.from_transformers and Detections.from_detectron2 to enable seamless integration with Transformers and Detectron2 models.
  • Added: Detections.area to dynamically calculate bounding box area.
  • Added: Detections.wth_nms to filter out double detections with NMS. Initial - only class agnostic - implementation.

0.2.0 February 2, 2023

  • Added: Advanced Detections filtering with pandas-like API.
  • Added: Detections.from_yolov5 and Detections.from_yolov8 to enable seamless integration with YOLOv5 and YOLOv8 models.

0.1.0 January 19, 2023

Say hello to Supervision 👋