superiorvision 0.30.0.dev1__tar.gz → 0.30.0.dev2__tar.gz
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-0.30.0.dev1/src/superiorvision.egg-info → superiorvision-0.30.0.dev2}/PKG-INFO +2 -2
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/README.md +1 -1
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/pyproject.toml +1 -1
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2/src/superiorvision.egg-info}/PKG-INFO +2 -2
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/core.py +7 -16
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/overlap_filter.py +46 -11
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/transformers.py +101 -27
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/core.py +7 -9
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/LICENSE.md +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/setup.cfg +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/SOURCES.txt +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/dependency_links.txt +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/requires.txt +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/top_level.txt +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/base.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/assets/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/assets/downloader.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/assets/list.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/classification/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/classification/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/config.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/coco.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/createml.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/labelme.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/pascal_voc.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/yolo.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/compact_mask.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/line_zone.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tensor_utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tensor_views.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/csv_sink.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/inference_slicer.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/json_sink.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/polygon_zone.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tools/smoother.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/_typing.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/boxes.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/converters.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/internal.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/iou_and_nms.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/masks.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/polygons.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/vlms.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/vlm.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/draw/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/draw/base.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/draw/color.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/draw/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/geometry/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/geometry/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/geometry/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/annotators.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/skeletons.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/keypoint/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/keypoint/annotators.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/keypoint/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/detection.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/f1_score.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/mean_average_precision.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/mean_average_recall.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/precision.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/recall.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/matching.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/object_size.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/py.typed +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/core.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/kalman_filter.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/matching.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/single_object_track.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/byte_tracker/utils.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/conversion.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/deprecate.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/file.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/image.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/internal.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/iterables.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/logger.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/notebook.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/tensor.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/video.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/validators/__init__.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/tests/test_public_api.py +0 -0
- {superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/tests/test_validate_deprecations.py +0 -0
{superiorvision-0.30.0.dev1/src/superiorvision.egg-info → superiorvision-0.30.0.dev2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superiorvision
|
|
3
|
-
Version: 0.30.0.
|
|
3
|
+
Version: 0.30.0.dev2
|
|
4
4
|
Summary: A tensor-native, inference-focused fork of Supervision
|
|
5
5
|
Author-email: "Roboflow et al." <develop@roboflow.com>
|
|
6
6
|
Maintainer-email: Piotr Skalski <piotr@roboflow.com>
|
|
@@ -114,7 +114,7 @@ Install the SuperiorVision distribution in a
|
|
|
114
114
|
is currently a development release, so pin it explicitly:
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
pip install superiorvision==0.30.0.
|
|
117
|
+
pip install superiorvision==0.30.0.dev2
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
For an editable checkout:
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2/src/superiorvision.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: superiorvision
|
|
3
|
-
Version: 0.30.0.
|
|
3
|
+
Version: 0.30.0.dev2
|
|
4
4
|
Summary: A tensor-native, inference-focused fork of Supervision
|
|
5
5
|
Author-email: "Roboflow et al." <develop@roboflow.com>
|
|
6
6
|
Maintainer-email: Piotr Skalski <piotr@roboflow.com>
|
|
@@ -114,7 +114,7 @@ Install the SuperiorVision distribution in a
|
|
|
114
114
|
is currently a development release, so pin it explicitly:
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
pip install superiorvision==0.30.0.
|
|
117
|
+
pip install superiorvision==0.30.0.dev2
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
For an editable checkout:
|
|
@@ -63,9 +63,6 @@ from supervision.detection.utils.iou_and_nms import (
|
|
|
63
63
|
from supervision.detection.utils.iou_and_nms import (
|
|
64
64
|
box_non_max_merge as numpy_box_non_max_merge,
|
|
65
65
|
)
|
|
66
|
-
from supervision.detection.utils.iou_and_nms import (
|
|
67
|
-
box_non_max_suppression as numpy_box_non_max_suppression,
|
|
68
|
-
)
|
|
69
66
|
from supervision.detection.utils.iou_and_nms import (
|
|
70
67
|
mask_non_max_merge as numpy_mask_non_max_merge,
|
|
71
68
|
)
|
|
@@ -784,7 +781,7 @@ class Detections:
|
|
|
784
781
|
@classmethod
|
|
785
782
|
def from_transformers(
|
|
786
783
|
cls,
|
|
787
|
-
transformers_results:
|
|
784
|
+
transformers_results: Any,
|
|
788
785
|
id2label: dict[int, str] | None = None,
|
|
789
786
|
) -> Detections:
|
|
790
787
|
"""
|
|
@@ -2961,7 +2958,10 @@ class Detections:
|
|
|
2961
2958
|
):
|
|
2962
2959
|
index = [int(index)]
|
|
2963
2960
|
tensor_index = _index_for_device(index, self.xyxy.device)
|
|
2964
|
-
|
|
2961
|
+
needs_host_index = isinstance(self.mask, CompactMask) or any(
|
|
2962
|
+
not isinstance(value, torch.Tensor) for value in self.data.values()
|
|
2963
|
+
)
|
|
2964
|
+
host_index = _index_for_host(index) if needs_host_index else index
|
|
2965
2965
|
data: _DetectionDataType = {}
|
|
2966
2966
|
for key, value in self.data.items():
|
|
2967
2967
|
if isinstance(value, torch.Tensor):
|
|
@@ -3329,10 +3329,7 @@ class Detections:
|
|
|
3329
3329
|
)
|
|
3330
3330
|
|
|
3331
3331
|
if self.mask is not None:
|
|
3332
|
-
if (
|
|
3333
|
-
isinstance(self.mask, torch.Tensor)
|
|
3334
|
-
and overlap_metric == OverlapMetric.IOU
|
|
3335
|
-
):
|
|
3332
|
+
if isinstance(self.mask, torch.Tensor):
|
|
3336
3333
|
indices = tensor_mask_non_max_suppression(
|
|
3337
3334
|
predictions=predictions,
|
|
3338
3335
|
masks=self.mask,
|
|
@@ -3359,18 +3356,12 @@ class Detections:
|
|
|
3359
3356
|
iou_threshold=threshold,
|
|
3360
3357
|
overlap_metric=overlap_metric,
|
|
3361
3358
|
)
|
|
3362
|
-
|
|
3359
|
+
else:
|
|
3363
3360
|
indices = tensor_box_non_max_suppression(
|
|
3364
3361
|
predictions=predictions,
|
|
3365
3362
|
iou_threshold=threshold,
|
|
3366
3363
|
overlap_metric=overlap_metric,
|
|
3367
3364
|
)
|
|
3368
|
-
else:
|
|
3369
|
-
indices = numpy_box_non_max_suppression(
|
|
3370
|
-
predictions=to_numpy(predictions),
|
|
3371
|
-
iou_threshold=threshold,
|
|
3372
|
-
overlap_metric=overlap_metric,
|
|
3373
|
-
)
|
|
3374
3365
|
|
|
3375
3366
|
return self.select(indices)
|
|
3376
3367
|
|
|
@@ -10,6 +10,40 @@ import torch
|
|
|
10
10
|
from supervision.detection.utils import box_iou_batch, mask_iou_batch
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def _uses_intersection_over_smaller(overlap_metric: object | None) -> bool:
|
|
14
|
+
"""Return whether an overlap metric requests intersection over smaller area."""
|
|
15
|
+
value = getattr(overlap_metric, "value", overlap_metric)
|
|
16
|
+
return isinstance(value, str) and value.lower() == "ios"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _tensor_mask_overlap_batch(
|
|
20
|
+
masks: torch.Tensor, overlap_metric: object | None
|
|
21
|
+
) -> torch.Tensor:
|
|
22
|
+
"""Compute pairwise tensor mask overlap without leaving the source device."""
|
|
23
|
+
flat_masks = masks.bool().flatten(1)
|
|
24
|
+
intersection = (flat_masks[:, None] & flat_masks[None, :]).sum(dim=2)
|
|
25
|
+
areas = flat_masks.sum(dim=1)
|
|
26
|
+
if _uses_intersection_over_smaller(overlap_metric):
|
|
27
|
+
denominator = torch.minimum(areas[:, None], areas[None, :])
|
|
28
|
+
else:
|
|
29
|
+
denominator = areas[:, None] + areas[None, :] - intersection
|
|
30
|
+
return intersection / denominator.clamp(min=1)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _tensor_box_overlap_batch(
|
|
34
|
+
boxes: torch.Tensor, overlap_metric: object | None
|
|
35
|
+
) -> torch.Tensor:
|
|
36
|
+
"""Compute pairwise tensor box overlap without leaving the source device."""
|
|
37
|
+
if not _uses_intersection_over_smaller(overlap_metric):
|
|
38
|
+
return box_iou_batch(boxes, boxes)
|
|
39
|
+
areas = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])
|
|
40
|
+
top_left = torch.maximum(boxes[:, None, :2], boxes[:, :2])
|
|
41
|
+
bottom_right = torch.minimum(boxes[:, None, 2:], boxes[:, 2:])
|
|
42
|
+
intersection = (bottom_right - top_left).clamp(min=0).prod(dim=2)
|
|
43
|
+
denominator = torch.minimum(areas[:, None], areas[None, :])
|
|
44
|
+
return torch.nan_to_num(intersection / denominator)
|
|
45
|
+
|
|
46
|
+
|
|
13
47
|
def resize_masks(masks: np.ndarray, max_dimension: int = 640) -> np.ndarray:
|
|
14
48
|
"""
|
|
15
49
|
Resize all masks in the array to have a maximum dimension of max_dimension,
|
|
@@ -86,16 +120,15 @@ def mask_non_max_suppression(
|
|
|
86
120
|
# Pairwise mask IoU without leaving the source device. This is intentionally
|
|
87
121
|
# exact; callers wanting a reduced-resolution approximation can downsample
|
|
88
122
|
# the masks before constructing Detections.
|
|
89
|
-
|
|
90
|
-
intersection = (flat_masks[:, None] & flat_masks[None, :]).sum(dim=2)
|
|
91
|
-
areas = flat_masks.sum(dim=1)
|
|
92
|
-
ious = intersection / (areas[:, None] + areas[None, :] - intersection).clamp(min=1)
|
|
123
|
+
ious = _tensor_mask_overlap_batch(sorted_masks, overlap_metric)
|
|
93
124
|
categories = sorted_predictions[:, 5]
|
|
94
125
|
keep = torch.ones(rows, dtype=torch.bool, device=predictions.device)
|
|
95
126
|
for index in range(rows):
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
127
|
+
suppress = (
|
|
128
|
+
(ious[index] > iou_threshold)
|
|
129
|
+
& (categories == categories[index])
|
|
130
|
+
& keep[index]
|
|
131
|
+
)
|
|
99
132
|
suppress[index] = False
|
|
100
133
|
keep &= ~suppress
|
|
101
134
|
output = torch.zeros(rows, dtype=torch.bool, device=predictions.device)
|
|
@@ -159,12 +192,14 @@ def box_non_max_suppression(
|
|
|
159
192
|
sort_index = torch.argsort(predictions[:, 4], descending=True)
|
|
160
193
|
sorted_predictions = predictions[sort_index]
|
|
161
194
|
boxes, categories = sorted_predictions[:, :4], sorted_predictions[:, 5]
|
|
162
|
-
ious =
|
|
195
|
+
ious = _tensor_box_overlap_batch(boxes, overlap_metric)
|
|
163
196
|
keep = torch.ones(rows, dtype=torch.bool, device=predictions.device)
|
|
164
197
|
for index in range(rows):
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
198
|
+
suppress = (
|
|
199
|
+
(ious[index] > iou_threshold)
|
|
200
|
+
& (categories == categories[index])
|
|
201
|
+
& keep[index]
|
|
202
|
+
)
|
|
168
203
|
suppress[index] = False
|
|
169
204
|
keep &= ~suppress
|
|
170
205
|
output = torch.zeros(rows, dtype=torch.bool, device=predictions.device)
|
|
@@ -8,7 +8,43 @@ import numpy.typing as npt
|
|
|
8
8
|
from PIL import Image
|
|
9
9
|
|
|
10
10
|
from supervision.config import CLASS_NAME_DATA_FIELD
|
|
11
|
-
from supervision.detection.
|
|
11
|
+
from supervision.detection.tensor_utils import mask_to_xyxy
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _detach_numeric(value: Any) -> Any:
|
|
15
|
+
"""Detach real tensors in place while retaining legacy array-like inputs."""
|
|
16
|
+
import torch
|
|
17
|
+
|
|
18
|
+
if isinstance(value, torch.Tensor):
|
|
19
|
+
return value.detach()
|
|
20
|
+
if isinstance(value, np.ndarray):
|
|
21
|
+
return value
|
|
22
|
+
return value.detach().numpy()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _as_boolean(value: Any) -> Any:
|
|
26
|
+
"""Cast a numeric mask to boolean without changing its device or container."""
|
|
27
|
+
import torch
|
|
28
|
+
|
|
29
|
+
if isinstance(value, torch.Tensor):
|
|
30
|
+
return value.to(dtype=torch.bool)
|
|
31
|
+
return value.astype(bool)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _as_integer(value: Any) -> Any:
|
|
35
|
+
"""Cast class identifiers to integers without changing their device."""
|
|
36
|
+
import torch
|
|
37
|
+
|
|
38
|
+
if isinstance(value, torch.Tensor):
|
|
39
|
+
return value.to(dtype=torch.long)
|
|
40
|
+
return value.astype(int)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def _is_tensor(value: Any) -> bool:
|
|
44
|
+
"""Return whether a value is a Torch tensor without importing Torch eagerly."""
|
|
45
|
+
import torch
|
|
46
|
+
|
|
47
|
+
return isinstance(value, torch.Tensor)
|
|
12
48
|
|
|
13
49
|
|
|
14
50
|
def process_transformers_detection_result(
|
|
@@ -29,12 +65,12 @@ def process_transformers_detection_result(
|
|
|
29
65
|
Processed detection result including bounding boxes, confidence scores,
|
|
30
66
|
class IDs, and data.
|
|
31
67
|
"""
|
|
32
|
-
class_ids = detection_result["labels"]
|
|
68
|
+
class_ids = _as_integer(_detach_numeric(detection_result["labels"]))
|
|
33
69
|
data = append_class_names_to_data(class_ids, id2label, {})
|
|
34
70
|
|
|
35
71
|
return dict(
|
|
36
|
-
xyxy=detection_result["boxes"]
|
|
37
|
-
confidence=detection_result["scores"]
|
|
72
|
+
xyxy=_detach_numeric(detection_result["boxes"]),
|
|
73
|
+
confidence=_detach_numeric(detection_result["scores"]),
|
|
38
74
|
class_id=class_ids,
|
|
39
75
|
data=data,
|
|
40
76
|
)
|
|
@@ -66,14 +102,14 @@ def process_transformers_v4_segmentation_result(
|
|
|
66
102
|
else:
|
|
67
103
|
boxes = None
|
|
68
104
|
if "boxes" in segmentation_result:
|
|
69
|
-
boxes = segmentation_result["boxes"]
|
|
70
|
-
masks = segmentation_result["masks"]
|
|
71
|
-
class_ids = segmentation_result["labels"]
|
|
105
|
+
boxes = _detach_numeric(segmentation_result["boxes"])
|
|
106
|
+
masks = _as_boolean(_detach_numeric(segmentation_result["masks"]))
|
|
107
|
+
class_ids = _as_integer(_detach_numeric(segmentation_result["labels"]))
|
|
72
108
|
|
|
73
109
|
return dict(
|
|
74
110
|
xyxy=boxes if boxes is not None else mask_to_xyxy(masks),
|
|
75
|
-
mask=
|
|
76
|
-
confidence=segmentation_result["scores"]
|
|
111
|
+
mask=masks.squeeze(1) if boxes is not None else masks,
|
|
112
|
+
confidence=_detach_numeric(segmentation_result["scores"]),
|
|
77
113
|
class_id=class_ids,
|
|
78
114
|
data=append_class_names_to_data(class_ids, id2label, {}),
|
|
79
115
|
)
|
|
@@ -99,8 +135,13 @@ def process_transformers_v5_segmentation_result(
|
|
|
99
135
|
Processed segmentation result including bounding boxes, masks, confidence
|
|
100
136
|
scores, class IDs, and data.
|
|
101
137
|
"""
|
|
138
|
+
if _is_tensor(segmentation_result):
|
|
139
|
+
segmentation_array = segmentation_result.detach()
|
|
140
|
+
return process_transformers_v5_panoptic_segmentation_result(
|
|
141
|
+
segmentation_array, id2label
|
|
142
|
+
)
|
|
102
143
|
if segmentation_result.__class__.__name__ == "Tensor":
|
|
103
|
-
segmentation_array = segmentation_result.
|
|
144
|
+
segmentation_array = segmentation_result.detach().numpy()
|
|
104
145
|
return process_transformers_v5_panoptic_segmentation_result(
|
|
105
146
|
segmentation_array, id2label
|
|
106
147
|
)
|
|
@@ -128,15 +169,38 @@ def process_transformers_v5_semantic_or_instance_segmentation_result(
|
|
|
128
169
|
scores, class IDs, and data.
|
|
129
170
|
"""
|
|
130
171
|
segments_info = segmentation_result["segments_info"]
|
|
131
|
-
segmentation_array = segmentation_result["segmentation"]
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
172
|
+
segmentation_array = _detach_numeric(segmentation_result["segmentation"])
|
|
173
|
+
if _is_tensor(segmentation_array):
|
|
174
|
+
import torch
|
|
175
|
+
|
|
176
|
+
device = segmentation_array.device
|
|
177
|
+
scores = torch.tensor(
|
|
178
|
+
[segment["score"] for segment in segments_info],
|
|
179
|
+
dtype=torch.float32,
|
|
180
|
+
device=device,
|
|
181
|
+
)
|
|
182
|
+
class_ids = torch.tensor(
|
|
183
|
+
[segment["label_id"] for segment in segments_info],
|
|
184
|
+
dtype=torch.long,
|
|
185
|
+
device=device,
|
|
186
|
+
)
|
|
187
|
+
segment_ids = torch.tensor(
|
|
188
|
+
[segment["id"] for segment in segments_info],
|
|
189
|
+
dtype=segmentation_array.dtype,
|
|
190
|
+
device=device,
|
|
191
|
+
)
|
|
192
|
+
masks = segmentation_array.unsqueeze(0) == segment_ids[:, None, None]
|
|
136
193
|
else:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
194
|
+
scores = np.array([segment["score"] for segment in segments_info], dtype=float)
|
|
195
|
+
class_ids = np.array(
|
|
196
|
+
[segment["label_id"] for segment in segments_info], dtype=int
|
|
197
|
+
)
|
|
198
|
+
if len(segments_info) == 0:
|
|
199
|
+
masks = np.empty((0, *segmentation_array.shape), dtype=bool)
|
|
200
|
+
else:
|
|
201
|
+
masks = np.array(
|
|
202
|
+
[segmentation_array == segment["id"] for segment in segments_info]
|
|
203
|
+
).astype(bool)
|
|
140
204
|
data = append_class_names_to_data(class_ids, id2label, {})
|
|
141
205
|
|
|
142
206
|
return dict(
|
|
@@ -183,7 +247,7 @@ def process_transformers_v4_panoptic_segmentation_result(
|
|
|
183
247
|
|
|
184
248
|
|
|
185
249
|
def process_transformers_v5_panoptic_segmentation_result(
|
|
186
|
-
segmentation_array:
|
|
250
|
+
segmentation_array: Any, id2label: dict[int, str] | None
|
|
187
251
|
) -> dict[str, Any]:
|
|
188
252
|
"""
|
|
189
253
|
Process a v5 Transformers semantic segmentation tensor.
|
|
@@ -198,13 +262,19 @@ def process_transformers_v5_panoptic_segmentation_result(
|
|
|
198
262
|
Processed segmentation result including bounding boxes, masks,
|
|
199
263
|
class IDs, and data.
|
|
200
264
|
"""
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
265
|
+
if _is_tensor(segmentation_array):
|
|
266
|
+
import torch
|
|
267
|
+
|
|
268
|
+
class_ids = torch.unique(segmentation_array).to(dtype=torch.long)
|
|
269
|
+
masks = segmentation_array.unsqueeze(0) == class_ids[:, None, None]
|
|
204
270
|
else:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
271
|
+
class_ids = np.unique(segmentation_array).astype(int)
|
|
272
|
+
if len(class_ids) == 0:
|
|
273
|
+
masks = np.empty((0, *segmentation_array.shape), dtype=bool)
|
|
274
|
+
else:
|
|
275
|
+
masks = np.stack(
|
|
276
|
+
[segmentation_array == class_id for class_id in class_ids], axis=0
|
|
277
|
+
).astype(bool)
|
|
208
278
|
data = append_class_names_to_data(class_ids, id2label, {})
|
|
209
279
|
return dict(xyxy=mask_to_xyxy(masks), mask=masks, class_id=class_ids, data=data)
|
|
210
280
|
|
|
@@ -237,7 +307,7 @@ def png_string_to_segmentation_array(png_string: bytes) -> npt.NDArray[Any]:
|
|
|
237
307
|
|
|
238
308
|
|
|
239
309
|
def append_class_names_to_data(
|
|
240
|
-
class_ids:
|
|
310
|
+
class_ids: Any,
|
|
241
311
|
id2label: dict[int, str] | None,
|
|
242
312
|
data: dict[str, Any] | None = None,
|
|
243
313
|
) -> dict[str, Any]:
|
|
@@ -259,7 +329,11 @@ def append_class_names_to_data(
|
|
|
259
329
|
data = {}
|
|
260
330
|
|
|
261
331
|
if id2label is not None:
|
|
262
|
-
|
|
332
|
+
if _is_tensor(class_ids):
|
|
333
|
+
host_class_ids = class_ids.detach().cpu().tolist()
|
|
334
|
+
else:
|
|
335
|
+
host_class_ids = class_ids.tolist()
|
|
336
|
+
class_names = np.array([id2label[class_id] for class_id in host_class_ids])
|
|
263
337
|
data[CLASS_NAME_DATA_FIELD] = class_names
|
|
264
338
|
|
|
265
339
|
return data
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/core.py
RENAMED
|
@@ -11,6 +11,7 @@ import torch
|
|
|
11
11
|
|
|
12
12
|
from supervision.config import CLASS_NAME_DATA_FIELD
|
|
13
13
|
from supervision.detection.core import Detections
|
|
14
|
+
from supervision.detection.overlap_filter import box_non_max_suppression
|
|
14
15
|
from supervision.detection.utils._typing import (
|
|
15
16
|
_DetectionDataType,
|
|
16
17
|
_DetectionDataValueType,
|
|
@@ -20,10 +21,7 @@ from supervision.detection.utils.internal import (
|
|
|
20
21
|
is_data_equal,
|
|
21
22
|
merge_data,
|
|
22
23
|
)
|
|
23
|
-
from supervision.detection.utils.iou_and_nms import
|
|
24
|
-
OverlapMetric,
|
|
25
|
-
box_non_max_suppression,
|
|
26
|
-
)
|
|
24
|
+
from supervision.detection.utils.iou_and_nms import OverlapMetric
|
|
27
25
|
from supervision.utils.internal import warn_deprecated
|
|
28
26
|
from supervision.utils.tensor import as_tensor, tensor_data
|
|
29
27
|
from supervision.validators import _validate_keypoints_fields
|
|
@@ -56,11 +54,6 @@ def _select_data(
|
|
|
56
54
|
) -> _DetectionDataType:
|
|
57
55
|
"""Select mixed tensor/host metadata without moving numeric tensors off device."""
|
|
58
56
|
selected: dict[str, Any] = {}
|
|
59
|
-
host_index: int | slice | npt.NDArray[np.generic]
|
|
60
|
-
if isinstance(index, torch.Tensor):
|
|
61
|
-
host_index = index.detach().cpu().numpy()
|
|
62
|
-
else:
|
|
63
|
-
host_index = index
|
|
64
57
|
for key, value in data.items():
|
|
65
58
|
if isinstance(value, torch.Tensor):
|
|
66
59
|
tensor_index = (
|
|
@@ -70,6 +63,11 @@ def _select_data(
|
|
|
70
63
|
)
|
|
71
64
|
selected[key] = value[tensor_index]
|
|
72
65
|
else:
|
|
66
|
+
host_index = (
|
|
67
|
+
index.detach().cpu().numpy()
|
|
68
|
+
if isinstance(index, torch.Tensor)
|
|
69
|
+
else index
|
|
70
|
+
)
|
|
73
71
|
selected.update(get_data_item({key: value}, cast(Any, host_index)))
|
|
74
72
|
return cast(_DetectionDataType, selected)
|
|
75
73
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/requires.txt
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/superiorvision.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/base.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/core.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/annotators/utils.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/assets/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/assets/downloader.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/classification/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/classification/core.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/coco.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/labelme.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/dataset/formats/yolo.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/compact_mask.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/line_zone.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tensor_utils.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/tensor_views.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/_typing.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/boxes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/masks.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/detection/utils/vlms.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/geometry/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/annotators.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/key_points/skeletons.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/keypoint/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/keypoint/annotators.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/detection.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/f1_score.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/precision.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/__init__.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/matching.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/metrics/utils/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/tracker/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/conversion.py
RENAMED
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/deprecate.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/utils/iterables.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/src/supervision/validators/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{superiorvision-0.30.0.dev1 → superiorvision-0.30.0.dev2}/tests/test_validate_deprecations.py
RENAMED
|
File without changes
|