This commit is contained in:
SkalskiP 2024-07-17 08:54:41 +02:00
parent d91113c9e7
commit 73ba5f039b
1 changed files with 209 additions and 218 deletions

View File

@ -1,53 +1,239 @@
---
comments: true
status: new
---
With Supervision, you can load and manipulate classification, object detection, and
segmentation datasets. This tutorial will walk you through how to load, split, merge,
and visualize datasets in Supervision.
visualize, and augment datasets in Supervision.
## Download Dataset
TODO
In this tutorial, we will use a dataset from
[Roboflow Universe](https://universe.roboflow.com/), a public repository of
thousands of computer vision datasets. If you already have your dataset in
[COCO](https://roboflow.com/formats/coco-json),
[YOLO](https://roboflow.com/formats/yolov8-pytorch-txt),
or [Pascal VOC](https://roboflow.com/formats/pascal-voc-xml) format, you can skip this
section.
```bash
pip install roboflow
```
TODO
Next, log into your Roboflow account and download the dataset of your choice in the
COCO, YOLO, or Pascal VOC format. You can customize the following code snippet with
your workspace ID, project ID, and version number.
```python
>>> import roboflow
=== "COCO"
>>> roboflow.login()
```python
import roboflow
>>> rf = roboflow.Roboflow()
>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("coco")
```
roboflow.login()
rf = roboflow.Roboflow()
project = rf.workspace(<WORKSPACE_ID>).project(<PROJECT_ID>)
dataset = project.version(<PROJECT_VERSION>).download("coco")
```
=== "YOLO"
```python
import roboflow
roboflow.login()
rf = roboflow.Roboflow()
project = rf.workspace(<WORKSPACE_ID>).project(<PROJECT_ID>)
dataset = project.version(<PROJECT_VERSION>).download("yolov8")
```
=== "Pascal VOC"
```python
import roboflow
roboflow.login()
rf = roboflow.Roboflow()
project = rf.workspace(<WORKSPACE_ID>).project(<PROJECT_ID>)
dataset = project.version(<PROJECT_VERSION>).download("voc")
```
## Load Dataset
- [`DetectionDataset.from_coco`](https://supervision.roboflow.com/datasets/#supervision.dataset.core.DetectionDataset.from_coco) ([COCO](https://roboflow.com/formats/coco-json))
- [`DetectionDataset.from_yolo`](https://supervision.roboflow.com/datasets/#supervision.dataset.core.DetectionDataset.from_yolo) ([YOLO](https://roboflow.com/formats/yolov8-pytorch-txt))
- [`DetectionDataset.from_pascal`](https://supervision.roboflow.com/datasets/#supervision.dataset.core.DetectionDataset.from_pascal) ([Pascal](https://roboflow.com/formats/pascal-voc-xml))
The Supervision library provides convenient functions to load datasets in various
formats. If your dataset is already split into train, test, and valid subsets, you can
load each of those as separate [`sv.DetectionDataset`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset)
instances.
=== "COCO"
We can do so using the [`sv.DetectionDataset.from_coco`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.from_coco) to load annotations in [COCO](https://roboflow.com/formats/coco-json) format.
```python
import supervision as sv
ds_train = sv.DetectionDataset.from_coco(
images_directory_path=f"{dataset.location}/train",
annotations_path=f"{dataset.location}/train/_annotations.coco.json",
)
ds_valid = sv.DetectionDataset.from_coco(
images_directory_path=f"{dataset.location}/valid",
annotations_path=f"{dataset.location}/valid/_annotations.coco.json",
)
ds_test = sv.DetectionDataset.from_coco(
images_directory_path=f"{dataset.location}/test",
annotations_path=f"{dataset.location}/test/_annotations.coco.json",
)
ds_train.classes
# ['person', 'bicycle', 'car', ...]
len(ds_train), len(ds_valid), len(ds_test)
# 800, 100, 100
```
=== "YOLO"
We can do so using the [`sv.DetectionDataset.from_yolo`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.from_yolo) to load annotations in [YOLO](https://roboflow.com/formats/yolov8-pytorch-txt) format.
```python
import supervision as sv
ds_train = 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_valid = sv.DetectionDataset.from_yolo(
images_directory_path=f"{dataset.location}/valid/images",
annotations_directory_path=f"{dataset.location}/valid/labels",
data_yaml_path=f"{dataset.location}/data.yaml"
)
ds_test = sv.DetectionDataset.from_yolo(
images_directory_path=f"{dataset.location}/test/images",
annotations_directory_path=f"{dataset.location}/test/labels",
data_yaml_path=f"{dataset.location}/data.yaml"
)
ds_train.classes
# ['person', 'bicycle', 'car', ...]
len(ds_train), len(ds_valid), len(ds_test)
# 800, 100, 100
```
=== "Pascal VOC"
We can do so using the [`sv.DetectionDataset.from_pascal_voc`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.from_pascal_voc) to load annotations in [Pascal VOC](https://roboflow.com/formats/pascal-voc-xml) format.
```python
import supervision as sv
ds_train = sv.DetectionDataset.from_pascal_voc(
images_directory_path=f"{dataset.location}/train/images",
annotations_directory_path=f"{dataset.location}/train/labels"
)
ds_valid = sv.DetectionDataset.from_pascal_voc(
images_directory_path=f"{dataset.location}/valid/images",
annotations_directory_path=f"{dataset.location}/valid/labels"
)
ds_test = sv.DetectionDataset.from_pascal_voc(
images_directory_path=f"{dataset.location}/test/images",
annotations_directory_path=f"{dataset.location}/test/labels"
)
ds_train.classes
# ['person', 'bicycle', 'car', ...]
len(ds_train), len(ds_valid), len(ds_test)
# 800, 100, 100
```
## Split Dataset
If your dataset is not already split into train, test, and valid subsets, you can
easily do so using the [`sv.DetectionDataset.split`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.split)
method. Let's assume we have a DetectionDataset named ds containing 1000 images. We
can split it as follows, ensuring a random shuffle of the data.
TODO
```python
>>> import supervision as sv
import supervision as sv
>>> ds = sv.DetectionDataset.from_coco(
... images_directory_path=f"{dataset.location}/train",
... annotations_path=f"{dataset.location}/train/_annotations.coco.json",
... )
ds = sv.DetectionDataset(...)
>>> ds.classes
['dog', 'person']
len(ds)
# 1000
ds_train, ds = ds.split(split_ratio=0.8, shuffle=True)
ds_valid, ds_test = ds.split(split_ratio=0.5, shuffle=True)
len(ds_train), len(ds_valid), len(ds_test)
# 800, 100, 100
```
## Iterate Over Dataset
There are two ways to loop over a `sv.DetectionDataset`:
- using a direct [for loop](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.__iter__)
called on the `sv.DetectionDataset` instance
- loading `sv.DetectionDataset` entries [by index](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.__getitem__).
```python
import supervision as sv
ds = sv.DetectionDataset(...)
# Option 1
for image_path, image, annotations in ds:
... # Process each image and its annotations
# Option 2
for idx in range(len(ds)):
image_path, image, annotations = ds[idx]
... # Process the image and annotations at index `idx`
```
## Visualize Dataset
TODO
The Supervision library provides tools for easily visualizing your detection dataset.
You can create a grid of annotated images to quickly inspect your data and labels.
First, initialize the [`sv.BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator)
and [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator).
Then, iterate through a subset of the dataset (e.g., the first 25 images), drawing
bounding boxes and class labels on each image. Finally, combine the annotated images
into a grid for display.
```python
>>> import supervision as sv
import supervision as sv
ds = sv.DetectionDataset(...)
box_annotator = sv.BoxAnnotator()
label_annotator = sv.LabelAnnotator()
annotated_images = []
for i in range(25):
_, image, annotations = ds[i]
labels = [ds.classes[class_id] for class_id in annotations.class_id]
annotated_image = image.copy()
annotated_image = box_annotator.annotate(annotated_image, annotations)
annotated_image = label_annotator.annotate(annotated_image, annotations, labels)
annotated_images.append(annotated_image)
grid = sv.create_tiles(
annotated_images,
grid_size=(5, 5),
single_tile_size=(400, 400),
tile_padding_color=sv.Color.WHITE,
tile_margin_color=sv.Color.WHITE
)
```
## Save Dataset
@ -62,20 +248,6 @@ TODO
>>> import supervision as sv
```
## Split Dataset
TODO
```python
>>> import supervision as sv
>>> train_ds, test_ds = ds.split(
... split_ratio=0.7,
... random_state=42,
... shuffle=True
... )
```
## Merge Dataset
TODO
@ -83,184 +255,3 @@ TODO
```python
>>> import supervision as sv
```
## Classification Dataset
TODO
```python
>>> import roboflow
>>> import supervision as sv
>>> roboflow.login()
>>> rf = roboflow.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 enables you to both process detections from a model and datasets. Dataset processing is implemented in the `sv.DetectionDataset` (object detection and segmentation) and `sv.ClassificationDataset` (classification) APIs.
The supervision `sv.DetectionDataset` and `sv.ClassificationDataset` APIs enables you to:
1. Load full datasets into supervision
2. Split datasets into train/test sets
3. Merge datasets together
Each image in a `DetectionDataset` object is assigned an [sv.Detections](https://supervision.roboflow.com/detection/core/) object that you can manipulate. Each image in a `ClassificationDataset` object is assigned a [Classifications](https://supervision.roboflow.com/classification/core/) object that you can manipulate.
In this guide, we will walk through how to accomplish all of the above tasks in supervision.
## Processing Detection Datasets
### Load a Dataset into Supervision
To load a dataset into supervision, you need to use a data loader. For this guide, we will load a COCO dataset, so we will use the `DetectionDataset.from_coco` data loader.
The following data loaders are supported:
- `DetectionDataset.from_coco` ([COCO JSON](https://roboflow.com/formats/coco-json))
- `DetectionDataset.from_yolo` ([YOLO PyTorch TXT](https://roboflow.com/formats/yolov8-pytorch-txt))
- `DetectionDataset.from_pascal_voc` ([Pascal VOC XML](https://roboflow.com/formats/pascal-voc-xml))
Create a new Python file and add the following code:
```python
import supervision as sv
DATASET_PATH = "football-players-detection"
ds = sv.DetectionDataset.from_yolo(
images_directory_path=f"{DATASET_PATH}/train/images",
annotations_directory_path=f"{DATASET_PATH}/train/labels",
data_yaml_path=f"{DATASET_PATH}/data.yaml"
)
print(ds.classes)
# ['ball', 'goalkeeper', 'player', 'referee']
```
This code loads a dataset stored in the YOLOv8 PyTorch TXT format into an `sv.DetectionDataset` object. Then, the classes in the dataset are printed out to the console.
### Split a Dataset into Train/Test Sets
To split a dataset into train/test datasets, you can use the `sv.DetectionDataset.split` method.
```python
train_ds, test_ds = ds.split(
split_ratio=0.7,
random_state=42,
shuffle=True
)
```
This code creates two `sv.DetectionDataset` instances. The first contains a train dataset and the second contains the test dataset. We have specified a 0.7 split, which means 70% of images will go to the test set.
You can use `random_state` to set a seed you can use to reproduce the same split. You can use `shuffle` to shuffle the dataset before splitting.
### Visualize Annotations
You can visualize annotations from an object detection and segmentation dataset using the `sv.BoundingBoxAnnotator` and `sv.MaskAnnotator` methods. See documentation for supervision anontators.
Let's visualize an image in a object detection dataset.
```python
image_name = DATASET_PATH + "/train/images/42ba34_9_9_png.rf.1f36573ac36d8b56c1f0a2f11bd480d4.jpg"
image = ds.images[image_name]
annotations = ds.annotations[image_name]
bounding_box_annotator = sv.BoundingBoxAnnotator()
label_annotator = sv.LabelAnnotator()
labels = [
ds.classes[class_id]
for class_id
in annotations.class_id
]
annotated_image = bounding_box_annotator.annotate(
scene=image, detections=annotations)
annotated_image = label_annotator.annotate(
scene=annotated_image, detections=annotations, labels=labels)
sv.plot_image(annotated_image)
```
Here is the output:
![Annotated Image of players on a football pitch](https://media.roboflow.com/football-players-supervision-example.png)
In the code above, we use retrieve an image from the dataset through the `ds.images` dictionary and its associated annotations (represented as a `sv.Detections` object) through the `ds.annotations` dictionary.
We use the `sv.BoundingBoxAnnotator` and `sv.LabelAnnotator` to annotate the image with bounding boxes and labels. We then plot the image using the `sv.plot_image` method.
## Merge Datasets
You can merge two detection datasets together using the `sv.DetectionDataset.merge` method.
```python
merged_ds = sv.ClassificationDataset.merge(
[cd_train, cd_test]
)
```
## Processing Classification Datasets
You can work with classification datasets using the `sv.ClassificationDataset` API.
### Load a Dataset into Supervision
To load a dataset into supervision, you need to use a data loader. You can load detections from a classification dataset using the `sv.ClassificationDataset.from_folder_structure` data loader.
```python
import supervision as sv
cd_train = sv.ClassificationDataset.from_folder_structure(
"artwork/train"
)
cd_test = sv.ClassificationDataset.from_folder_structure(
"artwork/test"
)
cd_valid = sv.ClassificationDataset.from_folder_structure(
"artwork/valid"
)
print(cd_train.classes)
# ['abstract', 'abstract digital', 'abstract digital landscape surrealism', 'abstract digital surrealism', ...]
```
`dataset/` is the path where your classification folder dataset is stored.
### Split a Dataset into Train/Test Sets
To split a dataset into train/test datasets, you can use the `sv.ClassificationDataset.split` method.
```python
train_ds, test_ds = ds.split(
split_ratio=0.7,
random_state=42,
shuffle=True
)
```
This code creates two `sv.ClassificationDataset` instances. The first contains a train dataset and the second contains the test dataset. We have specified a 0.7 split, which means 70% of images will go to the test set.
### Retrieve Annotations
You can retrieve annotations from a classification dataset using the `sv.ClassificationDataset.annotations` dictionary.
```python
image = "artwork/train/abstract digital/03c8e4c4430d631029694e64f4d29b97_jpg.rf.378dcf12b0adb97ee966d84fb63a0e28.jpg"
classes = cd_train.classes
print(classes[cd_train.annotations[image].class_id[0]])
# ['abstract digital']
```