diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/404.html b/404.html new file mode 100644 index 000000000..4cfde4cdb --- /dev/null +++ b/404.html @@ -0,0 +1,838 @@ + + + +
+ + + + + + + + + + + + + + + + + +sv.ClassificationDataset
in a folder structure format.>>> import supervision as sv
+
+>>> cs = sv.ClassificationDataset.from_folder_structure(
+... root_directory_path='...'
+... )
+
+>>> cs.as_folder_structure(
+... root_directory_path='...'
+... )
+
Added [#125]: support for sv.ClassificationDataset.split
allowing to divide sv.ClassificationDataset
into two parts.
Added [#110]: ability to extract masks from Roboflow API results using sv.Detections.from_roboflow
.
Added [commit hash]: Supervision Quickstart notebook where you can learn more about Detection, Dataset and Video APIs.
+Changed [#135]: sv.get_video_frames_generator
documentation to better describe actual behavior.
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)
+
sv.PolygonZone
coordinates. Now sv.PolygonZone
accepts coordinates in the form of [[x1, y1], [x2, y2], ...]
that can be both integers and floats.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.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']
+
DetectionDataset.split
allowing to divide DetectionDataset
into two parts. >>> 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)
+
approximation_percentage
parameter from 0.75
to 0.0
in DetectionDataset.as_yolo
and DetectionDataset.as_pascal_voc
.Detections.from_yolo_nas
to enable seamless integration with YOLO-NAS model.Dataset.from_yolo
. Detections.merge
to merge multiple Detections
objects together.LineZoneAnnotator.annotate
does not return annotated frame.LineZoneAnnotator.annotate
to allow for custom text for the in and out tags.Dataset
support and ability to save Detections
in Pascal VOC XML format. mask_to_polygons
, filter_polygons_by_area
, polygon_to_xyxy
and approximate_polygon
utilities.Dataset
.Detections
attributes to make it consistent with order of objects in __iter__
tuple.generate_2d_mask
to polygon_to_mask
.LineZone.trigger
function expects 4 values instead of 5.Detections.__getitem__
method did not return mask for selected item.Detections.area
crashed for mask detections.Detections.mask
to enable segmentation support.MaskAnnotator
to allow easy Detections.mask
annotation.Detections.from_sam
to enable native Segment Anything Model (SAM) support.Detections.area
behaviour to work not only with boxes but also with masks.Detections.empty
to allow easy creation of empty Detections
objects.Detections.from_roboflow
to allow easy creation of Detections
objects from Roboflow API inference results.plot_images_grid
to allow easy plotting of multiple images on single plot.detections_to_voc_xml
method.show_frame_in_notebook
refactored and renamed to plot_image
.Detections.class_id
to be None
. PolygonZone
throws an exception when the object touches the bottom edge of the image.Detections.wth_nms
method throws an exception when Detections
is empty.Detections.wth_nms
support class agnostic and non-class agnostic case.Detections.confidence
to be None
.Detections.from_transformers
and Detections.from_detectron2
to enable seamless integration with Transformers and Detectron2 models. Detections.area
to dynamically calculate bounding box area.Detections.wth_nms
to filter out double detections with NMS. Initial - only class agnostic - implementation. Detections
filtering with pandas-like API.Detections.from_yolov5
and Detections.from_yolov8
to enable seamless integration with YOLOv5 and YOLOv8 models.Say hello to Supervision 👋
+ + + + + + + + +supervision/classification/core.py
28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 |
|
__post_init__()
+
+¶Validate the classification inputs.
+ +supervision/classification/core.py
33 +34 +35 +36 +37 +38 +39 +40 |
|
from_yolov8(yolov8_results)
+
+
+ classmethod
+
+
+¶Creates a Classifications instance from a YOLOv8 inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
yolov8_results |
+
+ ultralytics.yolo.engine.results.Results
+ |
+
+
+
+ The output Results instance from YOLOv8 + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Classifications
+ |
+
+
+
+ A new Classifications object. + |
+
>>> import cv2
+>>> from ultralytics import YOLO
+>>> import supervision as sv
+
+>>> image = cv2.imread(SOURCE_IMAGE_PATH)
+>>> model = YOLO('yolov8s-cls.pt')
+>>> result = model(image)[0]
+>>> classifications = sv.Classifications.from_yolov8(result)
+
supervision/classification/core.py
42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 |
|
get_top_k(k)
+
+¶Retrieve the top k class IDs and confidences, ordered in descending order by confidence.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
k |
+
+ int
+ |
+
+
+
+ The number of top class IDs and confidences to retrieve. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ Tuple[np.ndarray, np.ndarray]
+ |
+
+
+
+ Tuple[np.ndarray, np.ndarray]: A tuple containing the top k class IDs and confidences. + |
+
>>> import supervision as sv
+
+>>> classifications = sv.Classifications(...)
+
+>>> classifications.get_top_k(1)
+
+(array([1]), array([0.9]))
+
supervision/classification/core.py
68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 |
|
Warning
+Dataset API is still fluid and may change. If you use Dataset API in your project until further notice, freeze the
+supervision
version in your requirements.txt
or setup.py
.
+ Bases: BaseDataset
Dataclass containing information about object detection dataset.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
classes |
+
+ List[str]
+ |
+
+
+
+ List containing dataset class names. + |
+
images |
+
+ Dict[str, np.ndarray]
+ |
+
+
+
+ Dictionary mapping image name to image. + |
+
annotations |
+
+ Dict[str, Detections]
+ |
+
+
+
+ Dictionary mapping image name to annotations. + |
+
supervision/dataset/core.py
44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 |
|
__iter__()
+
+¶Iterate over the images and annotations in the dataset.
+ +Yields:
+Type | +Description | +
---|---|
+ str
+ |
+
+
+
+ Iterator[Tuple[str, np.ndarray, Detections]]: An iterator that yields tuples containing the image name, + the image data, and its corresponding annotation. + |
+
supervision/dataset/core.py
68 +69 +70 +71 +72 +73 +74 +75 +76 +77 |
|
__len__()
+
+¶Return the number of images in the dataset.
+ +Returns:
+Name | Type | +Description | +
---|---|---|
int |
+ int
+ |
+
+
+
+ The number of images. + |
+
supervision/dataset/core.py
59 +60 +61 +62 +63 +64 +65 +66 |
|
as_coco(images_directory_path=None, annotations_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0, licenses=None, info=None)
+
+¶Exports the dataset to COCO format. This method saves the images and their corresponding +annotations in COCO format, which is a simple json file that describes an object in the image. +Annotation json file also include category maps.
+The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the images should be saved. +If not provided, images will not be saved. + |
+
+ None
+ |
+
annotations_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the annotations in +YOLO format should be saved. If not provided, annotations will not be saved. + |
+ + required + | +
min_image_area_percentage |
+
+ float
+ |
+
+
+
+ The minimum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 0.0
+ |
+
max_image_area_percentage |
+
+ float
+ |
+
+
+
+ The maximum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 1.0
+ |
+
approximation_percentage |
+
+ float
+ |
+
+
+
+ The percentage of polygon points to be removed from the input polygon, +in the range [0, 1). This is useful for simplifying the annotations. + |
+
+ 0.0
+ |
+
licenses |
+
+ Optional[str]
+ |
+
+
+
+ List of licenses for images + |
+
+ None
+ |
+
info |
+
+ Optional[dict]
+ |
+
+
+
+ Information of Dataset as dictionary + |
+
+ None
+ |
+
supervision/dataset/core.py
387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 |
|
as_pascal_voc(images_directory_path=None, annotations_directory_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0)
+
+¶Exports the dataset to PASCAL VOC format. This method saves the images and their corresponding annotations in +PASCAL VOC format, which consists of XML files. The method allows filtering the detections based on their area +percentage.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the images should be saved. +If not provided, images will not be saved. + |
+
+ None
+ |
+
annotations_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the annotations in +PASCAL VOC format should be saved. If not provided, annotations will not be saved. + |
+
+ None
+ |
+
min_image_area_percentage |
+
+ float
+ |
+
+
+
+ The minimum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 0.0
+ |
+
max_image_area_percentage |
+
+ float
+ |
+
+
+
+ The maximum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 1.0
+ |
+
approximation_percentage |
+
+ float
+ |
+
+
+
+ The percentage of polygon points to be removed from the input polygon, in the range [0, 1). + |
+
+ 0.0
+ |
+
supervision/dataset/core.py
124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 |
|
as_yolo(images_directory_path=None, annotations_directory_path=None, data_yaml_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0)
+
+¶Exports the dataset to YOLO format. This method saves the images and their corresponding +annotations in YOLO format, which is a simple text file that describes an object in the image. It also allows +for the optional saving of a data.yaml file, used in YOLOv5, that contains metadata about the dataset.
+The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the images should be saved. +If not provided, images will not be saved. + |
+
+ None
+ |
+
annotations_directory_path |
+
+ Optional[str]
+ |
+
+
+
+ The path to the directory where the annotations in +YOLO format should be saved. If not provided, annotations will not be saved. + |
+
+ None
+ |
+
data_yaml_path |
+
+ Optional[str]
+ |
+
+
+
+ The path where the data.yaml file should be saved. +If not provided, the file will not be saved. + |
+
+ None
+ |
+
min_image_area_percentage |
+
+ float
+ |
+
+
+
+ The minimum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 0.0
+ |
+
max_image_area_percentage |
+
+ float
+ |
+
+
+
+ The maximum percentage of detection area relative to +the image area for a detection to be included. + |
+
+ 1.0
+ |
+
approximation_percentage |
+
+ float
+ |
+
+
+
+ The percentage of polygon points to be removed from the input polygon, +in the range [0, 1). This is useful for simplifying the annotations. + |
+
+ 0.0
+ |
+
supervision/dataset/core.py
294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 |
|
from_coco(images_directory_path, annotations_path, force_masks=False)
+
+
+ classmethod
+
+
+¶Creates a Dataset instance from YOLO formatted data.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory containing the images. + |
+ + required + | +
annotations_path |
+
+ str
+ |
+
+
+
+ The path to the json annotation files. + |
+ + required + | +
force_masks |
+
+ bool
+ |
+
+
+
+ If True, forces masks to be loaded for all annotations, regardless of whether they are present. + |
+
+ False
+ |
+
Returns:
+Name | Type | +Description | +
---|---|---|
DetectionDataset |
+ DetectionDataset
+ |
+
+
+
+ A DetectionDataset instance containing the loaded images and annotations. + |
+
>>> 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 = sv.DetectionDataset.from_coco(
+... images_directory_path=f"{dataset.location}/train",
+... annotations_path=f"{dataset.location}/train/_annotations.coco.json",
+... )
+
+>>> ds.classes
+['dog', 'person']
+
supervision/dataset/core.py
340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 |
|
from_pascal_voc(images_directory_path, annotations_directory_path)
+
+
+ classmethod
+
+
+¶Creates a Dataset instance from PASCAL VOC formatted data.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory containing the images. + |
+ + required + | +
annotations_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory containing the PASCAL VOC XML annotations. + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
DetectionDataset |
+ DetectionDataset
+ |
+
+
+
+ A DetectionDataset instance containing the loaded images and annotations. + |
+
>>> 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("voc")
+
+>>> ds = sv.DetectionDataset.from_yolo(
+... images_directory_path=f"{dataset.location}/train/images",
+... annotations_directory_path=f"{dataset.location}/train/labels"
+... )
+
+>>> ds.classes
+['dog', 'person']
+
supervision/dataset/core.py
177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 |
|
from_yolo(images_directory_path, annotations_directory_path, data_yaml_path, force_masks=False)
+
+
+ classmethod
+
+
+¶Creates a Dataset instance from YOLO formatted data.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory containing the images. + |
+ + required + | +
annotations_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory containing the YOLO annotation files. + |
+ + required + | +
data_yaml_path |
+
+ str
+ |
+
+
+
+ The path to the data YAML file containing class information. + |
+ + required + | +
force_masks |
+
+ bool
+ |
+
+
+
+ If True, forces masks to be loaded for all annotations, regardless of whether they are present. + |
+
+ False
+ |
+
Returns:
+Name | Type | +Description | +
---|---|---|
DetectionDataset |
+ DetectionDataset
+ |
+
+
+
+ A DetectionDataset instance containing the loaded images and annotations. + |
+
>>> 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']
+
supervision/dataset/core.py
243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 |
|
split(split_ratio=0.8, random_state=None, shuffle=True)
+
+¶Splits the dataset into two parts (training and testing) using the provided split_ratio.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
split_ratio |
+
+ float
+ |
+
+
+
+ The ratio of the training set to the entire dataset. + |
+
+ 0.8
+ |
+
random_state |
+
+ int
+ |
+
+
+
+ The seed for the random number generator. This is used for reproducibility. + |
+
+ None
+ |
+
shuffle |
+
+ bool
+ |
+
+
+
+ Whether to shuffle the data before splitting. + |
+
+ True
+ |
+
Returns:
+Type | +Description | +
---|---|
+ Tuple[DetectionDataset, DetectionDataset]
+ |
+
+
+
+ Tuple[DetectionDataset, DetectionDataset]: A tuple containing the training and testing datasets. + |
+
>>> 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)
+
supervision/dataset/core.py
79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 |
|
+ Bases: BaseDataset
Dataclass containing information about a classification dataset.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
classes |
+
+ List[str]
+ |
+
+
+
+ List containing dataset class names. + |
+
images |
+
+ Dict[str, np.ndarray]
+ |
+
+
+
+ Dictionary mapping image name to image. + |
+
annotations |
+
+ Dict[str, Detections]
+ |
+
+
+
+ Dictionary mapping image name to annotations. + |
+
supervision/dataset/core.py
436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 |
|
as_folder_structure(root_directory_path)
+
+¶Saves the dataset as a multi-class folder structure.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
root_directory_path |
+
+ str
+ |
+
+
+
+ The path to the directory where the dataset will be saved. + |
+ + required + | +
supervision/dataset/core.py
498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 |
|
from_folder_structure(root_directory_path)
+
+
+ classmethod
+
+
+¶Load data from a multiclass folder structure into a ClassificationDataset.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
root_directory_path |
+
+ str
+ |
+
+
+
+ The path to the dataset directory. + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
ClassificationDataset |
+ ClassificationDataset
+ |
+
+
+
+ The 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("folder")
+
+>>> cd = sv.ClassificationDataset.from_folder_structure(
+... root_directory_path=f"{dataset.location}/train"
+... )
+
supervision/dataset/core.py
522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 |
|
split(split_ratio=0.8, random_state=None, shuffle=True)
+
+¶Splits the dataset into two parts (training and testing) using the provided split_ratio.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
split_ratio |
+
+ float
+ |
+
+
+
+ The ratio of the training set to the entire dataset. + |
+
+ 0.8
+ |
+
random_state |
+
+ int
+ |
+
+
+
+ The seed for the random number generator. This is used for reproducibility. + |
+
+ None
+ |
+
shuffle |
+
+ bool
+ |
+
+
+
+ Whether to shuffle the data before splitting. + |
+
+ True
+ |
+
Returns:
+Type | +Description | +
---|---|
+ Tuple[ClassificationDataset, ClassificationDataset]
+ |
+
+
+
+ Tuple[ClassificationDataset, ClassificationDataset]: A tuple containing the training and testing datasets. + |
+
>>> import supervision as sv
+
+>>> cd = sv.ClassificationDataset(...)
+>>> train_cd, test_cd = cd.split(split_ratio=0.7, random_state=42, shuffle=True)
+>>> len(train_cd), len(test_cd)
+(700, 300)
+
supervision/dataset/core.py
454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 |
|
A class for drawing bounding boxes on an image using detections provided.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
color |
+
+ Union[Color, ColorPalette]
+ |
+
+
+
+ The color to draw the bounding box, can be a single color or a color palette + |
+
thickness |
+
+ int
+ |
+
+
+
+ The thickness of the bounding box lines, default is 2 + |
+
text_color |
+
+ Color
+ |
+
+
+
+ The color of the text on the bounding box, default is white + |
+
text_scale |
+
+ float
+ |
+
+
+
+ The scale of the text on the bounding box, default is 0.5 + |
+
text_thickness |
+
+ int
+ |
+
+
+
+ The thickness of the text on the bounding box, default is 1 + |
+
text_padding |
+
+ int
+ |
+
+
+
+ The padding around the text on the bounding box, default is 5 + |
+
supervision/detection/annotate.py
10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 |
|
annotate(scene, detections, labels=None, skip_label=False)
+
+¶Draws bounding boxes on the frame using the detections provided.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The image on which the bounding boxes will be drawn + |
+ + required + | +
detections |
+
+ Detections
+ |
+
+
+
+ The detections for which the bounding boxes will be drawn + |
+ + required + | +
labels |
+
+ Optional[List[str]]
+ |
+
+
+
+ An optional list of labels corresponding to each detection. If |
+
+ None
+ |
+
skip_label |
+
+ bool
+ |
+
+
+
+ Is set to |
+
+ False
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The image with the bounding boxes drawn on it + |
+
>>> import supervision as sv
+
+>>> classes = ['person', ...]
+>>> image = ...
+>>> detections = sv.Detections(...)
+
+>>> box_annotator = sv.BoxAnnotator()
+>>> labels = [
+... f"{classes[class_id]} {confidence:0.2f}"
+... for _, _, confidence, class_id, _
+... in detections
+... ]
+>>> annotated_frame = box_annotator.annotate(
+... scene=image.copy(),
+... detections=detections,
+... labels=labels
+... )
+
supervision/detection/annotate.py
40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 |
|
A class for overlaying masks on an image using detections provided.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
color |
+
+ Union[Color, ColorPalette]
+ |
+
+
+
+ The color to fill the mask, can be a single color or a color palette + |
+
supervision/detection/annotate.py
143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 |
|
annotate(scene, detections, opacity=0.5)
+
+¶Overlays the masks on the given image based on the provided detections, with a specified opacity.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The image on which the masks will be overlaid + |
+ + required + | +
detections |
+
+ Detections
+ |
+
+
+
+ The detections for which the masks will be overlaid + |
+ + required + | +
opacity |
+
+ float
+ |
+
+
+
+ The opacity of the masks, between 0 and 1, default is 0.5 + |
+
+ 0.5
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The image with the masks overlaid + |
+
supervision/detection/annotate.py
157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 |
|
Data class containing information about the detections in a video frame.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
xyxy |
+
+ np.ndarray
+ |
+
+
+
+ An array of shape |
+
mask |
+
+ np.Optional[np.ndarray]
+ |
+
+
+
+ (Optional[np.ndarray]): An array of shape |
+
confidence |
+
+ Optional[np.ndarray]
+ |
+
+
+
+ An array of shape |
+
class_id |
+
+ Optional[np.ndarray]
+ |
+
+
+
+ An array of shape |
+
tracker_id |
+
+ Optional[np.ndarray]
+ |
+
+
+
+ An array of shape |
+
supervision/detection/core.py
57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 |
|
area: np.ndarray
+
+
+ property
+
+
+¶Calculate the area of each detection in the set of object detections. If masks field is defined property +returns are of each mask. If only box is given property return area of each box.
+ +Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: An array of floats containing the area of each detection in the format of |
+
box_area: np.ndarray
+
+
+ property
+
+
+¶Calculate the area of each bounding box in the set of object detections.
+ +Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: An array of floats containing the area of each bounding box in the format of |
+
__getitem__(index)
+
+¶Get a subset of the Detections object.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
index |
+
+ Union[int, slice, List[int], np.ndarray]
+ |
+
+
+
+ The index or indices of the subset of the Detections + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ Detections
+ |
+
+
+
+ A subset of the Detections object. + |
+
>>> import supervision as sv
+
+>>> detections = sv.Detections(...)
+
+>>> first_detection = detections[0]
+
+>>> first_10_detections = detections[0:10]
+
+>>> some_detections = detections[[0, 2, 4]]
+
+>>> class_0_detections = detections[detections.class_id == 0]
+
+>>> high_confidence_detections = detections[detections.confidence > 0.5]
+
supervision/detection/core.py
452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 |
|
__iter__()
+
+¶Iterates over the Detections object and yield a tuple of (xyxy, mask, confidence, class_id, tracker_id)
for each detection.
supervision/detection/core.py
89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 |
|
__len__()
+
+¶Returns the number of detections in the Detections object.
+ +supervision/detection/core.py
83 +84 +85 +86 +87 |
|
empty()
+
+
+ classmethod
+
+
+¶Create an empty Detections object with no bounding boxes, confidences, or class IDs.
+ +Returns:
+Type | +Description | +
---|---|
+ Detections
+ |
+
+
+
+ An empty Detections object. + |
+
>>> from supervision import Detections
+
+>>> empty_detections = Detections.empty()
+
supervision/detection/core.py
358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 |
|
from_detectron2(detectron2_results)
+
+
+ classmethod
+
+
+¶Create a Detections object from the Detectron2 inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
detectron2_results |
+ + | +
+
+
+ The output of a Detectron2 model containing instances with prediction data. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ Detections
+ |
+
+
+
+ A Detections object containing the bounding boxes, class IDs, and confidences of the predictions. + |
+
>>> import cv2
+>>> from detectron2.engine import DefaultPredictor
+>>> from detectron2.config import get_cfg
+>>> import supervision as sv
+
+>>> image = cv2.imread(SOURCE_IMAGE_PATH)
+>>> cfg = get_cfg()
+>>> cfg.merge_from_file("path/to/config.yaml")
+>>> cfg.MODEL.WEIGHTS = "path/to/model_weights.pth"
+>>> predictor = DefaultPredictor(cfg)
+>>> result = predictor(image)
+
+>>> detections = sv.Detections.from_detectron2(result)
+
supervision/detection/core.py
246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 |
|
from_roboflow(roboflow_result, class_list)
+
+
+ classmethod
+
+
+¶Create a Detections object from the Roboflow API inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
roboflow_result |
+
+ dict
+ |
+
+
+
+ The result from the Roboflow API containing predictions. + |
+ + required + | +
class_list |
+
+ List[str]
+ |
+
+
+
+ A list of class names corresponding to the class IDs in the API result. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ Detections
+ |
+
+
+
+ A Detections object containing the bounding boxes, class IDs, and confidences of the predictions. + |
+
>>> import supervision as sv
+
+>>> roboflow_result = {
+... "predictions": [
+... {
+... "x": 0.5,
+... "y": 0.5,
+... "width": 0.2,
+... "height": 0.3,
+... "class": "person",
+... "confidence": 0.9
+... },
+... # ... more predictions ...
+... ]
+... }
+>>> class_list = ["person", "car", "dog"]
+
+>>> detections = sv.Detections.from_roboflow(roboflow_result, class_list)
+
supervision/detection/core.py
283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 |
|
from_sam(sam_result)
+
+
+ classmethod
+
+
+¶Creates a Detections instance from Segment Anything Model inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
sam_result |
+
+ List[dict]
+ |
+
+
+
+ The output Results instance from SAM + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object. + |
+
>>> import supervision as sv
+>>> from segment_anything import sam_model_registry, SamAutomaticMaskGenerator
+
+>>> sam = sam_model_registry[MODEL_TYPE](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)
+
supervision/detection/core.py
327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 |
|
from_transformers(transformers_results)
+
+
+ classmethod
+
+
+¶Creates a Detections instance from object detection transformer inference result.
+ +Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object. + |
+
supervision/detection/core.py
232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 |
|
from_yolo_nas(yolo_nas_results)
+
+
+ classmethod
+
+
+¶Creates a Detections instance from a YOLO-NAS inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
yolo_nas_results |
+
+ super_gradients.training.models.prediction_results.ImageDetectionPrediction
+ |
+
+
+
+ The output Results instance from YOLO-NAS + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object. + |
+
>>> import cv2
+>>> from super_gradients.training import models
+>>> import supervision as sv
+
+>>> image = cv2.imread(SOURCE_IMAGE_PATH)
+>>> model = models.get('yolo_nas_l', pretrained_weights="coco")
+>>> result = list(model.predict(image, conf=0.35))[0]
+>>> detections = sv.Detections.from_yolo_nas(result)
+
supervision/detection/core.py
203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 |
|
from_yolov5(yolov5_results)
+
+
+ classmethod
+
+
+¶Creates a Detections instance from a YOLOv5 inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
yolov5_results |
+
+ yolov5.models.common.Detections
+ |
+
+
+
+ The output Detections instance from YOLOv5 + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object. + |
+
>>> import cv2
+>>> import torch
+>>> import supervision as sv
+
+>>> image = cv2.imread(SOURCE_IMAGE_PATH)
+>>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
+>>> result = model(image)
+>>> detections = sv.Detections.from_yolov5(result)
+
supervision/detection/core.py
143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 |
|
from_yolov8(yolov8_results)
+
+
+ classmethod
+
+
+¶Creates a Detections instance from a YOLOv8 inference result.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
yolov8_results |
+
+ ultralytics.yolo.engine.results.Results
+ |
+
+
+
+ The output Results instance from YOLOv8 + |
+ + required + | +
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object. + |
+
>>> import cv2
+>>> from ultralytics import YOLO
+>>> import supervision as sv
+
+>>> image = cv2.imread(SOURCE_IMAGE_PATH)
+>>> model = YOLO('yolov8s.pt')
+>>> result = model(image)[0]
+>>> detections = sv.Detections.from_yolov8(result)
+
supervision/detection/core.py
173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 |
|
get_anchor_coordinates(anchor)
+
+¶Returns the bounding box coordinates for a specific anchor.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
anchor |
+
+ Position
+ |
+
+
+
+ Position of bounding box anchor for which to return the coordinates. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: An array of shape |
+
supervision/detection/core.py
428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 |
|
merge(detections_list)
+
+
+ classmethod
+
+
+¶Merge a list of Detections objects into a single Detections object.
+This method takes a list of Detections objects and combines their respective fields (xyxy
, mask
,
+confidence
, class_id
, and tracker_id
) into a single Detections object. If all elements in a field are not
+None
, the corresponding field will be stacked. Otherwise, the field will be set to None
.
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
detections_list |
+
+ List[Detections]
+ |
+
+
+
+ A list of Detections objects to merge. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ Detections
+ |
+
+
+
+ A single Detections object containing the merged data from the input list. + |
+
>>> from supervision import Detections
+
+>>> detections_1 = Detections(...)
+>>> detections_2 = Detections(...)
+
+>>> merged_detections = Detections.merge([detections_1, detections_2])
+
supervision/detection/core.py
379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 |
|
with_nms(threshold=0.5, class_agnostic=False)
+
+¶Perform non-maximum suppression on the current set of object detections.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
threshold |
+
+ float
+ |
+
+
+
+ The intersection-over-union threshold to use for non-maximum suppression. Defaults to 0.5. + |
+
+ 0.5
+ |
+
class_agnostic |
+
+ bool
+ |
+
+
+
+ Whether to perform class-agnostic non-maximum suppression. If True, the class_id of each detection will be ignored. Defaults to False. + |
+
+ False
+ |
+
Returns:
+Name | Type | +Description | +
---|---|---|
Detections |
+ Detections
+ |
+
+
+
+ A new Detections object containing the subset of detections after non-maximum suppression. + |
+
Raises:
+Type | +Description | +
---|---|
+ AssertionError
+ |
+
+
+
+ If |
+
supervision/detection/core.py
515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 |
|
A class for defining a polygon-shaped zone within a frame for detecting objects.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
polygon |
+
+ np.ndarray
+ |
+
+
+
+ A polygon represented by a numpy array of shape |
+
frame_resolution_wh |
+
+ Tuple[int, int]
+ |
+
+
+
+ The frame resolution (width, height) + |
+
triggering_position |
+
+ Position
+ |
+
+
+
+ The position within the bounding box that triggers the zone (default: Position.BOTTOM_CENTER) + |
+
current_count |
+
+ int
+ |
+
+
+
+ The current count of detected objects within the zone + |
+
mask |
+
+ np.ndarray
+ |
+
+
+
+ The 2D bool mask for the polygon zone + |
+
supervision/detection/tools/polygon_zone.py
15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 |
|
trigger(detections)
+
+¶Determines if the detections are within the polygon zone.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
detections |
+
+ Detections
+ |
+
+
+
+ The detections to be checked against the polygon zone + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: A boolean numpy array indicating if each detection is within the polygon zone + |
+
supervision/detection/tools/polygon_zone.py
43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 |
|
A class for annotating a polygon-shaped zone within a frame with a count of detected objects.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
zone |
+
+ PolygonZone
+ |
+
+
+
+ The polygon zone to be annotated + |
+
color |
+
+ Color
+ |
+
+
+
+ The color to draw the polygon lines + |
+
thickness |
+
+ int
+ |
+
+
+
+ The thickness of the polygon lines, default is 2 + |
+
text_color |
+
+ Color
+ |
+
+
+
+ The color of the text on the polygon, default is black + |
+
text_scale |
+
+ float
+ |
+
+
+
+ The scale of the text on the polygon, default is 0.5 + |
+
text_thickness |
+
+ int
+ |
+
+
+
+ The thickness of the text on the polygon, default is 1 + |
+
text_padding |
+
+ int
+ |
+
+
+
+ The padding around the text on the polygon, default is 10 + |
+
font |
+
+ int
+ |
+
+
+
+ The font type for the text on the polygon, default is cv2.FONT_HERSHEY_SIMPLEX + |
+
center |
+
+ Tuple[int, int]
+ |
+
+
+
+ The center of the polygon for text placement + |
+
supervision/detection/tools/polygon_zone.py
66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 |
|
annotate(scene, label=None)
+
+¶Annotates the polygon zone within a frame with a count of detected objects.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The image on which the polygon zone will be annotated + |
+ + required + | +
label |
+
+ Optional[str]
+ |
+
+
+
+ An optional label for the count of detected objects within the polygon zone (default: None) + |
+
+ None
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The image with the polygon zone and count of detected objects + |
+
supervision/detection/tools/polygon_zone.py
102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 |
|
Compute Intersection over Union (IoU) of two sets of bounding boxes - boxes_true
and boxes_detection
. Both sets
+of boxes are expected to be in (x_min, y_min, x_max, y_max)
format.
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
boxes_true |
+
+ np.ndarray
+ |
+
+
+
+ 2D |
+ + required + | +
boxes_detection |
+
+ np.ndarray
+ |
+
+
+
+ 2D |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: Pairwise IoU of boxes from |
+
supervision/detection/utils.py
25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 |
|
Perform Non-Maximum Suppression (NMS) on object detection predictions.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
predictions |
+
+ np.ndarray
+ |
+
+
+
+ An array of object detection predictions in the format of |
+ + required + | +
iou_threshold |
+
+ float
+ |
+
+
+
+ The intersection-over-union threshold to use for non-maximum suppression. + |
+
+ 0.5
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: A boolean array indicating which predictions to keep after non-maximum suppression. + |
+
Raises:
+Type | +Description | +
---|---|
+ AssertionError
+ |
+
+
+
+ If |
+
supervision/detection/utils.py
51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 |
|
Generate a mask from a polygon.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
polygon |
+
+ np.ndarray
+ |
+
+
+
+ The polygon for which the mask should be generated, given as a list of vertices. + |
+ + required + | +
resolution_wh |
+
+ Tuple[int, int]
+ |
+
+
+
+ The width and height of the desired resolution. + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The generated 2D mask, where the polygon is marked with |
+
supervision/detection/utils.py
9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 |
|
Converts a 3D np.array
of 2D bool masks into a 2D np.array
of bounding boxes.
Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
masks |
+
+ np.ndarray
+ |
+
+
+
+ A 3D |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: A 2D |
+
supervision/detection/utils.py
129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 |
|
Converts a binary mask to a list of polygons.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
mask |
+
+ np.ndarray
+ |
+
+
+
+ A binary mask represented as a 2D NumPy array of shape |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ List[np.ndarray]
+ |
+
+
+
+ List[np.ndarray]: A list of polygons, where each polygon is represented by a NumPy array of shape |
+
supervision/detection/utils.py
153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 |
|
Converts a polygon represented by a NumPy array into a bounding box.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
polygon |
+
+ np.ndarray
+ |
+
+
+
+ A polygon represented by a NumPy array of shape |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: A 1D NumPy array containing the bounding box |
+
supervision/detection/utils.py
207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 |
|
Filters a list of polygons based on their area.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
polygons |
+
+ List[np.ndarray]
+ |
+
+
+
+ A list of polygons, where each polygon is represented by a NumPy array of shape |
+ + required + | +
min_area |
+
+ Optional[float]
+ |
+
+
+
+ The minimum area threshold. Only polygons with an area greater than or equal to this value +will be included in the output. If set to None, no minimum area constraint will be applied. + |
+
+ None
+ |
+
max_area |
+
+ Optional[float]
+ |
+
+
+
+ The maximum area threshold. Only polygons with an area less than or equal to this value +will be included in the output. If set to None, no maximum area constraint will be applied. + |
+
+ None
+ |
+
Returns:
+Type | +Description | +
---|---|
+ List[np.ndarray]
+ |
+
+
+
+ List[np.ndarray]: A new list of polygons containing only those with areas within the specified thresholds. + |
+
supervision/detection/utils.py
177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 |
|
Draws a line on a given scene.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The scene on which the line will be drawn + |
+ + required + | +
start |
+
+ Point
+ |
+
+
+
+ The starting point of the line + |
+ + required + | +
end |
+
+ Point
+ |
+
+
+
+ The end point of the line + |
+ + required + | +
color |
+
+ Color
+ |
+
+
+
+ The color of the line + |
+ + required + | +
thickness |
+
+ int
+ |
+
+
+
+ The thickness of the line + |
+
+ 2
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The scene with the line drawn on it + |
+
supervision/draw/utils.py
10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 |
|
Draws a rectangle on an image.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The scene on which the rectangle will be drawn + |
+ + required + | +
rect |
+
+ Rect
+ |
+
+
+
+ The rectangle to be drawn + |
+ + required + | +
color |
+
+ Color
+ |
+
+
+
+ The color of the rectangle + |
+ + required + | +
thickness |
+
+ int
+ |
+
+
+
+ The thickness of the rectangle border + |
+
+ 2
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The scene with the rectangle drawn on it + |
+
supervision/draw/utils.py
36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 |
|
Draws a filled rectangle on an image.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The scene on which the rectangle will be drawn + |
+ + required + | +
rect |
+
+ Rect
+ |
+
+
+
+ The rectangle to be drawn + |
+ + required + | +
color |
+
+ Color
+ |
+
+
+
+ The color of the rectangle + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The scene with the rectangle drawn on it + |
+
supervision/draw/utils.py
61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 |
|
Draw a polygon on a scene.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ The scene to draw the polygon on. + |
+ + required + | +
polygon |
+
+ np.ndarray
+ |
+
+
+
+ The polygon to be drawn, given as a list of vertices. + |
+ + required + | +
color |
+
+ Color
+ |
+
+
+
+ The color of the polygon. + |
+ + required + | +
thickness |
+
+ int
+ |
+
+
+
+ The thickness of the polygon lines, by default 2. + |
+
+ 2
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The scene with the polygon drawn on it. + |
+
supervision/draw/utils.py
83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 +100 |
|
Draw text with background on a scene.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
scene |
+
+ np.ndarray
+ |
+
+
+
+ A 2-dimensional numpy ndarray representing an image or scene. + |
+ + required + | +
text |
+
+ str
+ |
+
+
+
+ The text to be drawn. + |
+ + required + | +
text_anchor |
+
+ Point
+ |
+
+
+
+ The anchor point for the text, represented as a Point object with x and y attributes. + |
+ + required + | +
text_color |
+
+ Color
+ |
+
+
+
+ The color of the text. Defaults to black. + |
+
+ Color.black()
+ |
+
text_scale |
+
+ float
+ |
+
+
+
+ The scale of the text. Defaults to 0.5. + |
+
+ 0.5
+ |
+
text_thickness |
+
+ int
+ |
+
+
+
+ The thickness of the text. Defaults to 1. + |
+
+ 1
+ |
+
text_padding |
+
+ int
+ |
+
+
+
+ The amount of padding to add around the text when drawing a rectangle in the background. Defaults to 10. + |
+
+ 10
+ |
+
text_font |
+
+ int
+ |
+
+
+
+ The font to use for the text. Defaults to cv2.FONT_HERSHEY_SIMPLEX. + |
+
+ cv2.FONT_HERSHEY_SIMPLEX
+ |
+
background_color |
+
+ Color
+ |
+
+
+
+ The color of the background rectangle, if one is to be drawn. Defaults to None. + |
+
+ None
+ |
+
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ np.ndarray: The input scene with the text drawn on it. + |
+
Examples:
+>>> scene = np.zeros((100, 100, 3), dtype=np.uint8)
+>>> text_anchor = Point(x=50, y=50)
+>>> scene = draw_text(scene=scene, text="Hello, world!", text_anchor=text_anchor)
+
supervision/draw/utils.py
103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 |
|
+ + + +
+Supervision is a set of easy-to-use utilities that will come in handy in any computer vision project.
+Supervision is still in +pre-release stage 🚧 Keep your eyes open for potential bugs and be aware that at this stage our API is still fluid and may change.
+You can install supervision
with pip in a
+3.11>=Python>=3.7 environment.
Pip install method (recommended)
+pip install supervision
+
Git clone method (for development)
+git https://github.com/roboflow/supervision.git
+cd supervision
+pip install -e '.[dev]'
+
The advanced filtering capabilities of the Detections
class offer users a versatile and efficient way to narrow down
+and refine object detections. This section outlines various filtering methods, including filtering by specific class
+or a set of classes, confidence, object area, bounding box area, relative area, box dimensions, and designated zones.
+Each method is demonstrated with concise code examples to provide users with a clear understanding of how to implement
+the filters in their applications.
Allows you to select detections that belong only to one selected class.
+import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.class_id == 0]
+
import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.class_id == 0]
+
Allows you to select detections that belong only to selected set of classes.
+import numpy as np
+import supervision as sv
+
+selected_classes = [0, 2, 3]
+detections = sv.Detections(...)
+detections = detections[np.isin(detections.class_id, selected_classes)]
+
import numpy as np
+import supervision as sv
+
+class_id = [0, 2, 3]
+detections = sv.Detections(...)
+detections = detections[np.isin(detections.class_id, class_id)]
+
Allows you to select detections with specific confidence value, for example higher than selected threshold.
+import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.confidence > 0.5]
+
import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.confidence > 0.5]
+
Allows you to select detections based on their size. We define the area as the number of pixels occupied by the +detection in the image. In the example below, we have sifted out the detections that are too small.
+import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.area > 1000]
+
import supervision as sv
+
+detections = sv.Detections(...)
+detections = detections[detections.area > 1000]
+
Allows you to select detections based on their size in relation to the size of whole image. Sometimes the concept of +detection size changes depending on the image. Detection occupying 10000 square px can be large on a 1280x720 image +but small on a 3840x2160 image. In such cases, we can filter out detections based on the percentage of the image area +occupied by them. In the example below, we remove too large detections.
+import supervision as sv
+
+image = ...
+height, width, channels = image.shape
+image_area = height * width
+
+detections = sv.Detections(...)
+detections = detections[(detections.area / image_area) < 0.8]
+
import supervision as sv
+
+image = ...
+height, width, channels = image.shape
+image_area = height * width
+
+detections = sv.Detections(...)
+detections = detections[(detections.area / image_area) < 0.8]
+
Allows you to select detections based on their dimensions. The size of the bounding box, as well as its coordinates, +can be criteria for rejecting detection. Implementing such filtering requires a bit of custom code but is relatively +simple and fast.
+import supervision as sv
+
+detections = sv.Detections(...)
+w = detections.xyxy[:, 2] - detections.xyxy[:, 0]
+h = detections.xyxy[:, 3] - detections.xyxy[:, 1]
+detections = detections[(w > 200) & (h > 200)]
+
import supervision as sv
+
+detections = sv.Detections(...)
+w = detections.xyxy[:, 2] - detections.xyxy[:, 0]
+h = detections.xyxy[:, 3] - detections.xyxy[:, 1]
+detections = detections[(w > 200) & (h > 200)]
+
PolygonZone
¶Allows you to use Detections
in combination with PolygonZone
to weed out bounding boxes that are in and out of the
+zone. In the example below you can see how to filter out all detections located in the lower part of the image.
import supervision as sv
+
+zone = sv.PolygonZone(...)
+detections = sv.Detections(...)
+mask = zone.trigger(detections=detections)
+detections = detections[mask]
+
import supervision as sv
+
+zone = sv.PolygonZone(...)
+detections = sv.Detections(...)
+mask = zone.trigger(detections=detections)
+detections = detections[mask]
+
Detections
' greatest strength, however, is that you can build arbitrarily complex logical conditions by simply combining separate conditions using &
or |
.
import supervision as sv
+
+zone = sv.PolygonZone(...)
+detections = sv.Detections(...)
+mask = zone.trigger(detections=detections)
+detections = detections[(detections.confidence > 0.7) & mask]
+
import supervision as sv
+
+zone = sv.PolygonZone(...)
+detections = sv.Detections(...)
+mask = zone.trigger(detections=detections)
+detections = detections[mask]
+
Supervision is a set of easy-to-use utilities that will come in handy in any computer vision project.
Supervision is still in pre-release stage \ud83d\udea7 Keep your eyes open for potential bugs and be aware that at this stage our API is still fluid and may change.
"},{"location":"#how-to-install","title":"\ud83d\udcbb How to Install","text":"You can install supervision
with pip in a 3.11>=Python>=3.7 environment.
Pip install method (recommended)
pip install supervision\n
Git clone method (for development)
git https://github.com/roboflow/supervision.git\ncd supervision\npip install -e '.[dev]'\n
See contributing section to know more about contributing to the project"},{"location":"changelog/","title":"Changelog","text":""},{"location":"changelog/#0100-june-14-2023","title":"0.10.0 June 14, 2023","text":"sv.ClassificationDataset
in a folder structure format.>>> import supervision as sv\n\n>>> cs = sv.ClassificationDataset.from_folder_structure(\n... root_directory_path='...'\n... )\n\n>>> cs.as_folder_structure(\n... root_directory_path='...'\n... )\n
Added [#125]: support for sv.ClassificationDataset.split
allowing to divide sv.ClassificationDataset
into two parts.
Added [#110]: ability to extract masks from Roboflow API results using sv.Detections.from_roboflow
.
Added [commit hash]: Supervision Quickstart notebook where you can learn more about Detection, Dataset and Video APIs.
Changed [#135]: sv.get_video_frames_generator
documentation to better describe actual behavior.
sv.Detections
by index, list of indexes or slice. Here is an example illustrating the new selection methods.>>> import supervision as sv\n\n>>> detections = sv.Detections(...)\n>>> len(detections[0])\n1\n>>> len(detections[[0, 1]])\n2\n>>> len(detections[0:2])\n2\n
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\n\n>>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:\n... for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=10):\n... sink.save_image(image=image)\n
sv.PolygonZone
coordinates. Now sv.PolygonZone
accepts coordinates in the form of [[x1, y1], [x2, y2], ...]
that can be both integers and floats.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.DetectionDataset.as_yolo
. >>> import roboflow\n>>> from roboflow import Roboflow\n>>> import supervision as sv\n\n>>> roboflow.login()\n\n>>> rf = Roboflow()\n\n>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n>>> dataset = project.version(PROJECT_VERSION).download(\"yolov5\")\n\n>>> ds = sv.DetectionDataset.from_yolo(\n... images_directory_path=f\"{dataset.location}/train/images\",\n... annotations_directory_path=f\"{dataset.location}/train/labels\",\n... data_yaml_path=f\"{dataset.location}/data.yaml\"\n... )\n\n>>> ds.classes\n['dog', 'person']\n
DetectionDataset.split
allowing to divide DetectionDataset
into two parts. >>> import supervision as sv\n\n>>> ds = sv.DetectionDataset(...)\n>>> train_ds, test_ds = ds.split(split_ratio=0.7, random_state=42, shuffle=True)\n\n>>> len(train_ds), len(test_ds)\n(700, 300)\n
approximation_percentage
parameter from 0.75
to 0.0
in DetectionDataset.as_yolo
and DetectionDataset.as_pascal_voc
.Detections.from_yolo_nas
to enable seamless integration with YOLO-NAS model.Dataset.from_yolo
. Detections.merge
to merge multiple Detections
objects together.LineZoneAnnotator.annotate
does not return annotated frame.LineZoneAnnotator.annotate
to allow for custom text for the in and out tags.Dataset
support and ability to save Detections
in Pascal VOC XML format. mask_to_polygons
, filter_polygons_by_area
, polygon_to_xyxy
and approximate_polygon
utilities.Dataset
.Detections
attributes to make it consistent with order of objects in __iter__
tuple.generate_2d_mask
to polygon_to_mask
.LineZone.trigger
function expects 4 values instead of 5.Detections.__getitem__
method did not return mask for selected item.Detections.area
crashed for mask detections.Detections.mask
to enable segmentation support.MaskAnnotator
to allow easy Detections.mask
annotation.Detections.from_sam
to enable native Segment Anything Model (SAM) support.Detections.area
behaviour to work not only with boxes but also with masks.Detections.empty
to allow easy creation of empty Detections
objects.Detections.from_roboflow
to allow easy creation of Detections
objects from Roboflow API inference results.plot_images_grid
to allow easy plotting of multiple images on single plot.detections_to_voc_xml
method.show_frame_in_notebook
refactored and renamed to plot_image
.Detections.class_id
to be None
. PolygonZone
throws an exception when the object touches the bottom edge of the image.Detections.wth_nms
method throws an exception when Detections
is empty.Detections.wth_nms
support class agnostic and non-class agnostic case.Detections.confidence
to be None
.Detections.from_transformers
and Detections.from_detectron2
to enable seamless integration with Transformers and Detectron2 models. Detections.area
to dynamically calculate bounding box area.Detections.wth_nms
to filter out double detections with NMS. Initial - only class agnostic - implementation. Detections
filtering with pandas-like API.Detections.from_yolov5
and Detections.from_yolov8
to enable seamless integration with YOLOv5 and YOLOv8 models.Say hello to Supervision \ud83d\udc4b
"},{"location":"classification/core/","title":"Core","text":""},{"location":"classification/core/#classifications","title":"Classifications","text":"Source code insupervision/classification/core.py
@dataclass\nclass Classifications:\n class_id: np.ndarray\n confidence: Optional[np.ndarray] = None\n\n def __post_init__(self) -> None:\n\"\"\"\n Validate the classification inputs.\n \"\"\"\n n = len(self.class_id)\n\n _validate_class_ids(self.class_id, n)\n _validate_confidence(self.confidence, n)\n\n @classmethod\n def from_yolov8(cls, yolov8_results) -> Classifications:\n\"\"\"\n Creates a Classifications instance from a [YOLOv8](https://github.com/ultralytics/ultralytics) inference result.\n\n Args:\n yolov8_results (ultralytics.yolo.engine.results.Results): The output Results instance from YOLOv8\n\n Returns:\n Detections: A new Classifications object.\n\n Example:\n ```python\n >>> import cv2\n >>> from ultralytics import YOLO\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = YOLO('yolov8s-cls.pt')\n >>> result = model(image)[0]\n >>> classifications = sv.Classifications.from_yolov8(result)\n ```\n \"\"\"\n confidence = yolov8_results.probs.data.cpu().numpy()\n return cls(class_id=np.arange(confidence.shape[0]), confidence=confidence)\n\n def get_top_k(self, k: int) -> Tuple[np.ndarray, np.ndarray]:\n\"\"\"\n Retrieve the top k class IDs and confidences, ordered in descending order by confidence.\n\n Args:\n k (int): The number of top class IDs and confidences to retrieve.\n\n Returns:\n Tuple[np.ndarray, np.ndarray]: A tuple containing the top k class IDs and confidences.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> classifications = sv.Classifications(...)\n\n >>> classifications.get_top_k(1)\n\n (array([1]), array([0.9]))\n ```\n \"\"\"\n if self.confidence is None:\n raise ValueError(\"top_k could not be calculated, confidence is None\")\n\n order = np.argsort(self.confidence)[::-1]\n top_k_order = order[:k]\n top_k_class_id = self.class_id[top_k_order]\n top_k_confidence = self.confidence[top_k_order]\n\n return top_k_class_id, top_k_confidence\n
"},{"location":"classification/core/#supervision.classification.core.Classifications.__post_init__","title":"__post_init__()
","text":"Validate the classification inputs.
Source code insupervision/classification/core.py
def __post_init__(self) -> None:\n\"\"\"\n Validate the classification inputs.\n \"\"\"\n n = len(self.class_id)\n\n _validate_class_ids(self.class_id, n)\n _validate_confidence(self.confidence, n)\n
"},{"location":"classification/core/#supervision.classification.core.Classifications.from_yolov8","title":"from_yolov8(yolov8_results)
classmethod
","text":"Creates a Classifications instance from a YOLOv8 inference result.
Parameters:
Name Type Description Defaultyolov8_results
ultralytics.yolo.engine.results.Results
The output Results instance from YOLOv8
requiredReturns:
Name Type DescriptionDetections
Classifications
A new Classifications object.
Example>>> import cv2\n>>> from ultralytics import YOLO\n>>> import supervision as sv\n\n>>> image = cv2.imread(SOURCE_IMAGE_PATH)\n>>> model = YOLO('yolov8s-cls.pt')\n>>> result = model(image)[0]\n>>> classifications = sv.Classifications.from_yolov8(result)\n
Source code in supervision/classification/core.py
@classmethod\ndef from_yolov8(cls, yolov8_results) -> Classifications:\n\"\"\"\n Creates a Classifications instance from a [YOLOv8](https://github.com/ultralytics/ultralytics) inference result.\n\n Args:\n yolov8_results (ultralytics.yolo.engine.results.Results): The output Results instance from YOLOv8\n\n Returns:\n Detections: A new Classifications object.\n\n Example:\n ```python\n >>> import cv2\n >>> from ultralytics import YOLO\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = YOLO('yolov8s-cls.pt')\n >>> result = model(image)[0]\n >>> classifications = sv.Classifications.from_yolov8(result)\n ```\n \"\"\"\n confidence = yolov8_results.probs.data.cpu().numpy()\n return cls(class_id=np.arange(confidence.shape[0]), confidence=confidence)\n
"},{"location":"classification/core/#supervision.classification.core.Classifications.get_top_k","title":"get_top_k(k)
","text":"Retrieve the top k class IDs and confidences, ordered in descending order by confidence.
Parameters:
Name Type Description Defaultk
int
The number of top class IDs and confidences to retrieve.
requiredReturns:
Type DescriptionTuple[np.ndarray, np.ndarray]
Tuple[np.ndarray, np.ndarray]: A tuple containing the top k class IDs and confidences.
Example>>> import supervision as sv\n\n>>> classifications = sv.Classifications(...)\n\n>>> classifications.get_top_k(1)\n\n(array([1]), array([0.9]))\n
Source code in supervision/classification/core.py
def get_top_k(self, k: int) -> Tuple[np.ndarray, np.ndarray]:\n\"\"\"\n Retrieve the top k class IDs and confidences, ordered in descending order by confidence.\n\n Args:\n k (int): The number of top class IDs and confidences to retrieve.\n\n Returns:\n Tuple[np.ndarray, np.ndarray]: A tuple containing the top k class IDs and confidences.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> classifications = sv.Classifications(...)\n\n >>> classifications.get_top_k(1)\n\n (array([1]), array([0.9]))\n ```\n \"\"\"\n if self.confidence is None:\n raise ValueError(\"top_k could not be calculated, confidence is None\")\n\n order = np.argsort(self.confidence)[::-1]\n top_k_order = order[:k]\n top_k_class_id = self.class_id[top_k_order]\n top_k_confidence = self.confidence[top_k_order]\n\n return top_k_class_id, top_k_confidence\n
"},{"location":"dataset/core/","title":"Core","text":"Warning
Dataset API is still fluid and may change. If you use Dataset API in your project until further notice, freeze the supervision
version in your requirements.txt
or setup.py
.
Bases: BaseDataset
Dataclass containing information about object detection dataset.
Attributes:
Name Type Descriptionclasses
List[str]
List containing dataset class names.
images
Dict[str, np.ndarray]
Dictionary mapping image name to image.
annotations
Dict[str, Detections]
Dictionary mapping image name to annotations.
Source code insupervision/dataset/core.py
@dataclass\nclass DetectionDataset(BaseDataset):\n\"\"\"\n Dataclass containing information about object detection dataset.\n\n Attributes:\n classes (List[str]): List containing dataset class names.\n images (Dict[str, np.ndarray]): Dictionary mapping image name to image.\n annotations (Dict[str, Detections]): Dictionary mapping image name to annotations.\n \"\"\"\n\n classes: List[str]\n images: Dict[str, np.ndarray]\n annotations: Dict[str, Detections]\n\n def __len__(self) -> int:\n\"\"\"\n Return the number of images in the dataset.\n\n Returns:\n int: The number of images.\n \"\"\"\n return len(self.images)\n\n def __iter__(self) -> Iterator[Tuple[str, np.ndarray, Detections]]:\n\"\"\"\n Iterate over the images and annotations in the dataset.\n\n Yields:\n Iterator[Tuple[str, np.ndarray, Detections]]: An iterator that yields tuples containing the image name,\n the image data, and its corresponding annotation.\n \"\"\"\n for image_name, image in self.images.items():\n yield image_name, image, self.annotations.get(image_name, None)\n\n def split(\n self, split_ratio=0.8, random_state=None, shuffle: bool = True\n ) -> Tuple[DetectionDataset, DetectionDataset]:\n\"\"\"\n Splits the dataset into two parts (training and testing) using the provided split_ratio.\n\n Args:\n split_ratio (float, optional): The ratio of the training set to the entire dataset.\n random_state (int, optional): The seed for the random number generator. This is used for reproducibility.\n shuffle (bool, optional): Whether to shuffle the data before splitting.\n\n Returns:\n Tuple[DetectionDataset, DetectionDataset]: A tuple containing the training and testing datasets.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> ds = sv.DetectionDataset(...)\n >>> train_ds, test_ds = ds.split(split_ratio=0.7, random_state=42, shuffle=True)\n >>> len(train_ds), len(test_ds)\n (700, 300)\n ```\n \"\"\"\n\n image_names = list(self.images.keys())\n train_names, test_names = train_test_split(\n data=image_names,\n train_ratio=split_ratio,\n random_state=random_state,\n shuffle=shuffle,\n )\n\n train_dataset = DetectionDataset(\n classes=self.classes,\n images={name: self.images[name] for name in train_names},\n annotations={name: self.annotations[name] for name in train_names},\n )\n test_dataset = DetectionDataset(\n classes=self.classes,\n images={name: self.images[name] for name in test_names},\n annotations={name: self.annotations[name] for name in test_names},\n )\n return train_dataset, test_dataset\n\n def as_pascal_voc(\n self,\n images_directory_path: Optional[str] = None,\n annotations_directory_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n ) -> None:\n\"\"\"\n Exports the dataset to PASCAL VOC format. This method saves the images and their corresponding annotations in\n PASCAL VOC format, which consists of XML files. The method allows filtering the detections based on their area\n percentage.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n PASCAL VOC format should be saved. If not provided, annotations will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon, in the range [0, 1).\n \"\"\"\n if images_directory_path:\n images_path = Path(images_directory_path)\n images_path.mkdir(parents=True, exist_ok=True)\n\n if annotations_directory_path:\n annotations_path = Path(annotations_directory_path)\n annotations_path.mkdir(parents=True, exist_ok=True)\n\n for image_name, image in self.images.items():\n detections = self.annotations[image_name]\n\n if images_directory_path:\n cv2.imwrite(str(images_path / image_name), image)\n\n if annotations_directory_path:\n annotation_name = Path(image_name).stem\n pascal_voc_xml = detections_to_pascal_voc(\n detections=detections,\n classes=self.classes,\n filename=image_name,\n image_shape=image.shape,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n )\n\n with open(annotations_path / f\"{annotation_name}.xml\", \"w\") as f:\n f.write(pascal_voc_xml)\n\n @classmethod\n def from_pascal_voc(\n cls, images_directory_path: str, annotations_directory_path: str\n ) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from PASCAL VOC formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_directory_path (str): The path to the directory containing the PASCAL VOC XML annotations.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"voc\")\n\n >>> ds = sv.DetectionDataset.from_yolo(\n ... images_directory_path=f\"{dataset.location}/train/images\",\n ... annotations_directory_path=f\"{dataset.location}/train/labels\"\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n image_paths = list_files_with_extensions(\n directory=images_directory_path, extensions=[\"jpg\", \"jpeg\", \"png\"]\n )\n annotation_paths = list_files_with_extensions(\n directory=annotations_directory_path, extensions=[\"xml\"]\n )\n\n raw_annotations: List[Tuple[str, Detections, List[str]]] = [\n load_pascal_voc_annotations(annotation_path=str(annotation_path))\n for annotation_path in annotation_paths\n ]\n\n classes = []\n for annotation in raw_annotations:\n classes.extend(annotation[2])\n classes = list(set(classes))\n\n for annotation in raw_annotations:\n class_id = [classes.index(class_name) for class_name in annotation[2]]\n annotation[1].class_id = np.array(class_id)\n\n images = {\n image_path.name: cv2.imread(str(image_path)) for image_path in image_paths\n }\n\n annotations = {\n image_name: detections for image_name, detections, _ in raw_annotations\n }\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n\n @classmethod\n def from_yolo(\n cls,\n images_directory_path: str,\n annotations_directory_path: str,\n data_yaml_path: str,\n force_masks: bool = False,\n ) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from YOLO formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_directory_path (str): The path to the directory containing the YOLO annotation files.\n data_yaml_path (str): The path to the data YAML file containing class information.\n force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"yolov5\")\n\n >>> ds = sv.DetectionDataset.from_yolo(\n ... images_directory_path=f\"{dataset.location}/train/images\",\n ... annotations_directory_path=f\"{dataset.location}/train/labels\",\n ... data_yaml_path=f\"{dataset.location}/data.yaml\"\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n classes, images, annotations = load_yolo_annotations(\n images_directory_path=images_directory_path,\n annotations_directory_path=annotations_directory_path,\n data_yaml_path=data_yaml_path,\n force_masks=force_masks,\n )\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n\n def as_yolo(\n self,\n images_directory_path: Optional[str] = None,\n annotations_directory_path: Optional[str] = None,\n data_yaml_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n ) -> None:\n\"\"\"\n Exports the dataset to YOLO format. This method saves the images and their corresponding\n annotations in YOLO format, which is a simple text file that describes an object in the image. It also allows\n for the optional saving of a data.yaml file, used in YOLOv5, that contains metadata about the dataset.\n\n The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n YOLO format should be saved. If not provided, annotations will not be saved.\n data_yaml_path (Optional[str]): The path where the data.yaml file should be saved.\n If not provided, the file will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon,\n in the range [0, 1). This is useful for simplifying the annotations.\n \"\"\"\n if images_directory_path is not None:\n save_dataset_images(\n images_directory_path=images_directory_path, images=self.images\n )\n if annotations_directory_path is not None:\n save_yolo_annotations(\n annotations_directory_path=annotations_directory_path,\n images=self.images,\n annotations=self.annotations,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n )\n if data_yaml_path is not None:\n save_data_yaml(data_yaml_path=data_yaml_path, classes=self.classes)\n\n @classmethod\n def from_coco(\n cls,\n images_directory_path: str,\n annotations_path: str,\n force_masks: bool = False,\n ) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from YOLO formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_path (str): The path to the json annotation files.\n force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"coco\")\n\n >>> ds = sv.DetectionDataset.from_coco(\n ... images_directory_path=f\"{dataset.location}/train\",\n ... annotations_path=f\"{dataset.location}/train/_annotations.coco.json\",\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n classes, images, annotations = load_coco_annotations(\n images_directory_path=images_directory_path,\n annotations_path=annotations_path,\n force_masks=force_masks,\n )\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n\n def as_coco(\n self,\n images_directory_path: Optional[str] = None,\n annotations_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n licenses: Optional[list] = None,\n info: Optional[dict] = None,\n ) -> None:\n\"\"\"\n Exports the dataset to COCO format. This method saves the images and their corresponding\n annotations in COCO format, which is a simple json file that describes an object in the image.\n Annotation json file also include category maps.\n\n The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n YOLO format should be saved. If not provided, annotations will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon,\n in the range [0, 1). This is useful for simplifying the annotations.\n licenses (Optional[str]): List of licenses for images\n info (Optional[dict]): Information of Dataset as dictionary\n \"\"\"\n if images_directory_path is not None:\n save_dataset_images(\n images_directory_path=images_directory_path, images=self.images\n )\n if annotations_path is not None:\n save_coco_annotations(\n annotation_path=annotations_path,\n images=self.images,\n annotations=self.annotations,\n classes=self.classes,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n licenses=licenses,\n info=info,\n )\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.__iter__","title":"__iter__()
","text":"Iterate over the images and annotations in the dataset.
Yields:
Type Descriptionstr
Iterator[Tuple[str, np.ndarray, Detections]]: An iterator that yields tuples containing the image name, the image data, and its corresponding annotation.
Source code insupervision/dataset/core.py
def __iter__(self) -> Iterator[Tuple[str, np.ndarray, Detections]]:\n\"\"\"\n Iterate over the images and annotations in the dataset.\n\n Yields:\n Iterator[Tuple[str, np.ndarray, Detections]]: An iterator that yields tuples containing the image name,\n the image data, and its corresponding annotation.\n \"\"\"\n for image_name, image in self.images.items():\n yield image_name, image, self.annotations.get(image_name, None)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.__len__","title":"__len__()
","text":"Return the number of images in the dataset.
Returns:
Name Type Descriptionint
int
The number of images.
Source code insupervision/dataset/core.py
def __len__(self) -> int:\n\"\"\"\n Return the number of images in the dataset.\n\n Returns:\n int: The number of images.\n \"\"\"\n return len(self.images)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.as_coco","title":"as_coco(images_directory_path=None, annotations_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0, licenses=None, info=None)
","text":"Exports the dataset to COCO format. This method saves the images and their corresponding annotations in COCO format, which is a simple json file that describes an object in the image. Annotation json file also include category maps.
The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.
Parameters:
Name Type Description Defaultimages_directory_path
Optional[str]
The path to the directory where the images should be saved. If not provided, images will not be saved.
None
annotations_directory_path
Optional[str]
The path to the directory where the annotations in YOLO format should be saved. If not provided, annotations will not be saved.
requiredmin_image_area_percentage
float
The minimum percentage of detection area relative to the image area for a detection to be included.
0.0
max_image_area_percentage
float
The maximum percentage of detection area relative to the image area for a detection to be included.
1.0
approximation_percentage
float
The percentage of polygon points to be removed from the input polygon, in the range [0, 1). This is useful for simplifying the annotations.
0.0
licenses
Optional[str]
List of licenses for images
None
info
Optional[dict]
Information of Dataset as dictionary
None
Source code in supervision/dataset/core.py
def as_coco(\n self,\n images_directory_path: Optional[str] = None,\n annotations_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n licenses: Optional[list] = None,\n info: Optional[dict] = None,\n) -> None:\n\"\"\"\n Exports the dataset to COCO format. This method saves the images and their corresponding\n annotations in COCO format, which is a simple json file that describes an object in the image.\n Annotation json file also include category maps.\n\n The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n YOLO format should be saved. If not provided, annotations will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon,\n in the range [0, 1). This is useful for simplifying the annotations.\n licenses (Optional[str]): List of licenses for images\n info (Optional[dict]): Information of Dataset as dictionary\n \"\"\"\n if images_directory_path is not None:\n save_dataset_images(\n images_directory_path=images_directory_path, images=self.images\n )\n if annotations_path is not None:\n save_coco_annotations(\n annotation_path=annotations_path,\n images=self.images,\n annotations=self.annotations,\n classes=self.classes,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n licenses=licenses,\n info=info,\n )\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.as_pascal_voc","title":"as_pascal_voc(images_directory_path=None, annotations_directory_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0)
","text":"Exports the dataset to PASCAL VOC format. This method saves the images and their corresponding annotations in PASCAL VOC format, which consists of XML files. The method allows filtering the detections based on their area percentage.
Parameters:
Name Type Description Defaultimages_directory_path
Optional[str]
The path to the directory where the images should be saved. If not provided, images will not be saved.
None
annotations_directory_path
Optional[str]
The path to the directory where the annotations in PASCAL VOC format should be saved. If not provided, annotations will not be saved.
None
min_image_area_percentage
float
The minimum percentage of detection area relative to the image area for a detection to be included.
0.0
max_image_area_percentage
float
The maximum percentage of detection area relative to the image area for a detection to be included.
1.0
approximation_percentage
float
The percentage of polygon points to be removed from the input polygon, in the range [0, 1).
0.0
Source code in supervision/dataset/core.py
def as_pascal_voc(\n self,\n images_directory_path: Optional[str] = None,\n annotations_directory_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n) -> None:\n\"\"\"\n Exports the dataset to PASCAL VOC format. This method saves the images and their corresponding annotations in\n PASCAL VOC format, which consists of XML files. The method allows filtering the detections based on their area\n percentage.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n PASCAL VOC format should be saved. If not provided, annotations will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon, in the range [0, 1).\n \"\"\"\n if images_directory_path:\n images_path = Path(images_directory_path)\n images_path.mkdir(parents=True, exist_ok=True)\n\n if annotations_directory_path:\n annotations_path = Path(annotations_directory_path)\n annotations_path.mkdir(parents=True, exist_ok=True)\n\n for image_name, image in self.images.items():\n detections = self.annotations[image_name]\n\n if images_directory_path:\n cv2.imwrite(str(images_path / image_name), image)\n\n if annotations_directory_path:\n annotation_name = Path(image_name).stem\n pascal_voc_xml = detections_to_pascal_voc(\n detections=detections,\n classes=self.classes,\n filename=image_name,\n image_shape=image.shape,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n )\n\n with open(annotations_path / f\"{annotation_name}.xml\", \"w\") as f:\n f.write(pascal_voc_xml)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.as_yolo","title":"as_yolo(images_directory_path=None, annotations_directory_path=None, data_yaml_path=None, min_image_area_percentage=0.0, max_image_area_percentage=1.0, approximation_percentage=0.0)
","text":"Exports the dataset to YOLO format. This method saves the images and their corresponding annotations in YOLO format, which is a simple text file that describes an object in the image. It also allows for the optional saving of a data.yaml file, used in YOLOv5, that contains metadata about the dataset.
The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.
Parameters:
Name Type Description Defaultimages_directory_path
Optional[str]
The path to the directory where the images should be saved. If not provided, images will not be saved.
None
annotations_directory_path
Optional[str]
The path to the directory where the annotations in YOLO format should be saved. If not provided, annotations will not be saved.
None
data_yaml_path
Optional[str]
The path where the data.yaml file should be saved. If not provided, the file will not be saved.
None
min_image_area_percentage
float
The minimum percentage of detection area relative to the image area for a detection to be included.
0.0
max_image_area_percentage
float
The maximum percentage of detection area relative to the image area for a detection to be included.
1.0
approximation_percentage
float
The percentage of polygon points to be removed from the input polygon, in the range [0, 1). This is useful for simplifying the annotations.
0.0
Source code in supervision/dataset/core.py
def as_yolo(\n self,\n images_directory_path: Optional[str] = None,\n annotations_directory_path: Optional[str] = None,\n data_yaml_path: Optional[str] = None,\n min_image_area_percentage: float = 0.0,\n max_image_area_percentage: float = 1.0,\n approximation_percentage: float = 0.0,\n) -> None:\n\"\"\"\n Exports the dataset to YOLO format. This method saves the images and their corresponding\n annotations in YOLO format, which is a simple text file that describes an object in the image. It also allows\n for the optional saving of a data.yaml file, used in YOLOv5, that contains metadata about the dataset.\n\n The method allows filtering the detections based on their area percentage and offers an option for polygon approximation.\n\n Args:\n images_directory_path (Optional[str]): The path to the directory where the images should be saved.\n If not provided, images will not be saved.\n annotations_directory_path (Optional[str]): The path to the directory where the annotations in\n YOLO format should be saved. If not provided, annotations will not be saved.\n data_yaml_path (Optional[str]): The path where the data.yaml file should be saved.\n If not provided, the file will not be saved.\n min_image_area_percentage (float): The minimum percentage of detection area relative to\n the image area for a detection to be included.\n max_image_area_percentage (float): The maximum percentage of detection area relative to\n the image area for a detection to be included.\n approximation_percentage (float): The percentage of polygon points to be removed from the input polygon,\n in the range [0, 1). This is useful for simplifying the annotations.\n \"\"\"\n if images_directory_path is not None:\n save_dataset_images(\n images_directory_path=images_directory_path, images=self.images\n )\n if annotations_directory_path is not None:\n save_yolo_annotations(\n annotations_directory_path=annotations_directory_path,\n images=self.images,\n annotations=self.annotations,\n min_image_area_percentage=min_image_area_percentage,\n max_image_area_percentage=max_image_area_percentage,\n approximation_percentage=approximation_percentage,\n )\n if data_yaml_path is not None:\n save_data_yaml(data_yaml_path=data_yaml_path, classes=self.classes)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.from_coco","title":"from_coco(images_directory_path, annotations_path, force_masks=False)
classmethod
","text":"Creates a Dataset instance from YOLO formatted data.
Parameters:
Name Type Description Defaultimages_directory_path
str
The path to the directory containing the images.
requiredannotations_path
str
The path to the json annotation files.
requiredforce_masks
bool
If True, forces masks to be loaded for all annotations, regardless of whether they are present.
False
Returns:
Name Type DescriptionDetectionDataset
DetectionDataset
A DetectionDataset instance containing the loaded images and annotations.
Example>>> import roboflow\n>>> from roboflow import Roboflow\n>>> import supervision as sv\n\n>>> roboflow.login()\n\n>>> rf = Roboflow()\n\n>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n>>> dataset = project.version(PROJECT_VERSION).download(\"coco\")\n\n>>> ds = sv.DetectionDataset.from_coco(\n... images_directory_path=f\"{dataset.location}/train\",\n... annotations_path=f\"{dataset.location}/train/_annotations.coco.json\",\n... )\n\n>>> ds.classes\n['dog', 'person']\n
Source code in supervision/dataset/core.py
@classmethod\ndef from_coco(\n cls,\n images_directory_path: str,\n annotations_path: str,\n force_masks: bool = False,\n) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from YOLO formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_path (str): The path to the json annotation files.\n force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"coco\")\n\n >>> ds = sv.DetectionDataset.from_coco(\n ... images_directory_path=f\"{dataset.location}/train\",\n ... annotations_path=f\"{dataset.location}/train/_annotations.coco.json\",\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n classes, images, annotations = load_coco_annotations(\n images_directory_path=images_directory_path,\n annotations_path=annotations_path,\n force_masks=force_masks,\n )\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.from_pascal_voc","title":"from_pascal_voc(images_directory_path, annotations_directory_path)
classmethod
","text":"Creates a Dataset instance from PASCAL VOC formatted data.
Parameters:
Name Type Description Defaultimages_directory_path
str
The path to the directory containing the images.
requiredannotations_directory_path
str
The path to the directory containing the PASCAL VOC XML annotations.
requiredReturns:
Name Type DescriptionDetectionDataset
DetectionDataset
A DetectionDataset instance containing the loaded images and annotations.
Example>>> import roboflow\n>>> from roboflow import Roboflow\n>>> import supervision as sv\n\n>>> roboflow.login()\n\n>>> rf = Roboflow()\n\n>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n>>> dataset = project.version(PROJECT_VERSION).download(\"voc\")\n\n>>> ds = sv.DetectionDataset.from_yolo(\n... images_directory_path=f\"{dataset.location}/train/images\",\n... annotations_directory_path=f\"{dataset.location}/train/labels\"\n... )\n\n>>> ds.classes\n['dog', 'person']\n
Source code in supervision/dataset/core.py
@classmethod\ndef from_pascal_voc(\n cls, images_directory_path: str, annotations_directory_path: str\n) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from PASCAL VOC formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_directory_path (str): The path to the directory containing the PASCAL VOC XML annotations.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"voc\")\n\n >>> ds = sv.DetectionDataset.from_yolo(\n ... images_directory_path=f\"{dataset.location}/train/images\",\n ... annotations_directory_path=f\"{dataset.location}/train/labels\"\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n image_paths = list_files_with_extensions(\n directory=images_directory_path, extensions=[\"jpg\", \"jpeg\", \"png\"]\n )\n annotation_paths = list_files_with_extensions(\n directory=annotations_directory_path, extensions=[\"xml\"]\n )\n\n raw_annotations: List[Tuple[str, Detections, List[str]]] = [\n load_pascal_voc_annotations(annotation_path=str(annotation_path))\n for annotation_path in annotation_paths\n ]\n\n classes = []\n for annotation in raw_annotations:\n classes.extend(annotation[2])\n classes = list(set(classes))\n\n for annotation in raw_annotations:\n class_id = [classes.index(class_name) for class_name in annotation[2]]\n annotation[1].class_id = np.array(class_id)\n\n images = {\n image_path.name: cv2.imread(str(image_path)) for image_path in image_paths\n }\n\n annotations = {\n image_name: detections for image_name, detections, _ in raw_annotations\n }\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.from_yolo","title":"from_yolo(images_directory_path, annotations_directory_path, data_yaml_path, force_masks=False)
classmethod
","text":"Creates a Dataset instance from YOLO formatted data.
Parameters:
Name Type Description Defaultimages_directory_path
str
The path to the directory containing the images.
requiredannotations_directory_path
str
The path to the directory containing the YOLO annotation files.
requireddata_yaml_path
str
The path to the data YAML file containing class information.
requiredforce_masks
bool
If True, forces masks to be loaded for all annotations, regardless of whether they are present.
False
Returns:
Name Type DescriptionDetectionDataset
DetectionDataset
A DetectionDataset instance containing the loaded images and annotations.
Example>>> import roboflow\n>>> from roboflow import Roboflow\n>>> import supervision as sv\n\n>>> roboflow.login()\n\n>>> rf = Roboflow()\n\n>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n>>> dataset = project.version(PROJECT_VERSION).download(\"yolov5\")\n\n>>> ds = sv.DetectionDataset.from_yolo(\n... images_directory_path=f\"{dataset.location}/train/images\",\n... annotations_directory_path=f\"{dataset.location}/train/labels\",\n... data_yaml_path=f\"{dataset.location}/data.yaml\"\n... )\n\n>>> ds.classes\n['dog', 'person']\n
Source code in supervision/dataset/core.py
@classmethod\ndef from_yolo(\n cls,\n images_directory_path: str,\n annotations_directory_path: str,\n data_yaml_path: str,\n force_masks: bool = False,\n) -> DetectionDataset:\n\"\"\"\n Creates a Dataset instance from YOLO formatted data.\n\n Args:\n images_directory_path (str): The path to the directory containing the images.\n annotations_directory_path (str): The path to the directory containing the YOLO annotation files.\n data_yaml_path (str): The path to the data YAML file containing class information.\n force_masks (bool, optional): If True, forces masks to be loaded for all annotations, regardless of whether they are present.\n\n Returns:\n DetectionDataset: A DetectionDataset instance containing the loaded images and annotations.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"yolov5\")\n\n >>> ds = sv.DetectionDataset.from_yolo(\n ... images_directory_path=f\"{dataset.location}/train/images\",\n ... annotations_directory_path=f\"{dataset.location}/train/labels\",\n ... data_yaml_path=f\"{dataset.location}/data.yaml\"\n ... )\n\n >>> ds.classes\n ['dog', 'person']\n ```\n \"\"\"\n classes, images, annotations = load_yolo_annotations(\n images_directory_path=images_directory_path,\n annotations_directory_path=annotations_directory_path,\n data_yaml_path=data_yaml_path,\n force_masks=force_masks,\n )\n return DetectionDataset(classes=classes, images=images, annotations=annotations)\n
"},{"location":"dataset/core/#supervision.dataset.core.DetectionDataset.split","title":"split(split_ratio=0.8, random_state=None, shuffle=True)
","text":"Splits the dataset into two parts (training and testing) using the provided split_ratio.
Parameters:
Name Type Description Defaultsplit_ratio
float
The ratio of the training set to the entire dataset.
0.8
random_state
int
The seed for the random number generator. This is used for reproducibility.
None
shuffle
bool
Whether to shuffle the data before splitting.
True
Returns:
Type DescriptionTuple[DetectionDataset, DetectionDataset]
Tuple[DetectionDataset, DetectionDataset]: A tuple containing the training and testing datasets.
Example>>> import supervision as sv\n\n>>> ds = sv.DetectionDataset(...)\n>>> train_ds, test_ds = ds.split(split_ratio=0.7, random_state=42, shuffle=True)\n>>> len(train_ds), len(test_ds)\n(700, 300)\n
Source code in supervision/dataset/core.py
def split(\n self, split_ratio=0.8, random_state=None, shuffle: bool = True\n) -> Tuple[DetectionDataset, DetectionDataset]:\n\"\"\"\n Splits the dataset into two parts (training and testing) using the provided split_ratio.\n\n Args:\n split_ratio (float, optional): The ratio of the training set to the entire dataset.\n random_state (int, optional): The seed for the random number generator. This is used for reproducibility.\n shuffle (bool, optional): Whether to shuffle the data before splitting.\n\n Returns:\n Tuple[DetectionDataset, DetectionDataset]: A tuple containing the training and testing datasets.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> ds = sv.DetectionDataset(...)\n >>> train_ds, test_ds = ds.split(split_ratio=0.7, random_state=42, shuffle=True)\n >>> len(train_ds), len(test_ds)\n (700, 300)\n ```\n \"\"\"\n\n image_names = list(self.images.keys())\n train_names, test_names = train_test_split(\n data=image_names,\n train_ratio=split_ratio,\n random_state=random_state,\n shuffle=shuffle,\n )\n\n train_dataset = DetectionDataset(\n classes=self.classes,\n images={name: self.images[name] for name in train_names},\n annotations={name: self.annotations[name] for name in train_names},\n )\n test_dataset = DetectionDataset(\n classes=self.classes,\n images={name: self.images[name] for name in test_names},\n annotations={name: self.annotations[name] for name in test_names},\n )\n return train_dataset, test_dataset\n
"},{"location":"dataset/core/#classificationdataset","title":"ClassificationDataset","text":" Bases: BaseDataset
Dataclass containing information about a classification dataset.
Attributes:
Name Type Descriptionclasses
List[str]
List containing dataset class names.
images
Dict[str, np.ndarray]
Dictionary mapping image name to image.
annotations
Dict[str, Detections]
Dictionary mapping image name to annotations.
Source code insupervision/dataset/core.py
@dataclass\nclass ClassificationDataset(BaseDataset):\n\"\"\"\n Dataclass containing information about a classification dataset.\n\n Attributes:\n classes (List[str]): List containing dataset class names.\n images (Dict[str, np.ndarray]): Dictionary mapping image name to image.\n annotations (Dict[str, Detections]): Dictionary mapping image name to annotations.\n \"\"\"\n\n classes: List[str]\n images: Dict[str, np.ndarray]\n annotations: Dict[str, Classifications]\n\n def __len__(self) -> int:\n return len(self.images)\n\n def split(\n self, split_ratio=0.8, random_state=None, shuffle: bool = True\n ) -> Tuple[ClassificationDataset, ClassificationDataset]:\n\"\"\"\n Splits the dataset into two parts (training and testing) using the provided split_ratio.\n\n Args:\n split_ratio (float, optional): The ratio of the training set to the entire dataset.\n random_state (int, optional): The seed for the random number generator. This is used for reproducibility.\n shuffle (bool, optional): Whether to shuffle the data before splitting.\n\n Returns:\n Tuple[ClassificationDataset, ClassificationDataset]: A tuple containing the training and testing datasets.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> cd = sv.ClassificationDataset(...)\n >>> train_cd, test_cd = cd.split(split_ratio=0.7, random_state=42, shuffle=True)\n >>> len(train_cd), len(test_cd)\n (700, 300)\n ```\n \"\"\"\n image_names = list(self.images.keys())\n train_names, test_names = train_test_split(\n data=image_names,\n train_ratio=split_ratio,\n random_state=random_state,\n shuffle=shuffle,\n )\n\n train_dataset = ClassificationDataset(\n classes=self.classes,\n images={name: self.images[name] for name in train_names},\n annotations={name: self.annotations[name] for name in train_names},\n )\n test_dataset = ClassificationDataset(\n classes=self.classes,\n images={name: self.images[name] for name in test_names},\n annotations={name: self.annotations[name] for name in test_names},\n )\n return train_dataset, test_dataset\n\n def as_folder_structure(self, root_directory_path: str) -> None:\n\"\"\"\n Saves the dataset as a multi-class folder structure.\n\n Args:\n root_directory_path (str): The path to the directory where the dataset will be saved.\n \"\"\"\n os.makedirs(root_directory_path, exist_ok=True)\n\n for class_name in self.classes:\n os.makedirs(os.path.join(root_directory_path, class_name), exist_ok=True)\n\n for image_name in self.images:\n classification = self.annotations[image_name]\n image = self.images[image_name]\n class_id = (\n classification.class_id[0]\n if classification.confidence is None\n else classification.get_top_k(1)[0]\n )\n class_name = self.classes[class_id]\n image_path = os.path.join(root_directory_path, class_name, image_name)\n cv2.imwrite(image_path, image)\n\n @classmethod\n def from_folder_structure(cls, root_directory_path: str) -> ClassificationDataset:\n\"\"\"\n Load data from a multiclass folder structure into a ClassificationDataset.\n\n Args:\n root_directory_path (str): The path to the dataset directory.\n\n Returns:\n ClassificationDataset: The dataset.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"folder\")\n\n >>> cd = sv.ClassificationDataset.from_folder_structure(\n ... root_directory_path=f\"{dataset.location}/train\"\n ... )\n ```\n \"\"\"\n classes = os.listdir(root_directory_path)\n classes = sorted(set(classes))\n\n images = {}\n annotations = {}\n\n for class_name in classes:\n class_id = classes.index(class_name)\n\n for image in os.listdir(os.path.join(root_directory_path, class_name)):\n image_dir = os.path.join(root_directory_path, class_name, image)\n images[image] = cv2.imread(image_dir)\n annotations[image] = Classifications(\n class_id=np.array([class_id]),\n )\n\n return cls(\n classes=classes,\n images=images,\n annotations=annotations,\n )\n
"},{"location":"dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure","title":"as_folder_structure(root_directory_path)
","text":"Saves the dataset as a multi-class folder structure.
Parameters:
Name Type Description Defaultroot_directory_path
str
The path to the directory where the dataset will be saved.
required Source code insupervision/dataset/core.py
def as_folder_structure(self, root_directory_path: str) -> None:\n\"\"\"\n Saves the dataset as a multi-class folder structure.\n\n Args:\n root_directory_path (str): The path to the directory where the dataset will be saved.\n \"\"\"\n os.makedirs(root_directory_path, exist_ok=True)\n\n for class_name in self.classes:\n os.makedirs(os.path.join(root_directory_path, class_name), exist_ok=True)\n\n for image_name in self.images:\n classification = self.annotations[image_name]\n image = self.images[image_name]\n class_id = (\n classification.class_id[0]\n if classification.confidence is None\n else classification.get_top_k(1)[0]\n )\n class_name = self.classes[class_id]\n image_path = os.path.join(root_directory_path, class_name, image_name)\n cv2.imwrite(image_path, image)\n
"},{"location":"dataset/core/#supervision.dataset.core.ClassificationDataset.from_folder_structure","title":"from_folder_structure(root_directory_path)
classmethod
","text":"Load data from a multiclass folder structure into a ClassificationDataset.
Parameters:
Name Type Description Defaultroot_directory_path
str
The path to the dataset directory.
requiredReturns:
Name Type DescriptionClassificationDataset
ClassificationDataset
The dataset.
Example>>> import roboflow\n>>> from roboflow import Roboflow\n>>> import supervision as sv\n\n>>> roboflow.login()\n\n>>> rf = Roboflow()\n\n>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n>>> dataset = project.version(PROJECT_VERSION).download(\"folder\")\n\n>>> cd = sv.ClassificationDataset.from_folder_structure(\n... root_directory_path=f\"{dataset.location}/train\"\n... )\n
Source code in supervision/dataset/core.py
@classmethod\ndef from_folder_structure(cls, root_directory_path: str) -> ClassificationDataset:\n\"\"\"\n Load data from a multiclass folder structure into a ClassificationDataset.\n\n Args:\n root_directory_path (str): The path to the dataset directory.\n\n Returns:\n ClassificationDataset: The dataset.\n\n Example:\n ```python\n >>> import roboflow\n >>> from roboflow import Roboflow\n >>> import supervision as sv\n\n >>> roboflow.login()\n\n >>> rf = Roboflow()\n\n >>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)\n >>> dataset = project.version(PROJECT_VERSION).download(\"folder\")\n\n >>> cd = sv.ClassificationDataset.from_folder_structure(\n ... root_directory_path=f\"{dataset.location}/train\"\n ... )\n ```\n \"\"\"\n classes = os.listdir(root_directory_path)\n classes = sorted(set(classes))\n\n images = {}\n annotations = {}\n\n for class_name in classes:\n class_id = classes.index(class_name)\n\n for image in os.listdir(os.path.join(root_directory_path, class_name)):\n image_dir = os.path.join(root_directory_path, class_name, image)\n images[image] = cv2.imread(image_dir)\n annotations[image] = Classifications(\n class_id=np.array([class_id]),\n )\n\n return cls(\n classes=classes,\n images=images,\n annotations=annotations,\n )\n
"},{"location":"dataset/core/#supervision.dataset.core.ClassificationDataset.split","title":"split(split_ratio=0.8, random_state=None, shuffle=True)
","text":"Splits the dataset into two parts (training and testing) using the provided split_ratio.
Parameters:
Name Type Description Defaultsplit_ratio
float
The ratio of the training set to the entire dataset.
0.8
random_state
int
The seed for the random number generator. This is used for reproducibility.
None
shuffle
bool
Whether to shuffle the data before splitting.
True
Returns:
Type DescriptionTuple[ClassificationDataset, ClassificationDataset]
Tuple[ClassificationDataset, ClassificationDataset]: A tuple containing the training and testing datasets.
Example>>> import supervision as sv\n\n>>> cd = sv.ClassificationDataset(...)\n>>> train_cd, test_cd = cd.split(split_ratio=0.7, random_state=42, shuffle=True)\n>>> len(train_cd), len(test_cd)\n(700, 300)\n
Source code in supervision/dataset/core.py
def split(\n self, split_ratio=0.8, random_state=None, shuffle: bool = True\n) -> Tuple[ClassificationDataset, ClassificationDataset]:\n\"\"\"\n Splits the dataset into two parts (training and testing) using the provided split_ratio.\n\n Args:\n split_ratio (float, optional): The ratio of the training set to the entire dataset.\n random_state (int, optional): The seed for the random number generator. This is used for reproducibility.\n shuffle (bool, optional): Whether to shuffle the data before splitting.\n\n Returns:\n Tuple[ClassificationDataset, ClassificationDataset]: A tuple containing the training and testing datasets.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> cd = sv.ClassificationDataset(...)\n >>> train_cd, test_cd = cd.split(split_ratio=0.7, random_state=42, shuffle=True)\n >>> len(train_cd), len(test_cd)\n (700, 300)\n ```\n \"\"\"\n image_names = list(self.images.keys())\n train_names, test_names = train_test_split(\n data=image_names,\n train_ratio=split_ratio,\n random_state=random_state,\n shuffle=shuffle,\n )\n\n train_dataset = ClassificationDataset(\n classes=self.classes,\n images={name: self.images[name] for name in train_names},\n annotations={name: self.annotations[name] for name in train_names},\n )\n test_dataset = ClassificationDataset(\n classes=self.classes,\n images={name: self.images[name] for name in test_names},\n annotations={name: self.annotations[name] for name in test_names},\n )\n return train_dataset, test_dataset\n
"},{"location":"detection/annotate/","title":"Annotate","text":""},{"location":"detection/annotate/#boxannotator","title":"BoxAnnotator","text":"A class for drawing bounding boxes on an image using detections provided.
Attributes:
Name Type Descriptioncolor
Union[Color, ColorPalette]
The color to draw the bounding box, can be a single color or a color palette
thickness
int
The thickness of the bounding box lines, default is 2
text_color
Color
The color of the text on the bounding box, default is white
text_scale
float
The scale of the text on the bounding box, default is 0.5
text_thickness
int
The thickness of the text on the bounding box, default is 1
text_padding
int
The padding around the text on the bounding box, default is 5
Source code insupervision/detection/annotate.py
class BoxAnnotator:\n\"\"\"\n A class for drawing bounding boxes on an image using detections provided.\n\n Attributes:\n color (Union[Color, ColorPalette]): The color to draw the bounding box, can be a single color or a color palette\n thickness (int): The thickness of the bounding box lines, default is 2\n text_color (Color): The color of the text on the bounding box, default is white\n text_scale (float): The scale of the text on the bounding box, default is 0.5\n text_thickness (int): The thickness of the text on the bounding box, default is 1\n text_padding (int): The padding around the text on the bounding box, default is 5\n\n \"\"\"\n\n def __init__(\n self,\n color: Union[Color, ColorPalette] = ColorPalette.default(),\n thickness: int = 2,\n text_color: Color = Color.black(),\n text_scale: float = 0.5,\n text_thickness: int = 1,\n text_padding: int = 10,\n ):\n self.color: Union[Color, ColorPalette] = color\n self.thickness: int = thickness\n self.text_color: Color = text_color\n self.text_scale: float = text_scale\n self.text_thickness: int = text_thickness\n self.text_padding: int = text_padding\n\n def annotate(\n self,\n scene: np.ndarray,\n detections: Detections,\n labels: Optional[List[str]] = None,\n skip_label: bool = False,\n ) -> np.ndarray:\n\"\"\"\n Draws bounding boxes on the frame using the detections provided.\n\n Args:\n scene (np.ndarray): The image on which the bounding boxes will be drawn\n detections (Detections): The detections for which the bounding boxes will be drawn\n labels (Optional[List[str]]): An optional list of labels corresponding to each detection. If `labels` are not provided, corresponding `class_id` will be used as label.\n skip_label (bool): Is set to `True`, skips bounding box label annotation.\n Returns:\n np.ndarray: The image with the bounding boxes drawn on it\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> classes = ['person', ...]\n >>> image = ...\n >>> detections = sv.Detections(...)\n\n >>> box_annotator = sv.BoxAnnotator()\n >>> labels = [\n ... f\"{classes[class_id]} {confidence:0.2f}\"\n ... for _, _, confidence, class_id, _\n ... in detections\n ... ]\n >>> annotated_frame = box_annotator.annotate(\n ... scene=image.copy(),\n ... detections=detections,\n ... labels=labels\n ... )\n ```\n \"\"\"\n font = cv2.FONT_HERSHEY_SIMPLEX\n for i in range(len(detections)):\n x1, y1, x2, y2 = detections.xyxy[i].astype(int)\n class_id = (\n detections.class_id[i] if detections.class_id is not None else None\n )\n idx = class_id if class_id is not None else i\n color = (\n self.color.by_idx(idx)\n if isinstance(self.color, ColorPalette)\n else self.color\n )\n cv2.rectangle(\n img=scene,\n pt1=(x1, y1),\n pt2=(x2, y2),\n color=color.as_bgr(),\n thickness=self.thickness,\n )\n if skip_label:\n continue\n\n text = (\n f\"{class_id}\"\n if (labels is None or len(detections) != len(labels))\n else labels[i]\n )\n\n text_width, text_height = cv2.getTextSize(\n text=text,\n fontFace=font,\n fontScale=self.text_scale,\n thickness=self.text_thickness,\n )[0]\n\n text_x = x1 + self.text_padding\n text_y = y1 - self.text_padding\n\n text_background_x1 = x1\n text_background_y1 = y1 - 2 * self.text_padding - text_height\n\n text_background_x2 = x1 + 2 * self.text_padding + text_width\n text_background_y2 = y1\n\n cv2.rectangle(\n img=scene,\n pt1=(text_background_x1, text_background_y1),\n pt2=(text_background_x2, text_background_y2),\n color=color.as_bgr(),\n thickness=cv2.FILLED,\n )\n cv2.putText(\n img=scene,\n text=text,\n org=(text_x, text_y),\n fontFace=font,\n fontScale=self.text_scale,\n color=self.text_color.as_rgb(),\n thickness=self.text_thickness,\n lineType=cv2.LINE_AA,\n )\n return scene\n
"},{"location":"detection/annotate/#supervision.detection.annotate.BoxAnnotator.annotate","title":"annotate(scene, detections, labels=None, skip_label=False)
","text":"Draws bounding boxes on the frame using the detections provided.
Parameters:
Name Type Description Defaultscene
np.ndarray
The image on which the bounding boxes will be drawn
requireddetections
Detections
The detections for which the bounding boxes will be drawn
requiredlabels
Optional[List[str]]
An optional list of labels corresponding to each detection. If labels
are not provided, corresponding class_id
will be used as label.
None
skip_label
bool
Is set to True
, skips bounding box label annotation.
False
Returns:
Type Descriptionnp.ndarray
np.ndarray: The image with the bounding boxes drawn on it
Example>>> import supervision as sv\n\n>>> classes = ['person', ...]\n>>> image = ...\n>>> detections = sv.Detections(...)\n\n>>> box_annotator = sv.BoxAnnotator()\n>>> labels = [\n... f\"{classes[class_id]} {confidence:0.2f}\"\n... for _, _, confidence, class_id, _\n... in detections\n... ]\n>>> annotated_frame = box_annotator.annotate(\n... scene=image.copy(),\n... detections=detections,\n... labels=labels\n... )\n
Source code in supervision/detection/annotate.py
def annotate(\n self,\n scene: np.ndarray,\n detections: Detections,\n labels: Optional[List[str]] = None,\n skip_label: bool = False,\n) -> np.ndarray:\n\"\"\"\n Draws bounding boxes on the frame using the detections provided.\n\n Args:\n scene (np.ndarray): The image on which the bounding boxes will be drawn\n detections (Detections): The detections for which the bounding boxes will be drawn\n labels (Optional[List[str]]): An optional list of labels corresponding to each detection. If `labels` are not provided, corresponding `class_id` will be used as label.\n skip_label (bool): Is set to `True`, skips bounding box label annotation.\n Returns:\n np.ndarray: The image with the bounding boxes drawn on it\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> classes = ['person', ...]\n >>> image = ...\n >>> detections = sv.Detections(...)\n\n >>> box_annotator = sv.BoxAnnotator()\n >>> labels = [\n ... f\"{classes[class_id]} {confidence:0.2f}\"\n ... for _, _, confidence, class_id, _\n ... in detections\n ... ]\n >>> annotated_frame = box_annotator.annotate(\n ... scene=image.copy(),\n ... detections=detections,\n ... labels=labels\n ... )\n ```\n \"\"\"\n font = cv2.FONT_HERSHEY_SIMPLEX\n for i in range(len(detections)):\n x1, y1, x2, y2 = detections.xyxy[i].astype(int)\n class_id = (\n detections.class_id[i] if detections.class_id is not None else None\n )\n idx = class_id if class_id is not None else i\n color = (\n self.color.by_idx(idx)\n if isinstance(self.color, ColorPalette)\n else self.color\n )\n cv2.rectangle(\n img=scene,\n pt1=(x1, y1),\n pt2=(x2, y2),\n color=color.as_bgr(),\n thickness=self.thickness,\n )\n if skip_label:\n continue\n\n text = (\n f\"{class_id}\"\n if (labels is None or len(detections) != len(labels))\n else labels[i]\n )\n\n text_width, text_height = cv2.getTextSize(\n text=text,\n fontFace=font,\n fontScale=self.text_scale,\n thickness=self.text_thickness,\n )[0]\n\n text_x = x1 + self.text_padding\n text_y = y1 - self.text_padding\n\n text_background_x1 = x1\n text_background_y1 = y1 - 2 * self.text_padding - text_height\n\n text_background_x2 = x1 + 2 * self.text_padding + text_width\n text_background_y2 = y1\n\n cv2.rectangle(\n img=scene,\n pt1=(text_background_x1, text_background_y1),\n pt2=(text_background_x2, text_background_y2),\n color=color.as_bgr(),\n thickness=cv2.FILLED,\n )\n cv2.putText(\n img=scene,\n text=text,\n org=(text_x, text_y),\n fontFace=font,\n fontScale=self.text_scale,\n color=self.text_color.as_rgb(),\n thickness=self.text_thickness,\n lineType=cv2.LINE_AA,\n )\n return scene\n
"},{"location":"detection/annotate/#maskannotator","title":"MaskAnnotator","text":"A class for overlaying masks on an image using detections provided.
Attributes:
Name Type Descriptioncolor
Union[Color, ColorPalette]
The color to fill the mask, can be a single color or a color palette
Source code insupervision/detection/annotate.py
class MaskAnnotator:\n\"\"\"\n A class for overlaying masks on an image using detections provided.\n\n Attributes:\n color (Union[Color, ColorPalette]): The color to fill the mask, can be a single color or a color palette\n \"\"\"\n\n def __init__(\n self,\n color: Union[Color, ColorPalette] = ColorPalette.default(),\n ):\n self.color: Union[Color, ColorPalette] = color\n\n def annotate(\n self, scene: np.ndarray, detections: Detections, opacity: float = 0.5\n ) -> np.ndarray:\n\"\"\"\n Overlays the masks on the given image based on the provided detections, with a specified opacity.\n\n Args:\n scene (np.ndarray): The image on which the masks will be overlaid\n detections (Detections): The detections for which the masks will be overlaid\n opacity (float): The opacity of the masks, between 0 and 1, default is 0.5\n\n Returns:\n np.ndarray: The image with the masks overlaid\n \"\"\"\n if detections.mask is None:\n return scene\n\n for i in np.flip(np.argsort(detections.area)):\n class_id = (\n detections.class_id[i] if detections.class_id is not None else None\n )\n idx = class_id if class_id is not None else i\n color = (\n self.color.by_idx(idx)\n if isinstance(self.color, ColorPalette)\n else self.color\n )\n\n mask = detections.mask[i]\n colored_mask = np.zeros_like(scene, dtype=np.uint8)\n colored_mask[:] = color.as_bgr()\n\n scene = np.where(\n np.expand_dims(mask, axis=-1),\n np.uint8(opacity * colored_mask + (1 - opacity) * scene),\n scene,\n )\n\n return scene\n
"},{"location":"detection/annotate/#supervision.detection.annotate.MaskAnnotator.annotate","title":"annotate(scene, detections, opacity=0.5)
","text":"Overlays the masks on the given image based on the provided detections, with a specified opacity.
Parameters:
Name Type Description Defaultscene
np.ndarray
The image on which the masks will be overlaid
requireddetections
Detections
The detections for which the masks will be overlaid
requiredopacity
float
The opacity of the masks, between 0 and 1, default is 0.5
0.5
Returns:
Type Descriptionnp.ndarray
np.ndarray: The image with the masks overlaid
Source code insupervision/detection/annotate.py
def annotate(\n self, scene: np.ndarray, detections: Detections, opacity: float = 0.5\n) -> np.ndarray:\n\"\"\"\n Overlays the masks on the given image based on the provided detections, with a specified opacity.\n\n Args:\n scene (np.ndarray): The image on which the masks will be overlaid\n detections (Detections): The detections for which the masks will be overlaid\n opacity (float): The opacity of the masks, between 0 and 1, default is 0.5\n\n Returns:\n np.ndarray: The image with the masks overlaid\n \"\"\"\n if detections.mask is None:\n return scene\n\n for i in np.flip(np.argsort(detections.area)):\n class_id = (\n detections.class_id[i] if detections.class_id is not None else None\n )\n idx = class_id if class_id is not None else i\n color = (\n self.color.by_idx(idx)\n if isinstance(self.color, ColorPalette)\n else self.color\n )\n\n mask = detections.mask[i]\n colored_mask = np.zeros_like(scene, dtype=np.uint8)\n colored_mask[:] = color.as_bgr()\n\n scene = np.where(\n np.expand_dims(mask, axis=-1),\n np.uint8(opacity * colored_mask + (1 - opacity) * scene),\n scene,\n )\n\n return scene\n
"},{"location":"detection/core/","title":"Core","text":""},{"location":"detection/core/#detections","title":"Detections","text":"Data class containing information about the detections in a video frame.
Attributes:
Name Type Descriptionxyxy
np.ndarray
An array of shape (n, 4)
containing the bounding boxes coordinates in format [x1, y1, x2, y2]
mask
np.Optional[np.ndarray]
(Optional[np.ndarray]): An array of shape (n, W, H)
containing the segmentation masks.
confidence
Optional[np.ndarray]
An array of shape (n,)
containing the confidence scores of the detections.
class_id
Optional[np.ndarray]
An array of shape (n,)
containing the class ids of the detections.
tracker_id
Optional[np.ndarray]
An array of shape (n,)
containing the tracker ids of the detections.
supervision/detection/core.py
@dataclass\nclass Detections:\n\"\"\"\n Data class containing information about the detections in a video frame.\n Attributes:\n xyxy (np.ndarray): An array of shape `(n, 4)` containing the bounding boxes coordinates in format `[x1, y1, x2, y2]`\n mask: (Optional[np.ndarray]): An array of shape `(n, W, H)` containing the segmentation masks.\n confidence (Optional[np.ndarray]): An array of shape `(n,)` containing the confidence scores of the detections.\n class_id (Optional[np.ndarray]): An array of shape `(n,)` containing the class ids of the detections.\n tracker_id (Optional[np.ndarray]): An array of shape `(n,)` containing the tracker ids of the detections.\n \"\"\"\n\n xyxy: np.ndarray\n mask: np.Optional[np.ndarray] = None\n confidence: Optional[np.ndarray] = None\n class_id: Optional[np.ndarray] = None\n tracker_id: Optional[np.ndarray] = None\n\n def __post_init__(self):\n n = len(self.xyxy)\n _validate_xyxy(xyxy=self.xyxy, n=n)\n _validate_mask(mask=self.mask, n=n)\n _validate_class_id(class_id=self.class_id, n=n)\n _validate_confidence(confidence=self.confidence, n=n)\n _validate_tracker_id(tracker_id=self.tracker_id, n=n)\n\n def __len__(self):\n\"\"\"\n Returns the number of detections in the Detections object.\n \"\"\"\n return len(self.xyxy)\n\n def __iter__(\n self,\n ) -> Iterator[\n Tuple[\n np.ndarray,\n Optional[np.ndarray],\n Optional[float],\n Optional[int],\n Optional[int],\n ]\n ]:\n\"\"\"\n Iterates over the Detections object and yield a tuple of `(xyxy, mask, confidence, class_id, tracker_id)` for each detection.\n \"\"\"\n for i in range(len(self.xyxy)):\n yield (\n self.xyxy[i],\n self.mask[i] if self.mask is not None else None,\n self.confidence[i] if self.confidence is not None else None,\n self.class_id[i] if self.class_id is not None else None,\n self.tracker_id[i] if self.tracker_id is not None else None,\n )\n\n def __eq__(self, other: Detections):\n return all(\n [\n np.array_equal(self.xyxy, other.xyxy),\n any(\n [\n self.mask is None and other.mask is None,\n np.array_equal(self.mask, other.mask),\n ]\n ),\n any(\n [\n self.class_id is None and other.class_id is None,\n np.array_equal(self.class_id, other.class_id),\n ]\n ),\n any(\n [\n self.confidence is None and other.confidence is None,\n np.array_equal(self.confidence, other.confidence),\n ]\n ),\n any(\n [\n self.tracker_id is None and other.tracker_id is None,\n np.array_equal(self.tracker_id, other.tracker_id),\n ]\n ),\n ]\n )\n\n @classmethod\n def from_yolov5(cls, yolov5_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLOv5](https://github.com/ultralytics/yolov5) inference result.\n\n Args:\n yolov5_results (yolov5.models.common.Detections): The output Detections instance from YOLOv5\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> import torch\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')\n >>> result = model(image)\n >>> detections = sv.Detections.from_yolov5(result)\n ```\n \"\"\"\n yolov5_detections_predictions = yolov5_results.pred[0].cpu().cpu().numpy()\n return cls(\n xyxy=yolov5_detections_predictions[:, :4],\n confidence=yolov5_detections_predictions[:, 4],\n class_id=yolov5_detections_predictions[:, 5].astype(int),\n )\n\n @classmethod\n def from_yolov8(cls, yolov8_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLOv8](https://github.com/ultralytics/ultralytics) inference result.\n\n Args:\n yolov8_results (ultralytics.yolo.engine.results.Results): The output Results instance from YOLOv8\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> from ultralytics import YOLO\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = YOLO('yolov8s.pt')\n >>> result = model(image)[0]\n >>> detections = sv.Detections.from_yolov8(result)\n ```\n \"\"\"\n return cls(\n xyxy=yolov8_results.boxes.xyxy.cpu().numpy(),\n confidence=yolov8_results.boxes.conf.cpu().numpy(),\n class_id=yolov8_results.boxes.cls.cpu().numpy().astype(int),\n mask=extract_yolov8_masks(yolov8_results),\n )\n\n @classmethod\n def from_yolo_nas(cls, yolo_nas_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md) inference result.\n\n Args:\n yolo_nas_results (super_gradients.training.models.prediction_results.ImageDetectionPrediction): The output Results instance from YOLO-NAS\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> from super_gradients.training import models\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = models.get('yolo_nas_l', pretrained_weights=\"coco\")\n >>> result = list(model.predict(image, conf=0.35))[0]\n >>> detections = sv.Detections.from_yolo_nas(result)\n ```\n \"\"\"\n return cls(\n xyxy=yolo_nas_results.prediction.bboxes_xyxy,\n confidence=yolo_nas_results.prediction.confidence,\n class_id=yolo_nas_results.prediction.labels.astype(int),\n )\n\n @classmethod\n def from_transformers(cls, transformers_results: dict) -> Detections:\n\"\"\"\n Creates a Detections instance from object detection [transformer](https://github.com/huggingface/transformers) inference result.\n\n Returns:\n Detections: A new Detections object.\n \"\"\"\n return cls(\n xyxy=transformers_results[\"boxes\"].cpu().numpy(),\n confidence=transformers_results[\"scores\"].cpu().numpy(),\n class_id=transformers_results[\"labels\"].cpu().numpy().astype(int),\n )\n\n @classmethod\n def from_detectron2(cls, detectron2_results) -> Detections:\n\"\"\"\n Create a Detections object from the [Detectron2](https://github.com/facebookresearch/detectron2) inference result.\n\n Args:\n detectron2_results: The output of a Detectron2 model containing instances with prediction data.\n\n Returns:\n (Detections): A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.\n\n Example:\n ```python\n >>> import cv2\n >>> from detectron2.engine import DefaultPredictor\n >>> from detectron2.config import get_cfg\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> cfg = get_cfg()\n >>> cfg.merge_from_file(\"path/to/config.yaml\")\n >>> cfg.MODEL.WEIGHTS = \"path/to/model_weights.pth\"\n >>> predictor = DefaultPredictor(cfg)\n >>> result = predictor(image)\n\n >>> detections = sv.Detections.from_detectron2(result)\n ```\n \"\"\"\n return cls(\n xyxy=detectron2_results[\"instances\"].pred_boxes.tensor.cpu().numpy(),\n confidence=detectron2_results[\"instances\"].scores.cpu().numpy(),\n class_id=detectron2_results[\"instances\"]\n .pred_classes.cpu()\n .numpy()\n .astype(int),\n )\n\n @classmethod\n def from_roboflow(cls, roboflow_result: dict, class_list: List[str]) -> Detections:\n\"\"\"\n Create a Detections object from the [Roboflow](https://roboflow.com/) API inference result.\n\n Args:\n roboflow_result (dict): The result from the Roboflow API containing predictions.\n class_list (List[str]): A list of class names corresponding to the class IDs in the API result.\n\n Returns:\n (Detections): A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> roboflow_result = {\n ... \"predictions\": [\n ... {\n ... \"x\": 0.5,\n ... \"y\": 0.5,\n ... \"width\": 0.2,\n ... \"height\": 0.3,\n ... \"class\": \"person\",\n ... \"confidence\": 0.9\n ... },\n ... # ... more predictions ...\n ... ]\n ... }\n >>> class_list = [\"person\", \"car\", \"dog\"]\n\n >>> detections = sv.Detections.from_roboflow(roboflow_result, class_list)\n ```\n \"\"\"\n xyxy, confidence, class_id, masks = process_roboflow_result(\n roboflow_result=roboflow_result, class_list=class_list\n )\n return Detections(\n xyxy=xyxy,\n confidence=confidence,\n class_id=class_id,\n mask=masks,\n )\n\n @classmethod\n def from_sam(cls, sam_result: List[dict]) -> Detections:\n\"\"\"\n Creates a Detections instance from [Segment Anything Model](https://github.com/facebookresearch/segment-anything) inference result.\n\n Args:\n sam_result (List[dict]): The output Results instance from SAM\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import supervision as sv\n >>> from segment_anything import sam_model_registry, SamAutomaticMaskGenerator\n\n >>> sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)\n >>> mask_generator = SamAutomaticMaskGenerator(sam)\n >>> sam_result = mask_generator.generate(IMAGE)\n >>> detections = sv.Detections.from_sam(sam_result=sam_result)\n ```\n \"\"\"\n sorted_generated_masks = sorted(\n sam_result, key=lambda x: x[\"area\"], reverse=True\n )\n\n xywh = np.array([mask[\"bbox\"] for mask in sorted_generated_masks])\n mask = np.array([mask[\"segmentation\"] for mask in sorted_generated_masks])\n\n return Detections(xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask)\n\n @classmethod\n def empty(cls) -> Detections:\n\"\"\"\n Create an empty Detections object with no bounding boxes, confidences, or class IDs.\n\n Returns:\n (Detections): An empty Detections object.\n\n Example:\n ```python\n >>> from supervision import Detections\n\n >>> empty_detections = Detections.empty()\n ```\n \"\"\"\n return cls(\n xyxy=np.empty((0, 4), dtype=np.float32),\n confidence=np.array([], dtype=np.float32),\n class_id=np.array([], dtype=int),\n )\n\n @classmethod\n def merge(cls, detections_list: List[Detections]) -> Detections:\n\"\"\"\n Merge a list of Detections objects into a single Detections object.\n\n This method takes a list of Detections objects and combines their respective fields (`xyxy`, `mask`,\n `confidence`, `class_id`, and `tracker_id`) into a single Detections object. If all elements in a field are not\n `None`, the corresponding field will be stacked. Otherwise, the field will be set to `None`.\n\n Args:\n detections_list (List[Detections]): A list of Detections objects to merge.\n\n Returns:\n (Detections): A single Detections object containing the merged data from the input list.\n\n Example:\n ```python\n >>> from supervision import Detections\n\n >>> detections_1 = Detections(...)\n >>> detections_2 = Detections(...)\n\n >>> merged_detections = Detections.merge([detections_1, detections_2])\n ```\n \"\"\"\n if len(detections_list) == 0:\n return Detections.empty()\n\n detections_tuples_list = [astuple(detection) for detection in detections_list]\n xyxy, mask, confidence, class_id, tracker_id = [\n list(field) for field in zip(*detections_tuples_list)\n ]\n\n all_not_none = lambda l: all(x is not None for x in l)\n\n xyxy = np.vstack(xyxy)\n mask = np.vstack(mask) if all_not_none(mask) else None\n confidence = np.hstack(confidence) if all_not_none(confidence) else None\n class_id = np.hstack(class_id) if all_not_none(class_id) else None\n tracker_id = np.hstack(tracker_id) if all_not_none(tracker_id) else None\n\n return cls(\n xyxy=xyxy,\n mask=mask,\n confidence=confidence,\n class_id=class_id,\n tracker_id=tracker_id,\n )\n\n def get_anchor_coordinates(self, anchor: Position) -> np.ndarray:\n\"\"\"\n Returns the bounding box coordinates for a specific anchor.\n\n Args:\n anchor (Position): Position of bounding box anchor for which to return the coordinates.\n\n Returns:\n np.ndarray: An array of shape `(n, 2)` containing the bounding box anchor coordinates in format `[x, y]`.\n \"\"\"\n if anchor == Position.CENTER:\n return np.array(\n [\n (self.xyxy[:, 0] + self.xyxy[:, 2]) / 2,\n (self.xyxy[:, 1] + self.xyxy[:, 3]) / 2,\n ]\n ).transpose()\n elif anchor == Position.BOTTOM_CENTER:\n return np.array(\n [(self.xyxy[:, 0] + self.xyxy[:, 2]) / 2, self.xyxy[:, 3]]\n ).transpose()\n\n raise ValueError(f\"{anchor} is not supported.\")\n\n def __getitem__(\n self, index: Union[int, slice, List[int], np.ndarray]\n ) -> Detections:\n\"\"\"\n Get a subset of the Detections object.\n\n Args:\n index (Union[int, slice, List[int], np.ndarray]): The index or indices of the subset of the Detections\n\n Returns:\n (Detections): A subset of the Detections object.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> detections = sv.Detections(...)\n\n >>> first_detection = detections[0]\n\n >>> first_10_detections = detections[0:10]\n\n >>> some_detections = detections[[0, 2, 4]]\n\n >>> class_0_detections = detections[detections.class_id == 0]\n\n >>> high_confidence_detections = detections[detections.confidence > 0.5]\n ```\n \"\"\"\n if isinstance(index, int):\n index = [index]\n return Detections(\n xyxy=self.xyxy[index],\n mask=self.mask[index] if self.mask is not None else None,\n confidence=self.confidence[index] if self.confidence is not None else None,\n class_id=self.class_id[index] if self.class_id is not None else None,\n tracker_id=self.tracker_id[index] if self.tracker_id is not None else None,\n )\n\n @property\n def area(self) -> np.ndarray:\n\"\"\"\n Calculate the area of each detection in the set of object detections. If masks field is defined property\n returns are of each mask. If only box is given property return area of each box.\n\n Returns:\n np.ndarray: An array of floats containing the area of each detection in the format of `(area_1, area_2, ..., area_n)`, where n is the number of detections.\n \"\"\"\n if self.mask is not None:\n return np.array([np.sum(mask) for mask in self.mask])\n else:\n return self.box_area\n\n @property\n def box_area(self) -> np.ndarray:\n\"\"\"\n Calculate the area of each bounding box in the set of object detections.\n\n Returns:\n np.ndarray: An array of floats containing the area of each bounding box in the format of `(area_1, area_2, ..., area_n)`, where n is the number of detections.\n \"\"\"\n return (self.xyxy[:, 3] - self.xyxy[:, 1]) * (self.xyxy[:, 2] - self.xyxy[:, 0])\n\n def with_nms(\n self, threshold: float = 0.5, class_agnostic: bool = False\n ) -> Detections:\n\"\"\"\n Perform non-maximum suppression on the current set of object detections.\n\n Args:\n threshold (float, optional): The intersection-over-union threshold to use for non-maximum suppression. Defaults to 0.5.\n class_agnostic (bool, optional): Whether to perform class-agnostic non-maximum suppression. If True, the class_id of each detection will be ignored. Defaults to False.\n\n Returns:\n Detections: A new Detections object containing the subset of detections after non-maximum suppression.\n\n Raises:\n AssertionError: If `confidence` is None and class_agnostic is False. If `class_id` is None and class_agnostic is False.\n \"\"\"\n if len(self) == 0:\n return self\n\n assert (\n self.confidence is not None\n ), f\"Detections confidence must be given for NMS to be executed.\"\n\n if class_agnostic:\n predictions = np.hstack((self.xyxy, self.confidence.reshape(-1, 1)))\n indices = non_max_suppression(\n predictions=predictions, iou_threshold=threshold\n )\n return self[indices]\n\n assert self.class_id is not None, (\n f\"Detections class_id must be given for NMS to be executed. If you intended to perform class agnostic \"\n f\"NMS set class_agnostic=True.\"\n )\n\n predictions = np.hstack(\n (self.xyxy, self.confidence.reshape(-1, 1), self.class_id.reshape(-1, 1))\n )\n indices = non_max_suppression(predictions=predictions, iou_threshold=threshold)\n return self[indices]\n
"},{"location":"detection/core/#supervision.detection.core.Detections.area","title":"area: np.ndarray
property
","text":"Calculate the area of each detection in the set of object detections. If masks field is defined property returns are of each mask. If only box is given property return area of each box.
Returns:
Type Descriptionnp.ndarray
np.ndarray: An array of floats containing the area of each detection in the format of (area_1, area_2, ..., area_n)
, where n is the number of detections.
box_area: np.ndarray
property
","text":"Calculate the area of each bounding box in the set of object detections.
Returns:
Type Descriptionnp.ndarray
np.ndarray: An array of floats containing the area of each bounding box in the format of (area_1, area_2, ..., area_n)
, where n is the number of detections.
__getitem__(index)
","text":"Get a subset of the Detections object.
Parameters:
Name Type Description Defaultindex
Union[int, slice, List[int], np.ndarray]
The index or indices of the subset of the Detections
requiredReturns:
Type DescriptionDetections
A subset of the Detections object.
Example>>> import supervision as sv\n\n>>> detections = sv.Detections(...)\n\n>>> first_detection = detections[0]\n\n>>> first_10_detections = detections[0:10]\n\n>>> some_detections = detections[[0, 2, 4]]\n\n>>> class_0_detections = detections[detections.class_id == 0]\n\n>>> high_confidence_detections = detections[detections.confidence > 0.5]\n
Source code in supervision/detection/core.py
def __getitem__(\n self, index: Union[int, slice, List[int], np.ndarray]\n) -> Detections:\n\"\"\"\n Get a subset of the Detections object.\n\n Args:\n index (Union[int, slice, List[int], np.ndarray]): The index or indices of the subset of the Detections\n\n Returns:\n (Detections): A subset of the Detections object.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> detections = sv.Detections(...)\n\n >>> first_detection = detections[0]\n\n >>> first_10_detections = detections[0:10]\n\n >>> some_detections = detections[[0, 2, 4]]\n\n >>> class_0_detections = detections[detections.class_id == 0]\n\n >>> high_confidence_detections = detections[detections.confidence > 0.5]\n ```\n \"\"\"\n if isinstance(index, int):\n index = [index]\n return Detections(\n xyxy=self.xyxy[index],\n mask=self.mask[index] if self.mask is not None else None,\n confidence=self.confidence[index] if self.confidence is not None else None,\n class_id=self.class_id[index] if self.class_id is not None else None,\n tracker_id=self.tracker_id[index] if self.tracker_id is not None else None,\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.__iter__","title":"__iter__()
","text":"Iterates over the Detections object and yield a tuple of (xyxy, mask, confidence, class_id, tracker_id)
for each detection.
supervision/detection/core.py
def __iter__(\n self,\n) -> Iterator[\n Tuple[\n np.ndarray,\n Optional[np.ndarray],\n Optional[float],\n Optional[int],\n Optional[int],\n ]\n]:\n\"\"\"\n Iterates over the Detections object and yield a tuple of `(xyxy, mask, confidence, class_id, tracker_id)` for each detection.\n \"\"\"\n for i in range(len(self.xyxy)):\n yield (\n self.xyxy[i],\n self.mask[i] if self.mask is not None else None,\n self.confidence[i] if self.confidence is not None else None,\n self.class_id[i] if self.class_id is not None else None,\n self.tracker_id[i] if self.tracker_id is not None else None,\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.__len__","title":"__len__()
","text":"Returns the number of detections in the Detections object.
Source code insupervision/detection/core.py
def __len__(self):\n\"\"\"\n Returns the number of detections in the Detections object.\n \"\"\"\n return len(self.xyxy)\n
"},{"location":"detection/core/#supervision.detection.core.Detections.empty","title":"empty()
classmethod
","text":"Create an empty Detections object with no bounding boxes, confidences, or class IDs.
Returns:
Type DescriptionDetections
An empty Detections object.
Example>>> from supervision import Detections\n\n>>> empty_detections = Detections.empty()\n
Source code in supervision/detection/core.py
@classmethod\ndef empty(cls) -> Detections:\n\"\"\"\n Create an empty Detections object with no bounding boxes, confidences, or class IDs.\n\n Returns:\n (Detections): An empty Detections object.\n\n Example:\n ```python\n >>> from supervision import Detections\n\n >>> empty_detections = Detections.empty()\n ```\n \"\"\"\n return cls(\n xyxy=np.empty((0, 4), dtype=np.float32),\n confidence=np.array([], dtype=np.float32),\n class_id=np.array([], dtype=int),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_detectron2","title":"from_detectron2(detectron2_results)
classmethod
","text":"Create a Detections object from the Detectron2 inference result.
Parameters:
Name Type Description Defaultdetectron2_results
The output of a Detectron2 model containing instances with prediction data.
requiredReturns:
Type DescriptionDetections
A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.
Example>>> import cv2\n>>> from detectron2.engine import DefaultPredictor\n>>> from detectron2.config import get_cfg\n>>> import supervision as sv\n\n>>> image = cv2.imread(SOURCE_IMAGE_PATH)\n>>> cfg = get_cfg()\n>>> cfg.merge_from_file(\"path/to/config.yaml\")\n>>> cfg.MODEL.WEIGHTS = \"path/to/model_weights.pth\"\n>>> predictor = DefaultPredictor(cfg)\n>>> result = predictor(image)\n\n>>> detections = sv.Detections.from_detectron2(result)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_detectron2(cls, detectron2_results) -> Detections:\n\"\"\"\n Create a Detections object from the [Detectron2](https://github.com/facebookresearch/detectron2) inference result.\n\n Args:\n detectron2_results: The output of a Detectron2 model containing instances with prediction data.\n\n Returns:\n (Detections): A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.\n\n Example:\n ```python\n >>> import cv2\n >>> from detectron2.engine import DefaultPredictor\n >>> from detectron2.config import get_cfg\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> cfg = get_cfg()\n >>> cfg.merge_from_file(\"path/to/config.yaml\")\n >>> cfg.MODEL.WEIGHTS = \"path/to/model_weights.pth\"\n >>> predictor = DefaultPredictor(cfg)\n >>> result = predictor(image)\n\n >>> detections = sv.Detections.from_detectron2(result)\n ```\n \"\"\"\n return cls(\n xyxy=detectron2_results[\"instances\"].pred_boxes.tensor.cpu().numpy(),\n confidence=detectron2_results[\"instances\"].scores.cpu().numpy(),\n class_id=detectron2_results[\"instances\"]\n .pred_classes.cpu()\n .numpy()\n .astype(int),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_roboflow","title":"from_roboflow(roboflow_result, class_list)
classmethod
","text":"Create a Detections object from the Roboflow API inference result.
Parameters:
Name Type Description Defaultroboflow_result
dict
The result from the Roboflow API containing predictions.
requiredclass_list
List[str]
A list of class names corresponding to the class IDs in the API result.
requiredReturns:
Type DescriptionDetections
A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.
Example>>> import supervision as sv\n\n>>> roboflow_result = {\n... \"predictions\": [\n... {\n... \"x\": 0.5,\n... \"y\": 0.5,\n... \"width\": 0.2,\n... \"height\": 0.3,\n... \"class\": \"person\",\n... \"confidence\": 0.9\n... },\n... # ... more predictions ...\n... ]\n... }\n>>> class_list = [\"person\", \"car\", \"dog\"]\n\n>>> detections = sv.Detections.from_roboflow(roboflow_result, class_list)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_roboflow(cls, roboflow_result: dict, class_list: List[str]) -> Detections:\n\"\"\"\n Create a Detections object from the [Roboflow](https://roboflow.com/) API inference result.\n\n Args:\n roboflow_result (dict): The result from the Roboflow API containing predictions.\n class_list (List[str]): A list of class names corresponding to the class IDs in the API result.\n\n Returns:\n (Detections): A Detections object containing the bounding boxes, class IDs, and confidences of the predictions.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> roboflow_result = {\n ... \"predictions\": [\n ... {\n ... \"x\": 0.5,\n ... \"y\": 0.5,\n ... \"width\": 0.2,\n ... \"height\": 0.3,\n ... \"class\": \"person\",\n ... \"confidence\": 0.9\n ... },\n ... # ... more predictions ...\n ... ]\n ... }\n >>> class_list = [\"person\", \"car\", \"dog\"]\n\n >>> detections = sv.Detections.from_roboflow(roboflow_result, class_list)\n ```\n \"\"\"\n xyxy, confidence, class_id, masks = process_roboflow_result(\n roboflow_result=roboflow_result, class_list=class_list\n )\n return Detections(\n xyxy=xyxy,\n confidence=confidence,\n class_id=class_id,\n mask=masks,\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_sam","title":"from_sam(sam_result)
classmethod
","text":"Creates a Detections instance from Segment Anything Model inference result.
Parameters:
Name Type Description Defaultsam_result
List[dict]
The output Results instance from SAM
requiredReturns:
Name Type DescriptionDetections
Detections
A new Detections object.
Example>>> import supervision as sv\n>>> from segment_anything import sam_model_registry, SamAutomaticMaskGenerator\n\n>>> sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)\n>>> mask_generator = SamAutomaticMaskGenerator(sam)\n>>> sam_result = mask_generator.generate(IMAGE)\n>>> detections = sv.Detections.from_sam(sam_result=sam_result)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_sam(cls, sam_result: List[dict]) -> Detections:\n\"\"\"\n Creates a Detections instance from [Segment Anything Model](https://github.com/facebookresearch/segment-anything) inference result.\n\n Args:\n sam_result (List[dict]): The output Results instance from SAM\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import supervision as sv\n >>> from segment_anything import sam_model_registry, SamAutomaticMaskGenerator\n\n >>> sam = sam_model_registry[MODEL_TYPE](checkpoint=CHECKPOINT_PATH).to(device=DEVICE)\n >>> mask_generator = SamAutomaticMaskGenerator(sam)\n >>> sam_result = mask_generator.generate(IMAGE)\n >>> detections = sv.Detections.from_sam(sam_result=sam_result)\n ```\n \"\"\"\n sorted_generated_masks = sorted(\n sam_result, key=lambda x: x[\"area\"], reverse=True\n )\n\n xywh = np.array([mask[\"bbox\"] for mask in sorted_generated_masks])\n mask = np.array([mask[\"segmentation\"] for mask in sorted_generated_masks])\n\n return Detections(xyxy=xywh_to_xyxy(boxes_xywh=xywh), mask=mask)\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_transformers","title":"from_transformers(transformers_results)
classmethod
","text":"Creates a Detections instance from object detection transformer inference result.
Returns:
Name Type DescriptionDetections
Detections
A new Detections object.
Source code insupervision/detection/core.py
@classmethod\ndef from_transformers(cls, transformers_results: dict) -> Detections:\n\"\"\"\n Creates a Detections instance from object detection [transformer](https://github.com/huggingface/transformers) inference result.\n\n Returns:\n Detections: A new Detections object.\n \"\"\"\n return cls(\n xyxy=transformers_results[\"boxes\"].cpu().numpy(),\n confidence=transformers_results[\"scores\"].cpu().numpy(),\n class_id=transformers_results[\"labels\"].cpu().numpy().astype(int),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_yolo_nas","title":"from_yolo_nas(yolo_nas_results)
classmethod
","text":"Creates a Detections instance from a YOLO-NAS inference result.
Parameters:
Name Type Description Defaultyolo_nas_results
super_gradients.training.models.prediction_results.ImageDetectionPrediction
The output Results instance from YOLO-NAS
requiredReturns:
Name Type DescriptionDetections
Detections
A new Detections object.
Example>>> import cv2\n>>> from super_gradients.training import models\n>>> import supervision as sv\n\n>>> image = cv2.imread(SOURCE_IMAGE_PATH)\n>>> model = models.get('yolo_nas_l', pretrained_weights=\"coco\")\n>>> result = list(model.predict(image, conf=0.35))[0]\n>>> detections = sv.Detections.from_yolo_nas(result)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_yolo_nas(cls, yolo_nas_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md) inference result.\n\n Args:\n yolo_nas_results (super_gradients.training.models.prediction_results.ImageDetectionPrediction): The output Results instance from YOLO-NAS\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> from super_gradients.training import models\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = models.get('yolo_nas_l', pretrained_weights=\"coco\")\n >>> result = list(model.predict(image, conf=0.35))[0]\n >>> detections = sv.Detections.from_yolo_nas(result)\n ```\n \"\"\"\n return cls(\n xyxy=yolo_nas_results.prediction.bboxes_xyxy,\n confidence=yolo_nas_results.prediction.confidence,\n class_id=yolo_nas_results.prediction.labels.astype(int),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_yolov5","title":"from_yolov5(yolov5_results)
classmethod
","text":"Creates a Detections instance from a YOLOv5 inference result.
Parameters:
Name Type Description Defaultyolov5_results
yolov5.models.common.Detections
The output Detections instance from YOLOv5
requiredReturns:
Name Type DescriptionDetections
Detections
A new Detections object.
Example>>> import cv2\n>>> import torch\n>>> import supervision as sv\n\n>>> image = cv2.imread(SOURCE_IMAGE_PATH)\n>>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')\n>>> result = model(image)\n>>> detections = sv.Detections.from_yolov5(result)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_yolov5(cls, yolov5_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLOv5](https://github.com/ultralytics/yolov5) inference result.\n\n Args:\n yolov5_results (yolov5.models.common.Detections): The output Detections instance from YOLOv5\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> import torch\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')\n >>> result = model(image)\n >>> detections = sv.Detections.from_yolov5(result)\n ```\n \"\"\"\n yolov5_detections_predictions = yolov5_results.pred[0].cpu().cpu().numpy()\n return cls(\n xyxy=yolov5_detections_predictions[:, :4],\n confidence=yolov5_detections_predictions[:, 4],\n class_id=yolov5_detections_predictions[:, 5].astype(int),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.from_yolov8","title":"from_yolov8(yolov8_results)
classmethod
","text":"Creates a Detections instance from a YOLOv8 inference result.
Parameters:
Name Type Description Defaultyolov8_results
ultralytics.yolo.engine.results.Results
The output Results instance from YOLOv8
requiredReturns:
Name Type DescriptionDetections
Detections
A new Detections object.
Example>>> import cv2\n>>> from ultralytics import YOLO\n>>> import supervision as sv\n\n>>> image = cv2.imread(SOURCE_IMAGE_PATH)\n>>> model = YOLO('yolov8s.pt')\n>>> result = model(image)[0]\n>>> detections = sv.Detections.from_yolov8(result)\n
Source code in supervision/detection/core.py
@classmethod\ndef from_yolov8(cls, yolov8_results) -> Detections:\n\"\"\"\n Creates a Detections instance from a [YOLOv8](https://github.com/ultralytics/ultralytics) inference result.\n\n Args:\n yolov8_results (ultralytics.yolo.engine.results.Results): The output Results instance from YOLOv8\n\n Returns:\n Detections: A new Detections object.\n\n Example:\n ```python\n >>> import cv2\n >>> from ultralytics import YOLO\n >>> import supervision as sv\n\n >>> image = cv2.imread(SOURCE_IMAGE_PATH)\n >>> model = YOLO('yolov8s.pt')\n >>> result = model(image)[0]\n >>> detections = sv.Detections.from_yolov8(result)\n ```\n \"\"\"\n return cls(\n xyxy=yolov8_results.boxes.xyxy.cpu().numpy(),\n confidence=yolov8_results.boxes.conf.cpu().numpy(),\n class_id=yolov8_results.boxes.cls.cpu().numpy().astype(int),\n mask=extract_yolov8_masks(yolov8_results),\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.get_anchor_coordinates","title":"get_anchor_coordinates(anchor)
","text":"Returns the bounding box coordinates for a specific anchor.
Parameters:
Name Type Description Defaultanchor
Position
Position of bounding box anchor for which to return the coordinates.
requiredReturns:
Type Descriptionnp.ndarray
np.ndarray: An array of shape (n, 2)
containing the bounding box anchor coordinates in format [x, y]
.
supervision/detection/core.py
def get_anchor_coordinates(self, anchor: Position) -> np.ndarray:\n\"\"\"\n Returns the bounding box coordinates for a specific anchor.\n\n Args:\n anchor (Position): Position of bounding box anchor for which to return the coordinates.\n\n Returns:\n np.ndarray: An array of shape `(n, 2)` containing the bounding box anchor coordinates in format `[x, y]`.\n \"\"\"\n if anchor == Position.CENTER:\n return np.array(\n [\n (self.xyxy[:, 0] + self.xyxy[:, 2]) / 2,\n (self.xyxy[:, 1] + self.xyxy[:, 3]) / 2,\n ]\n ).transpose()\n elif anchor == Position.BOTTOM_CENTER:\n return np.array(\n [(self.xyxy[:, 0] + self.xyxy[:, 2]) / 2, self.xyxy[:, 3]]\n ).transpose()\n\n raise ValueError(f\"{anchor} is not supported.\")\n
"},{"location":"detection/core/#supervision.detection.core.Detections.merge","title":"merge(detections_list)
classmethod
","text":"Merge a list of Detections objects into a single Detections object.
This method takes a list of Detections objects and combines their respective fields (xyxy
, mask
, confidence
, class_id
, and tracker_id
) into a single Detections object. If all elements in a field are not None
, the corresponding field will be stacked. Otherwise, the field will be set to None
.
Parameters:
Name Type Description Defaultdetections_list
List[Detections]
A list of Detections objects to merge.
requiredReturns:
Type DescriptionDetections
A single Detections object containing the merged data from the input list.
Example>>> from supervision import Detections\n\n>>> detections_1 = Detections(...)\n>>> detections_2 = Detections(...)\n\n>>> merged_detections = Detections.merge([detections_1, detections_2])\n
Source code in supervision/detection/core.py
@classmethod\ndef merge(cls, detections_list: List[Detections]) -> Detections:\n\"\"\"\n Merge a list of Detections objects into a single Detections object.\n\n This method takes a list of Detections objects and combines their respective fields (`xyxy`, `mask`,\n `confidence`, `class_id`, and `tracker_id`) into a single Detections object. If all elements in a field are not\n `None`, the corresponding field will be stacked. Otherwise, the field will be set to `None`.\n\n Args:\n detections_list (List[Detections]): A list of Detections objects to merge.\n\n Returns:\n (Detections): A single Detections object containing the merged data from the input list.\n\n Example:\n ```python\n >>> from supervision import Detections\n\n >>> detections_1 = Detections(...)\n >>> detections_2 = Detections(...)\n\n >>> merged_detections = Detections.merge([detections_1, detections_2])\n ```\n \"\"\"\n if len(detections_list) == 0:\n return Detections.empty()\n\n detections_tuples_list = [astuple(detection) for detection in detections_list]\n xyxy, mask, confidence, class_id, tracker_id = [\n list(field) for field in zip(*detections_tuples_list)\n ]\n\n all_not_none = lambda l: all(x is not None for x in l)\n\n xyxy = np.vstack(xyxy)\n mask = np.vstack(mask) if all_not_none(mask) else None\n confidence = np.hstack(confidence) if all_not_none(confidence) else None\n class_id = np.hstack(class_id) if all_not_none(class_id) else None\n tracker_id = np.hstack(tracker_id) if all_not_none(tracker_id) else None\n\n return cls(\n xyxy=xyxy,\n mask=mask,\n confidence=confidence,\n class_id=class_id,\n tracker_id=tracker_id,\n )\n
"},{"location":"detection/core/#supervision.detection.core.Detections.with_nms","title":"with_nms(threshold=0.5, class_agnostic=False)
","text":"Perform non-maximum suppression on the current set of object detections.
Parameters:
Name Type Description Defaultthreshold
float
The intersection-over-union threshold to use for non-maximum suppression. Defaults to 0.5.
0.5
class_agnostic
bool
Whether to perform class-agnostic non-maximum suppression. If True, the class_id of each detection will be ignored. Defaults to False.
False
Returns:
Name Type DescriptionDetections
Detections
A new Detections object containing the subset of detections after non-maximum suppression.
Raises:
Type DescriptionAssertionError
If confidence
is None and class_agnostic is False. If class_id
is None and class_agnostic is False.
supervision/detection/core.py
def with_nms(\n self, threshold: float = 0.5, class_agnostic: bool = False\n) -> Detections:\n\"\"\"\n Perform non-maximum suppression on the current set of object detections.\n\n Args:\n threshold (float, optional): The intersection-over-union threshold to use for non-maximum suppression. Defaults to 0.5.\n class_agnostic (bool, optional): Whether to perform class-agnostic non-maximum suppression. If True, the class_id of each detection will be ignored. Defaults to False.\n\n Returns:\n Detections: A new Detections object containing the subset of detections after non-maximum suppression.\n\n Raises:\n AssertionError: If `confidence` is None and class_agnostic is False. If `class_id` is None and class_agnostic is False.\n \"\"\"\n if len(self) == 0:\n return self\n\n assert (\n self.confidence is not None\n ), f\"Detections confidence must be given for NMS to be executed.\"\n\n if class_agnostic:\n predictions = np.hstack((self.xyxy, self.confidence.reshape(-1, 1)))\n indices = non_max_suppression(\n predictions=predictions, iou_threshold=threshold\n )\n return self[indices]\n\n assert self.class_id is not None, (\n f\"Detections class_id must be given for NMS to be executed. If you intended to perform class agnostic \"\n f\"NMS set class_agnostic=True.\"\n )\n\n predictions = np.hstack(\n (self.xyxy, self.confidence.reshape(-1, 1), self.class_id.reshape(-1, 1))\n )\n indices = non_max_suppression(predictions=predictions, iou_threshold=threshold)\n return self[indices]\n
"},{"location":"detection/utils/","title":"Utils","text":""},{"location":"detection/utils/#box_iou_batch","title":"box_iou_batch","text":"Compute Intersection over Union (IoU) of two sets of bounding boxes - boxes_true
and boxes_detection
. Both sets of boxes are expected to be in (x_min, y_min, x_max, y_max)
format.
Parameters:
Name Type Description Defaultboxes_true
np.ndarray
2D np.ndarray
representing ground-truth boxes. shape = (N, 4)
where N
is number of true objects.
boxes_detection
np.ndarray
2D np.ndarray
representing detection boxes. shape = (M, 4)
where M
is number of detected objects.
Returns:
Type Descriptionnp.ndarray
np.ndarray: Pairwise IoU of boxes from boxes_true
and boxes_detection
. shape = (N, M)
where N
is number of true objects and M
is number of detected objects.
supervision/detection/utils.py
def box_iou_batch(boxes_true: np.ndarray, boxes_detection: np.ndarray) -> np.ndarray:\n\"\"\"\n Compute Intersection over Union (IoU) of two sets of bounding boxes - `boxes_true` and `boxes_detection`. Both sets\n of boxes are expected to be in `(x_min, y_min, x_max, y_max)` format.\n\n Args:\n boxes_true (np.ndarray): 2D `np.ndarray` representing ground-truth boxes. `shape = (N, 4)` where `N` is number of true objects.\n boxes_detection (np.ndarray): 2D `np.ndarray` representing detection boxes. `shape = (M, 4)` where `M` is number of detected objects.\n\n Returns:\n np.ndarray: Pairwise IoU of boxes from `boxes_true` and `boxes_detection`. `shape = (N, M)` where `N` is number of true objects and `M` is number of detected objects.\n \"\"\"\n\n def box_area(box):\n return (box[2] - box[0]) * (box[3] - box[1])\n\n area_true = box_area(boxes_true.T)\n area_detection = box_area(boxes_detection.T)\n\n top_left = np.maximum(boxes_true[:, None, :2], boxes_detection[:, :2])\n bottom_right = np.minimum(boxes_true[:, None, 2:], boxes_detection[:, 2:])\n\n area_inter = np.prod(np.clip(bottom_right - top_left, a_min=0, a_max=None), 2)\n return area_inter / (area_true[:, None] + area_detection - area_inter)\n
"},{"location":"detection/utils/#non_max_suppression","title":"non_max_suppression","text":"Perform Non-Maximum Suppression (NMS) on object detection predictions.
Parameters:
Name Type Description Defaultpredictions
np.ndarray
An array of object detection predictions in the format of (x_min, y_min, x_max, y_max, score)
or (x_min, y_min, x_max, y_max, score, class)
.
iou_threshold
float
The intersection-over-union threshold to use for non-maximum suppression.
0.5
Returns:
Type Descriptionnp.ndarray
np.ndarray: A boolean array indicating which predictions to keep after non-maximum suppression.
Raises:
Type DescriptionAssertionError
If iou_threshold
is not within the closed range from 0
to 1
.
supervision/detection/utils.py
def non_max_suppression(\n predictions: np.ndarray, iou_threshold: float = 0.5\n) -> np.ndarray:\n\"\"\"\n Perform Non-Maximum Suppression (NMS) on object detection predictions.\n\n Args:\n predictions (np.ndarray): An array of object detection predictions in the format of `(x_min, y_min, x_max, y_max, score)` or `(x_min, y_min, x_max, y_max, score, class)`.\n iou_threshold (float, optional): The intersection-over-union threshold to use for non-maximum suppression.\n\n Returns:\n np.ndarray: A boolean array indicating which predictions to keep after non-maximum suppression.\n\n Raises:\n AssertionError: If `iou_threshold` is not within the closed range from `0` to `1`.\n \"\"\"\n assert 0 <= iou_threshold <= 1, (\n f\"Value of `iou_threshold` must be in the closed range from 0 to 1, \"\n f\"{iou_threshold} given.\"\n )\n rows, columns = predictions.shape\n\n # add column #5 - category filled with zeros for agnostic nms\n if columns == 5:\n predictions = np.c_[predictions, np.zeros(rows)]\n\n # sort predictions column #4 - score\n sort_index = np.flip(predictions[:, 4].argsort())\n predictions = predictions[sort_index]\n\n boxes = predictions[:, :4]\n categories = predictions[:, 5]\n ious = box_iou_batch(boxes, boxes)\n ious = ious - np.eye(rows)\n\n keep = np.ones(rows, dtype=bool)\n\n for index, (iou, category) in enumerate(zip(ious, categories)):\n if not keep[index]:\n continue\n\n # drop detections with iou > iou_threshold and same category as current detections\n condition = (iou > iou_threshold) & (categories == category)\n keep = keep & ~condition\n\n return keep[sort_index.argsort()]\n
"},{"location":"detection/utils/#polygon_to_mask","title":"polygon_to_mask","text":"Generate a mask from a polygon.
Parameters:
Name Type Description Defaultpolygon
np.ndarray
The polygon for which the mask should be generated, given as a list of vertices.
requiredresolution_wh
Tuple[int, int]
The width and height of the desired resolution.
requiredReturns:
Type Descriptionnp.ndarray
np.ndarray: The generated 2D mask, where the polygon is marked with 1
's and the rest is filled with 0
's.
supervision/detection/utils.py
def polygon_to_mask(polygon: np.ndarray, resolution_wh: Tuple[int, int]) -> np.ndarray:\n\"\"\"Generate a mask from a polygon.\n\n Args:\n polygon (np.ndarray): The polygon for which the mask should be generated, given as a list of vertices.\n resolution_wh (Tuple[int, int]): The width and height of the desired resolution.\n\n Returns:\n np.ndarray: The generated 2D mask, where the polygon is marked with `1`'s and the rest is filled with `0`'s.\n \"\"\"\n width, height = resolution_wh\n mask = np.zeros((height, width), dtype=np.uint8)\n cv2.fillPoly(mask, [polygon], color=1)\n return mask\n
"},{"location":"detection/utils/#mask_to_xyxy","title":"mask_to_xyxy","text":"Converts a 3D np.array
of 2D bool masks into a 2D np.array
of bounding boxes.
Parameters:
Name Type Description Defaultmasks
np.ndarray
A 3D np.array
of shape (N, W, H)
containing 2D bool masks
Returns:
Type Descriptionnp.ndarray
np.ndarray: A 2D np.array
of shape (N, 4)
containing the bounding boxes (x_min, y_min, x_max, y_max)
for each mask
supervision/detection/utils.py
def mask_to_xyxy(masks: np.ndarray) -> np.ndarray:\n\"\"\"\n Converts a 3D `np.array` of 2D bool masks into a 2D `np.array` of bounding boxes.\n\n Parameters:\n masks (np.ndarray): A 3D `np.array` of shape `(N, W, H)` containing 2D bool masks\n\n Returns:\n np.ndarray: A 2D `np.array` of shape `(N, 4)` containing the bounding boxes `(x_min, y_min, x_max, y_max)` for each mask\n \"\"\"\n n = masks.shape[0]\n bboxes = np.zeros((n, 4), dtype=int)\n\n for i, mask in enumerate(masks):\n rows, cols = np.where(mask)\n\n if len(rows) > 0 and len(cols) > 0:\n x_min, x_max = np.min(cols), np.max(cols)\n y_min, y_max = np.min(rows), np.max(rows)\n bboxes[i, :] = [x_min, y_min, x_max, y_max]\n\n return bboxes\n
"},{"location":"detection/utils/#mask_to_polygons","title":"mask_to_polygons","text":"Converts a binary mask to a list of polygons.
Parameters:
Name Type Description Defaultmask
np.ndarray
A binary mask represented as a 2D NumPy array of shape (H, W)
, where H and W are the height and width of the mask, respectively.
Returns:
Type DescriptionList[np.ndarray]
List[np.ndarray]: A list of polygons, where each polygon is represented by a NumPy array of shape (N, 2)
, containing the x
, y
coordinates of the points. Polygons with fewer points than MIN_POLYGON_POINT_COUNT = 3
are excluded from the output.
supervision/detection/utils.py
def mask_to_polygons(mask: np.ndarray) -> List[np.ndarray]:\n\"\"\"\n Converts a binary mask to a list of polygons.\n\n Parameters:\n mask (np.ndarray): A binary mask represented as a 2D NumPy array of shape `(H, W)`,\n where H and W are the height and width of the mask, respectively.\n\n Returns:\n List[np.ndarray]: A list of polygons, where each polygon is represented by a NumPy array of shape `(N, 2)`,\n containing the `x`, `y` coordinates of the points. Polygons with fewer points than `MIN_POLYGON_POINT_COUNT = 3`\n are excluded from the output.\n \"\"\"\n\n contours, _ = cv2.findContours(\n mask.astype(np.uint8), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE\n )\n return [\n np.squeeze(contour, axis=1)\n for contour in contours\n if contour.shape[0] >= MIN_POLYGON_POINT_COUNT\n ]\n
"},{"location":"detection/utils/#polygon_to_xyxy","title":"polygon_to_xyxy","text":"Converts a polygon represented by a NumPy array into a bounding box.
Parameters:
Name Type Description Defaultpolygon
np.ndarray
A polygon represented by a NumPy array of shape (N, 2)
, containing the x
, y
coordinates of the points.
Returns:
Type Descriptionnp.ndarray
np.ndarray: A 1D NumPy array containing the bounding box (x_min, y_min, x_max, y_max)
of the input polygon.
supervision/detection/utils.py
def polygon_to_xyxy(polygon: np.ndarray) -> np.ndarray:\n\"\"\"\n Converts a polygon represented by a NumPy array into a bounding box.\n\n Parameters:\n polygon (np.ndarray): A polygon represented by a NumPy array of shape `(N, 2)`,\n containing the `x`, `y` coordinates of the points.\n\n Returns:\n np.ndarray: A 1D NumPy array containing the bounding box `(x_min, y_min, x_max, y_max)` of the input polygon.\n \"\"\"\n x_min, y_min = np.min(polygon, axis=0)\n x_max, y_max = np.max(polygon, axis=0)\n return np.array([x_min, y_min, x_max, y_max])\n
"},{"location":"detection/utils/#filter_polygons_by_area","title":"filter_polygons_by_area","text":"Filters a list of polygons based on their area.
Parameters:
Name Type Description Defaultpolygons
List[np.ndarray]
A list of polygons, where each polygon is represented by a NumPy array of shape (N, 2)
, containing the x
, y
coordinates of the points.
min_area
Optional[float]
The minimum area threshold. Only polygons with an area greater than or equal to this value will be included in the output. If set to None, no minimum area constraint will be applied.
None
max_area
Optional[float]
The maximum area threshold. Only polygons with an area less than or equal to this value will be included in the output. If set to None, no maximum area constraint will be applied.
None
Returns:
Type DescriptionList[np.ndarray]
List[np.ndarray]: A new list of polygons containing only those with areas within the specified thresholds.
Source code insupervision/detection/utils.py
def filter_polygons_by_area(\n polygons: List[np.ndarray],\n min_area: Optional[float] = None,\n max_area: Optional[float] = None,\n) -> List[np.ndarray]:\n\"\"\"\n Filters a list of polygons based on their area.\n\n Parameters:\n polygons (List[np.ndarray]): A list of polygons, where each polygon is represented by a NumPy array of shape `(N, 2)`,\n containing the `x`, `y` coordinates of the points.\n min_area (Optional[float]): The minimum area threshold. Only polygons with an area greater than or equal to this value\n will be included in the output. If set to None, no minimum area constraint will be applied.\n max_area (Optional[float]): The maximum area threshold. Only polygons with an area less than or equal to this value\n will be included in the output. If set to None, no maximum area constraint will be applied.\n\n Returns:\n List[np.ndarray]: A new list of polygons containing only those with areas within the specified thresholds.\n \"\"\"\n if min_area is None and max_area is None:\n return polygons\n ares = [cv2.contourArea(polygon) for polygon in polygons]\n return [\n polygon\n for polygon, area in zip(polygons, ares)\n if (min_area is None or area >= min_area)\n and (max_area is None or area <= max_area)\n ]\n
"},{"location":"detection/tools/polygon_zone/","title":"Polygon Zone","text":""},{"location":"detection/tools/polygon_zone/#polygonzone","title":"PolygonZone","text":"A class for defining a polygon-shaped zone within a frame for detecting objects.
Attributes:
Name Type Descriptionpolygon
np.ndarray
A polygon represented by a numpy array of shape (N, 2)
, containing the x
, y
coordinates of the points.
frame_resolution_wh
Tuple[int, int]
The frame resolution (width, height)
triggering_position
Position
The position within the bounding box that triggers the zone (default: Position.BOTTOM_CENTER)
current_count
int
The current count of detected objects within the zone
mask
np.ndarray
The 2D bool mask for the polygon zone
Source code insupervision/detection/tools/polygon_zone.py
class PolygonZone:\n\"\"\"\n A class for defining a polygon-shaped zone within a frame for detecting objects.\n\n Attributes:\n polygon (np.ndarray): A polygon represented by a numpy array of shape `(N, 2)`, containing the `x`, `y` coordinates of the points.\n frame_resolution_wh (Tuple[int, int]): The frame resolution (width, height)\n triggering_position (Position): The position within the bounding box that triggers the zone (default: Position.BOTTOM_CENTER)\n current_count (int): The current count of detected objects within the zone\n mask (np.ndarray): The 2D bool mask for the polygon zone\n \"\"\"\n\n def __init__(\n self,\n polygon: np.ndarray,\n frame_resolution_wh: Tuple[int, int],\n triggering_position: Position = Position.BOTTOM_CENTER,\n ):\n self.polygon = polygon.astype(int)\n self.frame_resolution_wh = frame_resolution_wh\n self.triggering_position = triggering_position\n self.current_count = 0\n\n width, height = frame_resolution_wh\n self.mask = polygon_to_mask(\n polygon=polygon, resolution_wh=(width + 1, height + 1)\n )\n\n def trigger(self, detections: Detections) -> np.ndarray:\n\"\"\"\n Determines if the detections are within the polygon zone.\n\n Parameters:\n detections (Detections): The detections to be checked against the polygon zone\n\n Returns:\n np.ndarray: A boolean numpy array indicating if each detection is within the polygon zone\n \"\"\"\n\n clipped_xyxy = clip_boxes(\n boxes_xyxy=detections.xyxy, frame_resolution_wh=self.frame_resolution_wh\n )\n clipped_detections = replace(detections, xyxy=clipped_xyxy)\n clipped_anchors = np.ceil(\n clipped_detections.get_anchor_coordinates(anchor=self.triggering_position)\n ).astype(int)\n is_in_zone = self.mask[clipped_anchors[:, 1], clipped_anchors[:, 0]]\n self.current_count = np.sum(is_in_zone)\n return is_in_zone.astype(bool)\n
"},{"location":"detection/tools/polygon_zone/#supervision.detection.tools.polygon_zone.PolygonZone.trigger","title":"trigger(detections)
","text":"Determines if the detections are within the polygon zone.
Parameters:
Name Type Description Defaultdetections
Detections
The detections to be checked against the polygon zone
requiredReturns:
Type Descriptionnp.ndarray
np.ndarray: A boolean numpy array indicating if each detection is within the polygon zone
Source code insupervision/detection/tools/polygon_zone.py
def trigger(self, detections: Detections) -> np.ndarray:\n\"\"\"\n Determines if the detections are within the polygon zone.\n\n Parameters:\n detections (Detections): The detections to be checked against the polygon zone\n\n Returns:\n np.ndarray: A boolean numpy array indicating if each detection is within the polygon zone\n \"\"\"\n\n clipped_xyxy = clip_boxes(\n boxes_xyxy=detections.xyxy, frame_resolution_wh=self.frame_resolution_wh\n )\n clipped_detections = replace(detections, xyxy=clipped_xyxy)\n clipped_anchors = np.ceil(\n clipped_detections.get_anchor_coordinates(anchor=self.triggering_position)\n ).astype(int)\n is_in_zone = self.mask[clipped_anchors[:, 1], clipped_anchors[:, 0]]\n self.current_count = np.sum(is_in_zone)\n return is_in_zone.astype(bool)\n
"},{"location":"detection/tools/polygon_zone/#polygonzoneannotator","title":"PolygonZoneAnnotator","text":"A class for annotating a polygon-shaped zone within a frame with a count of detected objects.
Attributes:
Name Type Descriptionzone
PolygonZone
The polygon zone to be annotated
color
Color
The color to draw the polygon lines
thickness
int
The thickness of the polygon lines, default is 2
text_color
Color
The color of the text on the polygon, default is black
text_scale
float
The scale of the text on the polygon, default is 0.5
text_thickness
int
The thickness of the text on the polygon, default is 1
text_padding
int
The padding around the text on the polygon, default is 10
font
int
The font type for the text on the polygon, default is cv2.FONT_HERSHEY_SIMPLEX
center
Tuple[int, int]
The center of the polygon for text placement
Source code insupervision/detection/tools/polygon_zone.py
class PolygonZoneAnnotator:\n\"\"\"\n A class for annotating a polygon-shaped zone within a frame with a count of detected objects.\n\n Attributes:\n zone (PolygonZone): The polygon zone to be annotated\n color (Color): The color to draw the polygon lines\n thickness (int): The thickness of the polygon lines, default is 2\n text_color (Color): The color of the text on the polygon, default is black\n text_scale (float): The scale of the text on the polygon, default is 0.5\n text_thickness (int): The thickness of the text on the polygon, default is 1\n text_padding (int): The padding around the text on the polygon, default is 10\n font (int): The font type for the text on the polygon, default is cv2.FONT_HERSHEY_SIMPLEX\n center (Tuple[int, int]): The center of the polygon for text placement\n \"\"\"\n\n def __init__(\n self,\n zone: PolygonZone,\n color: Color,\n thickness: int = 2,\n text_color: Color = Color.black(),\n text_scale: float = 0.5,\n text_thickness: int = 1,\n text_padding: int = 10,\n ):\n self.zone = zone\n self.color = color\n self.thickness = thickness\n self.text_color = text_color\n self.text_scale = text_scale\n self.text_thickness = text_thickness\n self.text_padding = text_padding\n self.font = cv2.FONT_HERSHEY_SIMPLEX\n self.center = get_polygon_center(polygon=zone.polygon)\n\n def annotate(self, scene: np.ndarray, label: Optional[str] = None) -> np.ndarray:\n\"\"\"\n Annotates the polygon zone within a frame with a count of detected objects.\n\n Parameters:\n scene (np.ndarray): The image on which the polygon zone will be annotated\n label (Optional[str]): An optional label for the count of detected objects within the polygon zone (default: None)\n\n Returns:\n np.ndarray: The image with the polygon zone and count of detected objects\n \"\"\"\n annotated_frame = draw_polygon(\n scene=scene,\n polygon=self.zone.polygon,\n color=self.color,\n thickness=self.thickness,\n )\n\n annotated_frame = draw_text(\n scene=annotated_frame,\n text=str(self.zone.current_count) if label is None else label,\n text_anchor=self.center,\n background_color=self.color,\n text_color=self.text_color,\n text_scale=self.text_scale,\n text_thickness=self.text_thickness,\n text_padding=self.text_padding,\n text_font=self.font,\n )\n\n return annotated_frame\n
"},{"location":"detection/tools/polygon_zone/#supervision.detection.tools.polygon_zone.PolygonZoneAnnotator.annotate","title":"annotate(scene, label=None)
","text":"Annotates the polygon zone within a frame with a count of detected objects.
Parameters:
Name Type Description Defaultscene
np.ndarray
The image on which the polygon zone will be annotated
requiredlabel
Optional[str]
An optional label for the count of detected objects within the polygon zone (default: None)
None
Returns:
Type Descriptionnp.ndarray
np.ndarray: The image with the polygon zone and count of detected objects
Source code insupervision/detection/tools/polygon_zone.py
def annotate(self, scene: np.ndarray, label: Optional[str] = None) -> np.ndarray:\n\"\"\"\n Annotates the polygon zone within a frame with a count of detected objects.\n\n Parameters:\n scene (np.ndarray): The image on which the polygon zone will be annotated\n label (Optional[str]): An optional label for the count of detected objects within the polygon zone (default: None)\n\n Returns:\n np.ndarray: The image with the polygon zone and count of detected objects\n \"\"\"\n annotated_frame = draw_polygon(\n scene=scene,\n polygon=self.zone.polygon,\n color=self.color,\n thickness=self.thickness,\n )\n\n annotated_frame = draw_text(\n scene=annotated_frame,\n text=str(self.zone.current_count) if label is None else label,\n text_anchor=self.center,\n background_color=self.color,\n text_color=self.text_color,\n text_scale=self.text_scale,\n text_thickness=self.text_thickness,\n text_padding=self.text_padding,\n text_font=self.font,\n )\n\n return annotated_frame\n
"},{"location":"draw/utils/","title":"Utils","text":""},{"location":"draw/utils/#draw_line","title":"draw_line","text":"Draws a line on a given scene.
Parameters:
Name Type Description Defaultscene
np.ndarray
The scene on which the line will be drawn
requiredstart
Point
The starting point of the line
requiredend
Point
The end point of the line
requiredcolor
Color
The color of the line
requiredthickness
int
The thickness of the line
2
Returns:
Type Descriptionnp.ndarray
np.ndarray: The scene with the line drawn on it
Source code insupervision/draw/utils.py
def draw_line(\n scene: np.ndarray, start: Point, end: Point, color: Color, thickness: int = 2\n) -> np.ndarray:\n\"\"\"\n Draws a line on a given scene.\n\n Parameters:\n scene (np.ndarray): The scene on which the line will be drawn\n start (Point): The starting point of the line\n end (Point): The end point of the line\n color (Color): The color of the line\n thickness (int): The thickness of the line\n\n Returns:\n np.ndarray: The scene with the line drawn on it\n \"\"\"\n cv2.line(\n scene,\n start.as_xy_int_tuple(),\n end.as_xy_int_tuple(),\n color.as_bgr(),\n thickness=thickness,\n )\n return scene\n
"},{"location":"draw/utils/#draw_rectangle","title":"draw_rectangle","text":"Draws a rectangle on an image.
Parameters:
Name Type Description Defaultscene
np.ndarray
The scene on which the rectangle will be drawn
requiredrect
Rect
The rectangle to be drawn
requiredcolor
Color
The color of the rectangle
requiredthickness
int
The thickness of the rectangle border
2
Returns:
Type Descriptionnp.ndarray
np.ndarray: The scene with the rectangle drawn on it
Source code insupervision/draw/utils.py
def draw_rectangle(\n scene: np.ndarray, rect: Rect, color: Color, thickness: int = 2\n) -> np.ndarray:\n\"\"\"\n Draws a rectangle on an image.\n\n Parameters:\n scene (np.ndarray): The scene on which the rectangle will be drawn\n rect (Rect): The rectangle to be drawn\n color (Color): The color of the rectangle\n thickness (int): The thickness of the rectangle border\n\n Returns:\n np.ndarray: The scene with the rectangle drawn on it\n \"\"\"\n cv2.rectangle(\n scene,\n rect.top_left.as_xy_int_tuple(),\n rect.bottom_right.as_xy_int_tuple(),\n color.as_bgr(),\n thickness=thickness,\n )\n return scene\n
"},{"location":"draw/utils/#draw_filled_rectangle","title":"draw_filled_rectangle","text":"Draws a filled rectangle on an image.
Parameters:
Name Type Description Defaultscene
np.ndarray
The scene on which the rectangle will be drawn
requiredrect
Rect
The rectangle to be drawn
requiredcolor
Color
The color of the rectangle
requiredReturns:
Type Descriptionnp.ndarray
np.ndarray: The scene with the rectangle drawn on it
Source code insupervision/draw/utils.py
def draw_filled_rectangle(scene: np.ndarray, rect: Rect, color: Color) -> np.ndarray:\n\"\"\"\n Draws a filled rectangle on an image.\n\n Parameters:\n scene (np.ndarray): The scene on which the rectangle will be drawn\n rect (Rect): The rectangle to be drawn\n color (Color): The color of the rectangle\n\n Returns:\n np.ndarray: The scene with the rectangle drawn on it\n \"\"\"\n cv2.rectangle(\n scene,\n rect.top_left.as_xy_int_tuple(),\n rect.bottom_right.as_xy_int_tuple(),\n color.as_bgr(),\n -1,\n )\n return scene\n
"},{"location":"draw/utils/#draw_polygon","title":"draw_polygon","text":"Draw a polygon on a scene.
Parameters:
Name Type Description Defaultscene
np.ndarray
The scene to draw the polygon on.
requiredpolygon
np.ndarray
The polygon to be drawn, given as a list of vertices.
requiredcolor
Color
The color of the polygon.
requiredthickness
int
The thickness of the polygon lines, by default 2.
2
Returns:
Type Descriptionnp.ndarray
np.ndarray: The scene with the polygon drawn on it.
Source code insupervision/draw/utils.py
def draw_polygon(\n scene: np.ndarray, polygon: np.ndarray, color: Color, thickness: int = 2\n) -> np.ndarray:\n\"\"\"Draw a polygon on a scene.\n\n Parameters:\n scene (np.ndarray): The scene to draw the polygon on.\n polygon (np.ndarray): The polygon to be drawn, given as a list of vertices.\n color (Color): The color of the polygon.\n thickness (int, optional): The thickness of the polygon lines, by default 2.\n\n Returns:\n np.ndarray: The scene with the polygon drawn on it.\n \"\"\"\n cv2.polylines(\n scene, [polygon], isClosed=True, color=color.as_bgr(), thickness=thickness\n )\n return scene\n
"},{"location":"draw/utils/#draw_text","title":"draw_text","text":"Draw text with background on a scene.
Parameters:
Name Type Description Defaultscene
np.ndarray
A 2-dimensional numpy ndarray representing an image or scene.
requiredtext
str
The text to be drawn.
requiredtext_anchor
Point
The anchor point for the text, represented as a Point object with x and y attributes.
requiredtext_color
Color
The color of the text. Defaults to black.
Color.black()
text_scale
float
The scale of the text. Defaults to 0.5.
0.5
text_thickness
int
The thickness of the text. Defaults to 1.
1
text_padding
int
The amount of padding to add around the text when drawing a rectangle in the background. Defaults to 10.
10
text_font
int
The font to use for the text. Defaults to cv2.FONT_HERSHEY_SIMPLEX.
cv2.FONT_HERSHEY_SIMPLEX
background_color
Color
The color of the background rectangle, if one is to be drawn. Defaults to None.
None
Returns:
Type Descriptionnp.ndarray
np.ndarray: The input scene with the text drawn on it.
Examples:
>>> scene = np.zeros((100, 100, 3), dtype=np.uint8)\n>>> text_anchor = Point(x=50, y=50)\n>>> scene = draw_text(scene=scene, text=\"Hello, world!\", text_anchor=text_anchor)\n
Source code in supervision/draw/utils.py
def draw_text(\n scene: np.ndarray,\n text: str,\n text_anchor: Point,\n text_color: Color = Color.black(),\n text_scale: float = 0.5,\n text_thickness: int = 1,\n text_padding: int = 10,\n text_font: int = cv2.FONT_HERSHEY_SIMPLEX,\n background_color: Optional[Color] = None,\n) -> np.ndarray:\n\"\"\"\n Draw text with background on a scene.\n\n Parameters:\n scene (np.ndarray): A 2-dimensional numpy ndarray representing an image or scene.\n text (str): The text to be drawn.\n text_anchor (Point): The anchor point for the text, represented as a Point object with x and y attributes.\n text_color (Color, optional): The color of the text. Defaults to black.\n text_scale (float, optional): The scale of the text. Defaults to 0.5.\n text_thickness (int, optional): The thickness of the text. Defaults to 1.\n text_padding (int, optional): The amount of padding to add around the text when drawing a rectangle in the background. Defaults to 10.\n text_font (int, optional): The font to use for the text. Defaults to cv2.FONT_HERSHEY_SIMPLEX.\n background_color (Color, optional): The color of the background rectangle, if one is to be drawn. Defaults to None.\n\n Returns:\n np.ndarray: The input scene with the text drawn on it.\n\n Examples:\n ```python\n >>> scene = np.zeros((100, 100, 3), dtype=np.uint8)\n >>> text_anchor = Point(x=50, y=50)\n >>> scene = draw_text(scene=scene, text=\"Hello, world!\", text_anchor=text_anchor)\n ```\n \"\"\"\n text_width, text_height = cv2.getTextSize(\n text=text,\n fontFace=text_font,\n fontScale=text_scale,\n thickness=text_thickness,\n )[0]\n text_rect = Rect(\n x=text_anchor.x - text_width // 2,\n y=text_anchor.y - text_height // 2,\n width=text_width,\n height=text_height,\n ).pad(text_padding)\n\n if background_color is not None:\n scene = draw_filled_rectangle(\n scene=scene, rect=text_rect, color=background_color\n )\n\n cv2.putText(\n img=scene,\n text=text,\n org=(text_anchor.x - text_width // 2, text_anchor.y + text_height // 2),\n fontFace=text_font,\n fontScale=text_scale,\n color=text_color.as_bgr(),\n thickness=text_thickness,\n lineType=cv2.LINE_AA,\n )\n return scene\n
"},{"location":"quickstart/detections/","title":"Detections","text":""},{"location":"quickstart/detections/#advanced-filtering","title":"advanced filtering","text":"The advanced filtering capabilities of the Detections
class offer users a versatile and efficient way to narrow down and refine object detections. This section outlines various filtering methods, including filtering by specific class or a set of classes, confidence, object area, bounding box area, relative area, box dimensions, and designated zones. Each method is demonstrated with concise code examples to provide users with a clear understanding of how to implement the filters in their applications.
Allows you to select detections that belong only to one selected class.
AfterBeforeimport supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.class_id == 0]\n
import supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.class_id == 0]\n
"},{"location":"quickstart/detections/#by-set-of-classes","title":"by set of classes","text":"Allows you to select detections that belong only to selected set of classes.
AfterBeforeimport numpy as np\nimport supervision as sv\n\nselected_classes = [0, 2, 3]\ndetections = sv.Detections(...)\ndetections = detections[np.isin(detections.class_id, selected_classes)]\n
import numpy as np\nimport supervision as sv\n\nclass_id = [0, 2, 3]\ndetections = sv.Detections(...)\ndetections = detections[np.isin(detections.class_id, class_id)]\n
"},{"location":"quickstart/detections/#by-confidence","title":"by confidence","text":"Allows you to select detections with specific confidence value, for example higher than selected threshold.
AfterBeforeimport supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.confidence > 0.5]\n
import supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.confidence > 0.5]\n
"},{"location":"quickstart/detections/#by-area","title":"by area","text":"Allows you to select detections based on their size. We define the area as the number of pixels occupied by the detection in the image. In the example below, we have sifted out the detections that are too small.
AfterBeforeimport supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.area > 1000]\n
import supervision as sv\n\ndetections = sv.Detections(...)\ndetections = detections[detections.area > 1000]\n
"},{"location":"quickstart/detections/#by-relative-area","title":"by relative area","text":"Allows you to select detections based on their size in relation to the size of whole image. Sometimes the concept of detection size changes depending on the image. Detection occupying 10000 square px can be large on a 1280x720 image but small on a 3840x2160 image. In such cases, we can filter out detections based on the percentage of the image area occupied by them. In the example below, we remove too large detections.
AfterBeforeimport supervision as sv\n\nimage = ...\nheight, width, channels = image.shape\nimage_area = height * width\n\ndetections = sv.Detections(...)\ndetections = detections[(detections.area / image_area) < 0.8]\n
import supervision as sv\n\nimage = ...\nheight, width, channels = image.shape\nimage_area = height * width\n\ndetections = sv.Detections(...)\ndetections = detections[(detections.area / image_area) < 0.8]\n
"},{"location":"quickstart/detections/#by-box-dimensions","title":"by box dimensions","text":"Allows you to select detections based on their dimensions. The size of the bounding box, as well as its coordinates, can be criteria for rejecting detection. Implementing such filtering requires a bit of custom code but is relatively simple and fast.
AfterBeforeimport supervision as sv\n\ndetections = sv.Detections(...)\nw = detections.xyxy[:, 2] - detections.xyxy[:, 0]\nh = detections.xyxy[:, 3] - detections.xyxy[:, 1]\ndetections = detections[(w > 200) & (h > 200)]\n
import supervision as sv\n\ndetections = sv.Detections(...)\nw = detections.xyxy[:, 2] - detections.xyxy[:, 0]\nh = detections.xyxy[:, 3] - detections.xyxy[:, 1]\ndetections = detections[(w > 200) & (h > 200)]\n
"},{"location":"quickstart/detections/#by-polygonzone","title":"by PolygonZone
","text":"Allows you to use Detections
in combination with PolygonZone
to weed out bounding boxes that are in and out of the zone. In the example below you can see how to filter out all detections located in the lower part of the image.
import supervision as sv\n\nzone = sv.PolygonZone(...)\ndetections = sv.Detections(...)\nmask = zone.trigger(detections=detections)\ndetections = detections[mask]\n
import supervision as sv\n\nzone = sv.PolygonZone(...)\ndetections = sv.Detections(...)\nmask = zone.trigger(detections=detections)\ndetections = detections[mask]\n
"},{"location":"quickstart/detections/#by-mixed-conditions","title":"by mixed conditions","text":"Detections
' greatest strength, however, is that you can build arbitrarily complex logical conditions by simply combining separate conditions using &
or |
.
import supervision as sv\n\nzone = sv.PolygonZone(...)\ndetections = sv.Detections(...)\nmask = zone.trigger(detections=detections)\ndetections = detections[(detections.confidence > 0.7) & mask]\n
import supervision as sv\n\nzone = sv.PolygonZone(...)\ndetections = sv.Detections(...)\nmask = zone.trigger(detections=detections)\ndetections = detections[mask]\n
"},{"location":"utils/file/","title":"File","text":""},{"location":"utils/file/#list_files_with_extensions","title":"list_files_with_extensions","text":"List files in a directory with specified extensions or all files if no extensions are provided.
Parameters:
Name Type Description Defaultdirectory
Union[str, Path]
The directory path as a string or Path object.
requiredextensions
Optional[List[str]]
A list of file extensions to filter. Default is None, which lists all files.
None
Returns:
Type DescriptionList[Path]
A list of Path objects for the matching files.
Examples:
>>> import supervision as sv\n\n>>> # List all files in the directory\n>>> files = sv.list_files_with_extensions(directory='my_directory')\n\n>>> # List only files with '.txt' and '.md' extensions\n>>> files = sv.list_files_with_extensions(directory='my_directory', extensions=['txt', 'md'])\n
Source code in supervision/utils/file.py
def list_files_with_extensions(\n directory: Union[str, Path], extensions: Optional[List[str]] = None\n) -> List[Path]:\n\"\"\"\n List files in a directory with specified extensions or all files if no extensions are provided.\n\n Args:\n directory (Union[str, Path]): The directory path as a string or Path object.\n extensions (Optional[List[str]]): A list of file extensions to filter. Default is None, which lists all files.\n\n Returns:\n (List[Path]): A list of Path objects for the matching files.\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> # List all files in the directory\n >>> files = sv.list_files_with_extensions(directory='my_directory')\n\n >>> # List only files with '.txt' and '.md' extensions\n >>> files = sv.list_files_with_extensions(directory='my_directory', extensions=['txt', 'md'])\n ```\n \"\"\"\n directory = Path(directory)\n files_with_extensions = []\n\n if extensions is not None:\n for ext in extensions:\n files_with_extensions.extend(directory.glob(f\"*.{ext}\"))\n else:\n files_with_extensions.extend(directory.glob(\"*\"))\n\n return files_with_extensions\n
"},{"location":"utils/image/","title":"Image","text":""},{"location":"utils/image/#imagesink","title":"ImageSink","text":"Source code in supervision/utils/image.py
class ImageSink:\n def __init__(\n self,\n target_dir_path: str,\n overwrite: bool = False,\n image_name_pattern: str = \"image_{:05d}.png\",\n ):\n\"\"\"\n Initialize a context manager for saving images.\n\n Args:\n target_dir_path (str): The target directory where images will be saved.\n overwrite (bool, optional): Whether to overwrite the existing directory. Defaults to False.\n image_name_pattern (str, optional): The image file name pattern. Defaults to \"image_{:05d}.png\".\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> with sv.ImageSink(target_dir_path='target/directory/path', overwrite=True) as sink:\n ... for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):\n ... sink.save_image(image=image)\n ```\n \"\"\"\n self.target_dir_path = target_dir_path\n self.overwrite = overwrite\n self.image_name_pattern = image_name_pattern\n self.image_count = 0\n\n def __enter__(self):\n if os.path.exists(self.target_dir_path):\n if self.overwrite:\n shutil.rmtree(self.target_dir_path)\n os.makedirs(self.target_dir_path)\n else:\n os.makedirs(self.target_dir_path)\n\n return self\n\n def save_image(self, image: np.ndarray, image_name: Optional[str] = None):\n\"\"\"\n Save a given image in the target directory.\n\n Args:\n image (np.ndarray): The image to be saved.\n image_name (str, optional): The name to use for the saved image. If not provided, a name will be generated using the `image_name_pattern`.\n \"\"\"\n if image_name is None:\n image_name = self.image_name_pattern.format(self.image_count)\n\n image_path = os.path.join(self.target_dir_path, image_name)\n cv2.imwrite(image_path, image)\n self.image_count += 1\n\n def __exit__(self, exc_type, exc_value, exc_traceback):\n pass\n
"},{"location":"utils/image/#supervision.utils.image.ImageSink.__init__","title":"__init__(target_dir_path, overwrite=False, image_name_pattern='image_{:05d}.png')
","text":"Initialize a context manager for saving images.
Parameters:
Name Type Description Defaulttarget_dir_path
str
The target directory where images will be saved.
requiredoverwrite
bool
Whether to overwrite the existing directory. Defaults to False.
False
image_name_pattern
str
The image file name pattern. Defaults to \"image_{:05d}.png\".
'image_{:05d}.png'
Examples:
>>> import supervision as sv\n\n>>> with sv.ImageSink(target_dir_path='target/directory/path', overwrite=True) as sink:\n... for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):\n... sink.save_image(image=image)\n
Source code in supervision/utils/image.py
def __init__(\n self,\n target_dir_path: str,\n overwrite: bool = False,\n image_name_pattern: str = \"image_{:05d}.png\",\n):\n\"\"\"\n Initialize a context manager for saving images.\n\n Args:\n target_dir_path (str): The target directory where images will be saved.\n overwrite (bool, optional): Whether to overwrite the existing directory. Defaults to False.\n image_name_pattern (str, optional): The image file name pattern. Defaults to \"image_{:05d}.png\".\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> with sv.ImageSink(target_dir_path='target/directory/path', overwrite=True) as sink:\n ... for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):\n ... sink.save_image(image=image)\n ```\n \"\"\"\n self.target_dir_path = target_dir_path\n self.overwrite = overwrite\n self.image_name_pattern = image_name_pattern\n self.image_count = 0\n
"},{"location":"utils/image/#supervision.utils.image.ImageSink.save_image","title":"save_image(image, image_name=None)
","text":"Save a given image in the target directory.
Parameters:
Name Type Description Defaultimage
np.ndarray
The image to be saved.
requiredimage_name
str
The name to use for the saved image. If not provided, a name will be generated using the image_name_pattern
.
None
Source code in supervision/utils/image.py
def save_image(self, image: np.ndarray, image_name: Optional[str] = None):\n\"\"\"\n Save a given image in the target directory.\n\n Args:\n image (np.ndarray): The image to be saved.\n image_name (str, optional): The name to use for the saved image. If not provided, a name will be generated using the `image_name_pattern`.\n \"\"\"\n if image_name is None:\n image_name = self.image_name_pattern.format(self.image_count)\n\n image_path = os.path.join(self.target_dir_path, image_name)\n cv2.imwrite(image_path, image)\n self.image_count += 1\n
"},{"location":"utils/image/#crop","title":"crop","text":"Crops the given image based on the given bounding box.
Parameters:
Name Type Description Defaultimage
np.ndarray
The image to be cropped, represented as a numpy array.
requiredxyxy
np.ndarray
A numpy array containing the bounding box coordinates in the format (x1, y1, x2, y2).
requiredReturns:
Type Descriptionnp.ndarray
The cropped image as a numpy array.
Examples:
>>> import supervision as sv\n\n>>> detection = sv.Detections(...)\n>>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:\n... for xyxy in detection.xyxy:\n... cropped_image = sv.crop(image=image, xyxy=xyxy)\n... sink.save_image(image=image)\n
Source code in supervision/utils/image.py
def crop(image: np.ndarray, xyxy: np.ndarray) -> np.ndarray:\n\"\"\"\n Crops the given image based on the given bounding box.\n\n Args:\n image (np.ndarray): The image to be cropped, represented as a numpy array.\n xyxy (np.ndarray): A numpy array containing the bounding box coordinates in the format (x1, y1, x2, y2).\n\n Returns:\n (np.ndarray): The cropped image as a numpy array.\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> detection = sv.Detections(...)\n >>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:\n ... for xyxy in detection.xyxy:\n ... cropped_image = sv.crop(image=image, xyxy=xyxy)\n ... sink.save_image(image=image)\n ```\n \"\"\"\n\n xyxy = np.round(xyxy).astype(int)\n x1, y1, x2, y2 = xyxy\n cropped_img = image[y1:y2, x1:x2]\n return cropped_img\n
"},{"location":"utils/notebook/","title":"Notebook","text":""},{"location":"utils/notebook/#plot_image","title":"plot_image","text":"Plots image using matplotlib.
Parameters:
Name Type Description Defaultimage
np.ndarray
The frame to be displayed.
requiredsize
Tuple[int, int]
The size of the plot.
(12, 12)
cmap
str
the colormap to use for single channel images.
'gray'
Examples:
>>> import cv2\n>>> import supervision as sv\n\n>>> image = cv2.imread(\"path/to/image.jpg\")\n\n%matplotlib inline\n>>> sv.plot_image(image=image, size=(16, 16))\n
Source code in supervision/utils/notebook.py
def plot_image(\n image: np.ndarray, size: Tuple[int, int] = (12, 12), cmap: Optional[str] = \"gray\"\n) -> None:\n\"\"\"\n Plots image using matplotlib.\n\n Args:\n image (np.ndarray): The frame to be displayed.\n size (Tuple[int, int]): The size of the plot.\n cmap (str): the colormap to use for single channel images.\n\n Examples:\n ```python\n >>> import cv2\n >>> import supervision as sv\n\n >>> image = cv2.imread(\"path/to/image.jpg\")\n\n %matplotlib inline\n >>> sv.plot_image(image=image, size=(16, 16))\n ```\n \"\"\"\n plt.figure(figsize=size)\n\n if image.ndim == 2:\n plt.imshow(image, cmap=cmap)\n else:\n plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))\n\n plt.axis(\"off\")\n plt.show()\n
"},{"location":"utils/notebook/#plot_images_grid","title":"plot_images_grid","text":"Plots images in a grid using matplotlib.
Parameters:
Name Type Description Defaultimages
List[np.ndarray]
A list of images as numpy arrays.
requiredgrid_size
Tuple[int, int]
A tuple specifying the number of rows and columns for the grid.
requiredtitles
Optional[List[str]]
A list of titles for each image. Defaults to None.
None
size
Tuple[int, int]
A tuple specifying the width and height of the entire plot in inches.
(12, 12)
cmap
str
the colormap to use for single channel images.
'gray'
Raises:
Type DescriptionValueError
If the number of images exceeds the grid size.
Examples:
>>> import cv2\n>>> import supervision as sv\n\n>>> image1 = cv2.imread(\"path/to/image1.jpg\")\n>>> image2 = cv2.imread(\"path/to/image2.jpg\")\n>>> image3 = cv2.imread(\"path/to/image3.jpg\")\n\n>>> images = [image1, image2, image3]\n>>> titles = [\"Image 1\", \"Image 2\", \"Image 3\"]\n\n%matplotlib inline\n>>> plot_images_grid(images, grid_size=(2, 2), titles=titles, size=(16, 16))\n
Source code in supervision/utils/notebook.py
def plot_images_grid(\n images: List[np.ndarray],\n grid_size: Tuple[int, int],\n titles: Optional[List[str]] = None,\n size: Tuple[int, int] = (12, 12),\n cmap: Optional[str] = \"gray\",\n) -> None:\n\"\"\"\n Plots images in a grid using matplotlib.\n\n Args:\n images (List[np.ndarray]): A list of images as numpy arrays.\n grid_size (Tuple[int, int]): A tuple specifying the number of rows and columns for the grid.\n titles (Optional[List[str]]): A list of titles for each image. Defaults to None.\n size (Tuple[int, int]): A tuple specifying the width and height of the entire plot in inches.\n cmap (str): the colormap to use for single channel images.\n\n Raises:\n ValueError: If the number of images exceeds the grid size.\n\n Examples:\n ```python\n >>> import cv2\n >>> import supervision as sv\n\n >>> image1 = cv2.imread(\"path/to/image1.jpg\")\n >>> image2 = cv2.imread(\"path/to/image2.jpg\")\n >>> image3 = cv2.imread(\"path/to/image3.jpg\")\n\n >>> images = [image1, image2, image3]\n >>> titles = [\"Image 1\", \"Image 2\", \"Image 3\"]\n\n %matplotlib inline\n >>> plot_images_grid(images, grid_size=(2, 2), titles=titles, size=(16, 16))\n ```\n \"\"\"\n nrows, ncols = grid_size\n\n if len(images) > nrows * ncols:\n raise ValueError(\n \"The number of images exceeds the grid size. Please increase the grid size or reduce the number of images.\"\n )\n\n fig, axes = plt.subplots(nrows=nrows, ncols=ncols, figsize=size)\n\n for idx, ax in enumerate(axes.flat):\n if idx < len(images):\n if images[idx].ndim == 2:\n ax.imshow(images[idx], cmap=cmap)\n else:\n ax.imshow(cv2.cvtColor(images[idx], cv2.COLOR_BGR2RGB))\n\n if titles is not None and idx < len(titles):\n ax.set_title(titles[idx])\n\n ax.axis(\"off\")\n plt.show()\n
"},{"location":"utils/video/","title":"Video","text":""},{"location":"utils/video/#videoinfo","title":"VideoInfo","text":"A class to store video information, including width, height, fps and total number of frames.
Attributes:
Name Type Descriptionwidth
int
width of the video in pixels
height
int
height of the video in pixels
fps
int
frames per second of the video
total_frames
int
total number of frames in the video, default is None
Examples:
>>> import supervision as sv\n\n>>> video_info = sv.VideoInfo.from_video_path(video_path='video.mp4')\n\n>>> video_info\nVideoInfo(width=3840, height=2160, fps=25, total_frames=538)\n\n>>> video_info.resolution_wh\n(3840, 2160)\n
Source code in supervision/utils/video.py
@dataclass\nclass VideoInfo:\n\"\"\"\n A class to store video information, including width, height, fps and total number of frames.\n\n Attributes:\n width (int): width of the video in pixels\n height (int): height of the video in pixels\n fps (int): frames per second of the video\n total_frames (int, optional): total number of frames in the video, default is None\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> video_info = sv.VideoInfo.from_video_path(video_path='video.mp4')\n\n >>> video_info\n VideoInfo(width=3840, height=2160, fps=25, total_frames=538)\n\n >>> video_info.resolution_wh\n (3840, 2160)\n ```\n \"\"\"\n\n width: int\n height: int\n fps: int\n total_frames: Optional[int] = None\n\n @classmethod\n def from_video_path(cls, video_path: str) -> VideoInfo:\n video = cv2.VideoCapture(video_path)\n if not video.isOpened():\n raise Exception(f\"Could not open video at {video_path}\")\n\n width = int(video.get(cv2.CAP_PROP_FRAME_WIDTH))\n height = int(video.get(cv2.CAP_PROP_FRAME_HEIGHT))\n fps = int(video.get(cv2.CAP_PROP_FPS))\n total_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))\n video.release()\n return VideoInfo(width, height, fps, total_frames)\n\n @property\n def resolution_wh(self) -> Tuple[int, int]:\n return self.width, self.height\n
"},{"location":"utils/video/#videosink","title":"VideoSink","text":"Context manager that saves video frames to a file using OpenCV.
Attributes:
Name Type Descriptiontarget_path
str
The path to the output file where the video will be saved.
video_info
VideoInfo
Information about the video resolution, fps, and total frame count.
Example>>> import supervision as sv\n\n>>> video_info = sv.VideoInfo.from_video_path(video_path='source_video.mp4')\n\n>>> with sv.VideoSink(target_path='target_video.mp4', video_info=video_info) as sink:\n... for frame in get_video_frames_generator(source_path='source_video.mp4', stride=2):\n... sink.write_frame(frame=frame)\n
Source code in supervision/utils/video.py
class VideoSink:\n\"\"\"\n Context manager that saves video frames to a file using OpenCV.\n\n Attributes:\n target_path (str): The path to the output file where the video will be saved.\n video_info (VideoInfo): Information about the video resolution, fps, and total frame count.\n\n Example:\n ```python\n >>> import supervision as sv\n\n >>> video_info = sv.VideoInfo.from_video_path(video_path='source_video.mp4')\n\n >>> with sv.VideoSink(target_path='target_video.mp4', video_info=video_info) as sink:\n ... for frame in get_video_frames_generator(source_path='source_video.mp4', stride=2):\n ... sink.write_frame(frame=frame)\n ```\n \"\"\"\n\n def __init__(self, target_path: str, video_info: VideoInfo):\n self.target_path = target_path\n self.video_info = video_info\n self.__fourcc = cv2.VideoWriter_fourcc(*\"mp4v\")\n self.__writer = None\n\n def __enter__(self):\n self.__writer = cv2.VideoWriter(\n self.target_path,\n self.__fourcc,\n self.video_info.fps,\n self.video_info.resolution_wh,\n )\n return self\n\n def write_frame(self, frame: np.ndarray):\n self.__writer.write(frame)\n\n def __exit__(self, exc_type, exc_value, exc_traceback):\n self.__writer.release()\n
"},{"location":"utils/video/#get_video_frames_generator","title":"get_video_frames_generator","text":"Get a generator that yields the frames of the video.
Parameters:
Name Type Description Defaultsource_path
str
The path of the video file.
requiredstride
int
Indicates the interval at which frames are returned, skipping stride - 1 frames between each.
1
Returns:
Type DescriptionGenerator[np.ndarray, None, None]
A generator that yields the frames of the video.
Examples:
>>> import supervision as sv\n\n>>> for frame in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):\n... ...\n
Source code in supervision/utils/video.py
def get_video_frames_generator(\n source_path: str, stride: int = 1\n) -> Generator[np.ndarray, None, None]:\n\"\"\"\n Get a generator that yields the frames of the video.\n\n Args:\n source_path (str): The path of the video file.\n stride (int): Indicates the interval at which frames are returned, skipping stride - 1 frames between each.\n\n Returns:\n (Generator[np.ndarray, None, None]): A generator that yields the frames of the video.\n\n Examples:\n ```python\n >>> import supervision as sv\n\n >>> for frame in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):\n ... ...\n ```\n \"\"\"\n video = cv2.VideoCapture(source_path)\n if not video.isOpened():\n raise Exception(f\"Could not open video at {source_path}\")\n\n frame_count = 0\n success, frame = video.read()\n while success:\n if frame_count % stride == 0:\n yield frame\n success, frame = video.read()\n frame_count += 1\n\n video.release()\n
"},{"location":"utils/video/#process_video","title":"process_video","text":"Process a video file by applying a callback function on each frame and saving the result to a target video file.
Parameters:
Name Type Description Defaultsource_path
str
The path to the source video file.
requiredtarget_path
str
The path to the target video file.
requiredcallback
Callable[[np.ndarray, int], np.ndarray]
A function that takes in a numpy ndarray representation of a video frame and an int index of the frame and returns a processed numpy ndarray representation of the frame.
requiredExamples:
>>> from supervision import process_video\n\n>>> def process_frame(scene: np.ndarray) -> np.ndarray:\n... ...\n\n>>> process_video(\n... source_path='source_video.mp4',\n... target_path='target_video.mp4',\n... callback=process_frame\n... )\n
Source code in supervision/utils/video.py
def process_video(\n source_path: str,\n target_path: str,\n callback: Callable[[np.ndarray, int], np.ndarray],\n) -> None:\n\"\"\"\n Process a video file by applying a callback function on each frame and saving the result to a target video file.\n\n Args:\n source_path (str): The path to the source video file.\n target_path (str): The path to the target video file.\n callback (Callable[[np.ndarray, int], np.ndarray]): A function that takes in a numpy ndarray representation of a video frame and an int index of the frame and returns a processed numpy ndarray representation of the frame.\n\n Examples:\n ```python\n >>> from supervision import process_video\n\n >>> def process_frame(scene: np.ndarray) -> np.ndarray:\n ... ...\n\n >>> process_video(\n ... source_path='source_video.mp4',\n ... target_path='target_video.mp4',\n ... callback=process_frame\n ... )\n ```\n \"\"\"\n source_video_info = VideoInfo.from_video_path(video_path=source_path)\n with VideoSink(target_path=target_path, video_info=source_video_info) as sink:\n for index, frame in enumerate(\n get_video_frames_generator(source_path=source_path)\n ):\n result_frame = callback(frame, index)\n sink.write_frame(frame=result_frame)\n
"}]}
\ No newline at end of file
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 000000000..ca428ea00
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1,73 @@
+
+List files in a directory with specified extensions or all files if no extensions are provided.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
directory |
+
+ Union[str, Path]
+ |
+
+
+
+ The directory path as a string or Path object. + |
+ + required + | +
extensions |
+
+ Optional[List[str]]
+ |
+
+
+
+ A list of file extensions to filter. Default is None, which lists all files. + |
+
+ None
+ |
+
Returns:
+Type | +Description | +
---|---|
+ List[Path]
+ |
+
+
+
+ A list of Path objects for the matching files. + |
+
Examples:
+>>> import supervision as sv
+
+>>> # List all files in the directory
+>>> files = sv.list_files_with_extensions(directory='my_directory')
+
+>>> # List only files with '.txt' and '.md' extensions
+>>> files = sv.list_files_with_extensions(directory='my_directory', extensions=['txt', 'md'])
+
supervision/utils/file.py
19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 |
|
supervision/utils/image.py
38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 |
|
__init__(target_dir_path, overwrite=False, image_name_pattern='image_{:05d}.png')
+
+¶Initialize a context manager for saving images.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
target_dir_path |
+
+ str
+ |
+
+
+
+ The target directory where images will be saved. + |
+ + required + | +
overwrite |
+
+ bool
+ |
+
+
+
+ Whether to overwrite the existing directory. Defaults to False. + |
+
+ False
+ |
+
image_name_pattern |
+
+ str
+ |
+
+
+
+ The image file name pattern. Defaults to "image_{:05d}.png". + |
+
+ 'image_{:05d}.png'
+ |
+
Examples:
+>>> import supervision as sv
+
+>>> with sv.ImageSink(target_dir_path='target/directory/path', overwrite=True) as sink:
+... for image in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):
+... sink.save_image(image=image)
+
supervision/utils/image.py
39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 |
|
save_image(image, image_name=None)
+
+¶Save a given image in the target directory.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
image |
+
+ np.ndarray
+ |
+
+
+
+ The image to be saved. + |
+ + required + | +
image_name |
+
+ str
+ |
+
+
+
+ The name to use for the saved image. If not provided, a name will be generated using the |
+
+ None
+ |
+
supervision/utils/image.py
77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 |
|
Crops the given image based on the given bounding box.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
image |
+
+ np.ndarray
+ |
+
+
+
+ The image to be cropped, represented as a numpy array. + |
+ + required + | +
xyxy |
+
+ np.ndarray
+ |
+
+
+
+ A numpy array containing the bounding box coordinates in the format (x1, y1, x2, y2). + |
+ + required + | +
Returns:
+Type | +Description | +
---|---|
+ np.ndarray
+ |
+
+
+
+ The cropped image as a numpy array. + |
+
Examples:
+>>> import supervision as sv
+
+>>> detection = sv.Detections(...)
+>>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:
+... for xyxy in detection.xyxy:
+... cropped_image = sv.crop(image=image, xyxy=xyxy)
+... sink.save_image(image=image)
+
supervision/utils/image.py
9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 |
|
Plots image using matplotlib.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
image |
+
+ np.ndarray
+ |
+
+
+
+ The frame to be displayed. + |
+ + required + | +
size |
+
+ Tuple[int, int]
+ |
+
+
+
+ The size of the plot. + |
+
+ (12, 12)
+ |
+
cmap |
+
+ str
+ |
+
+
+
+ the colormap to use for single channel images. + |
+
+ 'gray'
+ |
+
Examples:
+>>> import cv2
+>>> import supervision as sv
+
+>>> image = cv2.imread("path/to/image.jpg")
+
+%matplotlib inline
+>>> sv.plot_image(image=image, size=(16, 16))
+
supervision/utils/notebook.py
8 + 9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 |
|
Plots images in a grid using matplotlib.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
images |
+
+ List[np.ndarray]
+ |
+
+
+
+ A list of images as numpy arrays. + |
+ + required + | +
grid_size |
+
+ Tuple[int, int]
+ |
+
+
+
+ A tuple specifying the number of rows and columns for the grid. + |
+ + required + | +
titles |
+
+ Optional[List[str]]
+ |
+
+
+
+ A list of titles for each image. Defaults to None. + |
+
+ None
+ |
+
size |
+
+ Tuple[int, int]
+ |
+
+
+
+ A tuple specifying the width and height of the entire plot in inches. + |
+
+ (12, 12)
+ |
+
cmap |
+
+ str
+ |
+
+
+
+ the colormap to use for single channel images. + |
+
+ 'gray'
+ |
+
Raises:
+Type | +Description | +
---|---|
+ ValueError
+ |
+
+
+
+ If the number of images exceeds the grid size. + |
+
Examples:
+>>> import cv2
+>>> import supervision as sv
+
+>>> image1 = cv2.imread("path/to/image1.jpg")
+>>> image2 = cv2.imread("path/to/image2.jpg")
+>>> image3 = cv2.imread("path/to/image3.jpg")
+
+>>> images = [image1, image2, image3]
+>>> titles = ["Image 1", "Image 2", "Image 3"]
+
+%matplotlib inline
+>>> plot_images_grid(images, grid_size=(2, 2), titles=titles, size=(16, 16))
+
supervision/utils/notebook.py
41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 |
|
A class to store video information, including width, height, fps and total number of frames.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
width |
+
+ int
+ |
+
+
+
+ width of the video in pixels + |
+
height |
+
+ int
+ |
+
+
+
+ height of the video in pixels + |
+
fps |
+
+ int
+ |
+
+
+
+ frames per second of the video + |
+
total_frames |
+
+ int
+ |
+
+
+
+ total number of frames in the video, default is None + |
+
Examples:
+>>> import supervision as sv
+
+>>> video_info = sv.VideoInfo.from_video_path(video_path='video.mp4')
+
+>>> video_info
+VideoInfo(width=3840, height=2160, fps=25, total_frames=538)
+
+>>> video_info.resolution_wh
+(3840, 2160)
+
supervision/utils/video.py
10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 |
|
Context manager that saves video frames to a file using OpenCV.
+ +Attributes:
+Name | +Type | +Description | +
---|---|---|
target_path |
+
+ str
+ |
+
+
+
+ The path to the output file where the video will be saved. + |
+
video_info |
+
+ VideoInfo
+ |
+
+
+
+ Information about the video resolution, fps, and total frame count. + |
+
>>> import supervision as sv
+
+>>> video_info = sv.VideoInfo.from_video_path(video_path='source_video.mp4')
+
+>>> with sv.VideoSink(target_path='target_video.mp4', video_info=video_info) as sink:
+... for frame in get_video_frames_generator(source_path='source_video.mp4', stride=2):
+... sink.write_frame(frame=frame)
+
supervision/utils/video.py
58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 |
|
Get a generator that yields the frames of the video.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
source_path |
+
+ str
+ |
+
+
+
+ The path of the video file. + |
+ + required + | +
stride |
+
+ int
+ |
+
+
+
+ Indicates the interval at which frames are returned, skipping stride - 1 frames between each. + |
+
+ 1
+ |
+
Returns:
+Type | +Description | +
---|---|
+ Generator[np.ndarray, None, None]
+ |
+
+
+
+ A generator that yields the frames of the video. + |
+
Examples:
+>>> import supervision as sv
+
+>>> for frame in sv.get_video_frames_generator(source_path='source_video.mp4', stride=2):
+... ...
+
supervision/utils/video.py
100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 |
|
Process a video file by applying a callback function on each frame and saving the result to a target video file.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
source_path |
+
+ str
+ |
+
+
+
+ The path to the source video file. + |
+ + required + | +
target_path |
+
+ str
+ |
+
+
+
+ The path to the target video file. + |
+ + required + | +
callback |
+
+ Callable[[np.ndarray, int], np.ndarray]
+ |
+
+
+
+ A function that takes in a numpy ndarray representation of a video frame and an int index of the frame and returns a processed numpy ndarray representation of the frame. + |
+ + required + | +
Examples:
+>>> from supervision import process_video
+
+>>> def process_frame(scene: np.ndarray) -> np.ndarray:
+... ...
+
+>>> process_video(
+... source_path='source_video.mp4',
+... target_path='target_video.mp4',
+... callback=process_frame
+... )
+
supervision/utils/video.py
136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 |
|