superiorvision 0.30.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- superiorvision/__init__.py +19 -0
- superiorvision-0.30.0.dev0.dist-info/METADATA +398 -0
- superiorvision-0.30.0.dev0.dist-info/RECORD +96 -0
- superiorvision-0.30.0.dev0.dist-info/WHEEL +5 -0
- superiorvision-0.30.0.dev0.dist-info/licenses/LICENSE.md +9 -0
- superiorvision-0.30.0.dev0.dist-info/top_level.txt +2 -0
- supervision/__init__.py +318 -0
- supervision/annotators/__init__.py +0 -0
- supervision/annotators/base.py +21 -0
- supervision/annotators/core.py +3551 -0
- supervision/annotators/utils.py +541 -0
- supervision/assets/__init__.py +4 -0
- supervision/assets/downloader.py +166 -0
- supervision/assets/list.py +84 -0
- supervision/classification/__init__.py +0 -0
- supervision/classification/core.py +216 -0
- supervision/config.py +13 -0
- supervision/dataset/__init__.py +0 -0
- supervision/dataset/core.py +1313 -0
- supervision/dataset/formats/__init__.py +0 -0
- supervision/dataset/formats/coco.py +708 -0
- supervision/dataset/formats/createml.py +331 -0
- supervision/dataset/formats/labelme.py +405 -0
- supervision/dataset/formats/pascal_voc.py +449 -0
- supervision/dataset/formats/yolo.py +502 -0
- supervision/dataset/utils.py +265 -0
- supervision/detection/__init__.py +0 -0
- supervision/detection/compact_mask.py +1927 -0
- supervision/detection/core.py +3864 -0
- supervision/detection/line_zone.py +924 -0
- supervision/detection/overlap_filter.py +426 -0
- supervision/detection/tensor_utils.py +1596 -0
- supervision/detection/tensor_views.py +48 -0
- supervision/detection/tools/__init__.py +0 -0
- supervision/detection/tools/csv_sink.py +242 -0
- supervision/detection/tools/inference_slicer.py +776 -0
- supervision/detection/tools/json_sink.py +215 -0
- supervision/detection/tools/polygon_zone.py +266 -0
- supervision/detection/tools/smoother.py +218 -0
- supervision/detection/tools/transformers.py +265 -0
- supervision/detection/utils/__init__.py +12 -0
- supervision/detection/utils/_typing.py +11 -0
- supervision/detection/utils/boxes.py +510 -0
- supervision/detection/utils/converters.py +830 -0
- supervision/detection/utils/internal.py +806 -0
- supervision/detection/utils/iou_and_nms.py +1606 -0
- supervision/detection/utils/masks.py +625 -0
- supervision/detection/utils/polygons.py +128 -0
- supervision/detection/utils/vlms.py +97 -0
- supervision/detection/vlm.py +945 -0
- supervision/draw/__init__.py +0 -0
- supervision/draw/base.py +14 -0
- supervision/draw/color.py +598 -0
- supervision/draw/utils.py +527 -0
- supervision/geometry/__init__.py +0 -0
- supervision/geometry/core.py +208 -0
- supervision/geometry/utils.py +54 -0
- supervision/key_points/__init__.py +0 -0
- supervision/key_points/annotators.py +997 -0
- supervision/key_points/core.py +1506 -0
- supervision/key_points/skeletons.py +2646 -0
- supervision/keypoint/__init__.py +13 -0
- supervision/keypoint/annotators.py +13 -0
- supervision/keypoint/core.py +8 -0
- supervision/metrics/__init__.py +40 -0
- supervision/metrics/core.py +74 -0
- supervision/metrics/detection.py +1632 -0
- supervision/metrics/f1_score.py +815 -0
- supervision/metrics/mean_average_precision.py +1723 -0
- supervision/metrics/mean_average_recall.py +734 -0
- supervision/metrics/precision.py +815 -0
- supervision/metrics/recall.py +774 -0
- supervision/metrics/utils/__init__.py +0 -0
- supervision/metrics/utils/matching.py +56 -0
- supervision/metrics/utils/object_size.py +256 -0
- supervision/metrics/utils/utils.py +9 -0
- supervision/py.typed +0 -0
- supervision/tracker/__init__.py +5 -0
- supervision/tracker/byte_tracker/__init__.py +0 -0
- supervision/tracker/byte_tracker/core.py +448 -0
- supervision/tracker/byte_tracker/kalman_filter.py +186 -0
- supervision/tracker/byte_tracker/matching.py +211 -0
- supervision/tracker/byte_tracker/single_object_track.py +194 -0
- supervision/tracker/byte_tracker/utils.py +34 -0
- supervision/utils/__init__.py +0 -0
- supervision/utils/conversion.py +223 -0
- supervision/utils/deprecate.py +54 -0
- supervision/utils/file.py +209 -0
- supervision/utils/image.py +988 -0
- supervision/utils/internal.py +209 -0
- supervision/utils/iterables.py +103 -0
- supervision/utils/logger.py +61 -0
- supervision/utils/notebook.py +124 -0
- supervision/utils/tensor.py +362 -0
- supervision/utils/video.py +533 -0
- supervision/validators/__init__.py +379 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
BASE_VIDEO_URL = "https://media.roboflow.com/supervision/video-examples/"
|
|
6
|
+
BASE_IMAGE_URL = "https://media.roboflow.com/supervision/image-examples/"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Assets(Enum):
|
|
10
|
+
filename: str
|
|
11
|
+
md5_hash: str
|
|
12
|
+
|
|
13
|
+
def __new__(cls, filename: str, md5_hash: str) -> Assets:
|
|
14
|
+
obj = object.__new__(cls)
|
|
15
|
+
obj._value_ = filename
|
|
16
|
+
obj.filename = filename
|
|
17
|
+
obj.md5_hash = md5_hash
|
|
18
|
+
return obj
|
|
19
|
+
|
|
20
|
+
@classmethod
|
|
21
|
+
def list(cls) -> list[str]:
|
|
22
|
+
return [asset.filename for asset in cls]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class VideoAssets(Assets):
|
|
26
|
+
"""
|
|
27
|
+
Each member of this class represents a video asset. The value associated with each
|
|
28
|
+
member has a filename and hash of the video. File names and links can be seen below.
|
|
29
|
+
|
|
30
|
+
| Asset | Video Filename | Video URL |
|
|
31
|
+
|------------------------|----------------------------|---------------------------------------------------------------------------------------|
|
|
32
|
+
| `VEHICLES` | `vehicles.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/vehicles.mp4) |
|
|
33
|
+
| `MILK_BOTTLING_PLANT` | `milk-bottling-plant.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/milk-bottling-plant.mp4) |
|
|
34
|
+
| `VEHICLES_2` | `vehicles-2.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/vehicles-2.mp4) |
|
|
35
|
+
| `GROCERY_STORE` | `grocery-store.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/grocery-store.mp4) |
|
|
36
|
+
| `SUBWAY` | `subway.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/subway.mp4) |
|
|
37
|
+
| `MARKET_SQUARE` | `market-square.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/market-square.mp4) |
|
|
38
|
+
| `PEOPLE_WALKING` | `people-walking.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/people-walking.mp4) |
|
|
39
|
+
| `BEACH` | `beach-1.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/beach-1.mp4) |
|
|
40
|
+
| `BASKETBALL` | `basketball-1.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/basketball-1.mp4) |
|
|
41
|
+
| `SKIING` | `skiing.mp4` | [Link](https://media.roboflow.com/supervision/video-examples/skiing.mp4) |
|
|
42
|
+
""" # noqa: E501 // docs
|
|
43
|
+
|
|
44
|
+
VEHICLES = ("vehicles.mp4", "8155ff4e4de08cfa25f39de96483f918")
|
|
45
|
+
MILK_BOTTLING_PLANT = (
|
|
46
|
+
"milk-bottling-plant.mp4",
|
|
47
|
+
"9e8fb6e883f842a38b3d34267290bdc7",
|
|
48
|
+
)
|
|
49
|
+
VEHICLES_2 = ("vehicles-2.mp4", "830af6fba21ffbf14867a7fea595937b")
|
|
50
|
+
GROCERY_STORE = ("grocery-store.mp4", "48608fb4a8981f1c2469fa492adeec9c")
|
|
51
|
+
SUBWAY = ("subway.mp4", "453475750691fb23c56a0cffef089194")
|
|
52
|
+
MARKET_SQUARE = ("market-square.mp4", "859179bf4a21f80a8baabfdb2ed716dc")
|
|
53
|
+
PEOPLE_WALKING = ("people-walking.mp4", "0574c053c8686c3f1dc0aa3743e45cb9")
|
|
54
|
+
BEACH = ("beach-1.mp4", "4175d42fec4d450ed081523fd39e0cf8")
|
|
55
|
+
BASKETBALL = ("basketball-1.mp4", "60d94a3c7c47d16f09d342b088012ecc")
|
|
56
|
+
SKIING = ("skiing.mp4", "d30987cbab1bbc5934199cdd1b293119")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class ImageAssets(Assets):
|
|
60
|
+
"""
|
|
61
|
+
Each member of this enum represents a image asset. The value associated with each
|
|
62
|
+
member is the filename of the image.
|
|
63
|
+
|
|
64
|
+
| Asset | Image Filename | Video URL |
|
|
65
|
+
|--------------------|------------------------|---------------------------------------------------------------------------------------|
|
|
66
|
+
| `PEOPLE_WALKING` | `people-walking.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/people-walking.jpg) |
|
|
67
|
+
| `SOCCER` | `soccer.jpg` | [Link](https://media.roboflow.com/supervision/image-examples/soccer.jpg) |
|
|
68
|
+
|
|
69
|
+
""" # noqa: E501 // docs
|
|
70
|
+
|
|
71
|
+
PEOPLE_WALKING = ("people-walking.jpg", "e6bda00b47f2908eeae7df86ef995dcd")
|
|
72
|
+
SOCCER = ("soccer.jpg", "0f5a4b98abf3e3973faf9e9260a7d876")
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
MEDIA_ASSETS: dict[str, tuple[str, str]] = {
|
|
76
|
+
**{
|
|
77
|
+
asset.filename: (f"{BASE_VIDEO_URL}{asset.filename}", asset.md5_hash)
|
|
78
|
+
for asset in VideoAssets
|
|
79
|
+
},
|
|
80
|
+
**{
|
|
81
|
+
asset.filename: (f"{BASE_IMAGE_URL}{asset.filename}", asset.md5_hash)
|
|
82
|
+
for asset in ImageAssets
|
|
83
|
+
},
|
|
84
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import TYPE_CHECKING, Any
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
import numpy.typing as npt
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
import torch # type: ignore[import-not-found, unused-ignore]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _validate_class_ids(class_id: Any, n: int) -> None:
|
|
14
|
+
"""
|
|
15
|
+
Ensure that class_id is a 1d np.ndarray with (n, ) shape.
|
|
16
|
+
"""
|
|
17
|
+
is_valid = isinstance(class_id, np.ndarray) and class_id.shape == (n,)
|
|
18
|
+
if not is_valid:
|
|
19
|
+
raise ValueError("class_id must be 1d np.ndarray with (n, ) shape")
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _validate_confidence(confidence: Any, n: int) -> None:
|
|
23
|
+
"""
|
|
24
|
+
Ensure that confidence is a 1d np.ndarray with (n, ) shape.
|
|
25
|
+
"""
|
|
26
|
+
if confidence is not None:
|
|
27
|
+
is_valid = isinstance(confidence, np.ndarray) and confidence.shape == (n,)
|
|
28
|
+
if not is_valid:
|
|
29
|
+
raise ValueError("confidence must be 1d np.ndarray with (n, ) shape")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class Classifications:
|
|
34
|
+
class_id: npt.NDArray[np.int_]
|
|
35
|
+
confidence: npt.NDArray[np.floating] | None = None
|
|
36
|
+
|
|
37
|
+
def __post_init__(self) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Validate the classification inputs.
|
|
40
|
+
"""
|
|
41
|
+
n = len(self.class_id)
|
|
42
|
+
|
|
43
|
+
_validate_class_ids(self.class_id, n)
|
|
44
|
+
_validate_confidence(self.confidence, n)
|
|
45
|
+
|
|
46
|
+
def __eq__(self, other: object) -> bool:
|
|
47
|
+
"""
|
|
48
|
+
Compare classifications by value across numpy-backed fields.
|
|
49
|
+
"""
|
|
50
|
+
if not isinstance(other, Classifications):
|
|
51
|
+
return NotImplemented
|
|
52
|
+
if not np.array_equal(self.class_id, other.class_id):
|
|
53
|
+
return False
|
|
54
|
+
if self.confidence is None or other.confidence is None:
|
|
55
|
+
return self.confidence is other.confidence
|
|
56
|
+
return bool(np.array_equal(self.confidence, other.confidence))
|
|
57
|
+
|
|
58
|
+
def __len__(self) -> int:
|
|
59
|
+
"""
|
|
60
|
+
Returns the number of classifications.
|
|
61
|
+
"""
|
|
62
|
+
return len(self.class_id)
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def from_clip(cls, clip_results: torch.Tensor) -> Classifications:
|
|
66
|
+
"""
|
|
67
|
+
Creates a Classifications instance from a
|
|
68
|
+
[clip](https://github.com/openai/clip) inference result.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
clip_results: The inference result from clip model.
|
|
72
|
+
|
|
73
|
+
Returns:
|
|
74
|
+
A new Classifications object.
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
```python
|
|
78
|
+
from PIL import Image
|
|
79
|
+
import clip
|
|
80
|
+
import supervision as sv
|
|
81
|
+
|
|
82
|
+
model, preprocess = clip.load('ViT-B/32')
|
|
83
|
+
|
|
84
|
+
image = cv2.imread(SOURCE_IMAGE_PATH)
|
|
85
|
+
image = preprocess(image).unsqueeze(0)
|
|
86
|
+
|
|
87
|
+
text = clip.tokenize(["a diagram", "a dog", "a cat"])
|
|
88
|
+
output, _ = model(image, text)
|
|
89
|
+
classifications = sv.Classifications.from_clip(output)
|
|
90
|
+
```
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
confidence = clip_results.softmax(dim=-1).cpu().detach().numpy()[0]
|
|
94
|
+
|
|
95
|
+
if len(confidence) == 0:
|
|
96
|
+
return cls(
|
|
97
|
+
class_id=np.array([], dtype=np.int_),
|
|
98
|
+
confidence=np.array([], dtype=np.float32),
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
class_ids = np.arange(len(confidence))
|
|
102
|
+
return cls(class_id=class_ids, confidence=confidence)
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def from_ultralytics(cls, ultralytics_results: Any) -> Classifications:
|
|
106
|
+
"""
|
|
107
|
+
Creates a Classifications instance from a
|
|
108
|
+
[ultralytics](https://github.com/ultralytics/ultralytics) inference result.
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
ultralytics_results: The inference result from ultralytics model.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
A new Classifications object.
|
|
115
|
+
|
|
116
|
+
Example:
|
|
117
|
+
```python
|
|
118
|
+
import cv2
|
|
119
|
+
from ultralytics import YOLO
|
|
120
|
+
import supervision as sv
|
|
121
|
+
|
|
122
|
+
image = cv2.imread(SOURCE_IMAGE_PATH)
|
|
123
|
+
model = YOLO('yolov8n-cls.pt')
|
|
124
|
+
|
|
125
|
+
output = model(image)[0]
|
|
126
|
+
classifications = sv.Classifications.from_ultralytics(output)
|
|
127
|
+
```
|
|
128
|
+
"""
|
|
129
|
+
confidence = ultralytics_results.probs.data.cpu().numpy()
|
|
130
|
+
return cls(class_id=np.arange(confidence.shape[0]), confidence=confidence)
|
|
131
|
+
|
|
132
|
+
@classmethod
|
|
133
|
+
def from_timm(cls, timm_results: Any) -> Classifications:
|
|
134
|
+
"""
|
|
135
|
+
Creates a Classifications instance from a
|
|
136
|
+
[timm](https://huggingface.co/docs/hub/timm) inference result.
|
|
137
|
+
|
|
138
|
+
Note:
|
|
139
|
+
Returned confidences are softmax-normalized probabilities, so
|
|
140
|
+
thresholds calibrated against raw logits may need recalibration.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
timm_results: The inference result from timm model.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
A new Classifications object.
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
```python
|
|
150
|
+
from PIL import Image
|
|
151
|
+
import timm
|
|
152
|
+
from timm.data import resolve_data_config, create_transform
|
|
153
|
+
import supervision as sv
|
|
154
|
+
|
|
155
|
+
model = timm.create_model(
|
|
156
|
+
model_name='hf-hub:nateraw/resnet50-oxford-iiit-pet',
|
|
157
|
+
pretrained=True
|
|
158
|
+
).eval()
|
|
159
|
+
|
|
160
|
+
config = resolve_data_config({}, model=model)
|
|
161
|
+
transform = create_transform(**config)
|
|
162
|
+
|
|
163
|
+
image = Image.open(SOURCE_IMAGE_PATH).convert('RGB')
|
|
164
|
+
x = transform(image).unsqueeze(0)
|
|
165
|
+
|
|
166
|
+
output = model(x)
|
|
167
|
+
|
|
168
|
+
classifications = sv.Classifications.from_timm(output)
|
|
169
|
+
```
|
|
170
|
+
"""
|
|
171
|
+
confidence = timm_results.softmax(dim=-1).cpu().detach().numpy()[0]
|
|
172
|
+
|
|
173
|
+
if len(confidence) == 0:
|
|
174
|
+
return cls(
|
|
175
|
+
class_id=np.array([], dtype=np.int_),
|
|
176
|
+
confidence=np.array([], dtype=np.float32),
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
class_id = np.arange(len(confidence))
|
|
180
|
+
return cls(class_id=class_id, confidence=confidence)
|
|
181
|
+
|
|
182
|
+
def get_top_k(
|
|
183
|
+
self, k: int
|
|
184
|
+
) -> tuple[npt.NDArray[np.int_], npt.NDArray[np.floating]]:
|
|
185
|
+
"""
|
|
186
|
+
Retrieve the top k class IDs and confidences,
|
|
187
|
+
ordered in descending order by confidence.
|
|
188
|
+
|
|
189
|
+
Args:
|
|
190
|
+
k: The number of top class IDs and confidences to retrieve.
|
|
191
|
+
|
|
192
|
+
Returns:
|
|
193
|
+
A tuple containing the top k class IDs and confidences.
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
```pycon
|
|
197
|
+
>>> import numpy as np
|
|
198
|
+
>>> import supervision as sv
|
|
199
|
+
>>> classifications = sv.Classifications(
|
|
200
|
+
... class_id=np.array([0, 1, 2]),
|
|
201
|
+
... confidence=np.array([0.3, 0.9, 0.5])
|
|
202
|
+
... )
|
|
203
|
+
>>> classifications.get_top_k(1)
|
|
204
|
+
(array([1]), array([0.9]))
|
|
205
|
+
|
|
206
|
+
```
|
|
207
|
+
"""
|
|
208
|
+
if self.confidence is None:
|
|
209
|
+
raise ValueError("top_k could not be calculated, confidence is None")
|
|
210
|
+
|
|
211
|
+
order = np.argsort(self.confidence)[::-1]
|
|
212
|
+
top_k_order = order[:k]
|
|
213
|
+
top_k_class_id = self.class_id[top_k_order]
|
|
214
|
+
top_k_confidence = self.confidence[top_k_order]
|
|
215
|
+
|
|
216
|
+
return top_k_class_id, top_k_confidence
|
supervision/config.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
CLASS_NAME_DATA_FIELD: str = "class_name"
|
|
2
|
+
COCO_RAW_SEGMENTATION: str = "coco_raw_segmentation"
|
|
3
|
+
#: Key for oriented bounding-box corner coordinates in ``Detections.data``.
|
|
4
|
+
#:
|
|
5
|
+
#: Value layout: ``np.ndarray`` of shape ``(N, 4, 2)``, dtype ``float32``, pixel
|
|
6
|
+
#: coordinates ordered as ``[[x1, y1], [x2, y2], [x3, y3], [x4, y4]]`` per
|
|
7
|
+
#: detection where the four points are the corners of the oriented box.
|
|
8
|
+
#: Used by :func:`~supervision.dataset.formats.yolo.detections_to_yolo_annotations`
|
|
9
|
+
#: (``is_obb=True``) and
|
|
10
|
+
#: :func:`~supervision.dataset.formats.yolo.yolo_annotations_to_detections`
|
|
11
|
+
#: (``is_obb=True``).
|
|
12
|
+
#: Also triggers sequential mode in ``InferenceSlicer`` when present.
|
|
13
|
+
ORIENTED_BOX_COORDINATES: str = "xyxyxyxy"
|
|
File without changes
|