valor-lite 0.34.3__py3-none-any.whl → 0.36.0__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.
Potentially problematic release.
This version of valor-lite might be problematic. Click here for more details.
- valor_lite/classification/computation.py +147 -38
- valor_lite/classification/manager.py +229 -236
- valor_lite/classification/metric.py +5 -8
- valor_lite/classification/utilities.py +18 -14
- valor_lite/object_detection/__init__.py +2 -15
- valor_lite/object_detection/annotation.py +24 -48
- valor_lite/object_detection/computation.py +324 -384
- valor_lite/object_detection/manager.py +549 -456
- valor_lite/object_detection/metric.py +16 -34
- valor_lite/object_detection/utilities.py +134 -305
- valor_lite/semantic_segmentation/__init__.py +3 -3
- valor_lite/semantic_segmentation/annotation.py +32 -103
- valor_lite/semantic_segmentation/benchmark.py +87 -1
- valor_lite/semantic_segmentation/computation.py +96 -14
- valor_lite/semantic_segmentation/manager.py +199 -222
- valor_lite/semantic_segmentation/utilities.py +3 -3
- {valor_lite-0.34.3.dist-info → valor_lite-0.36.0.dist-info}/METADATA +2 -2
- {valor_lite-0.34.3.dist-info → valor_lite-0.36.0.dist-info}/RECORD +20 -20
- {valor_lite-0.34.3.dist-info → valor_lite-0.36.0.dist-info}/WHEEL +1 -1
- {valor_lite-0.34.3.dist-info → valor_lite-0.36.0.dist-info}/top_level.txt +0 -0
|
@@ -19,7 +19,7 @@ def unpack_precision_recall_rocauc_into_metric_lists(
|
|
|
19
19
|
score_thresholds: list[float],
|
|
20
20
|
hardmax: bool,
|
|
21
21
|
label_metadata: NDArray[np.int32],
|
|
22
|
-
index_to_label:
|
|
22
|
+
index_to_label: list[str],
|
|
23
23
|
) -> dict[MetricType, list[Metric]]:
|
|
24
24
|
(
|
|
25
25
|
counts,
|
|
@@ -38,7 +38,7 @@ def unpack_precision_recall_rocauc_into_metric_lists(
|
|
|
38
38
|
value=float(rocauc[label_idx]),
|
|
39
39
|
label=label,
|
|
40
40
|
)
|
|
41
|
-
for label_idx, label in index_to_label
|
|
41
|
+
for label_idx, label in enumerate(index_to_label)
|
|
42
42
|
if label_metadata[label_idx, 0] > 0
|
|
43
43
|
]
|
|
44
44
|
|
|
@@ -57,7 +57,7 @@ def unpack_precision_recall_rocauc_into_metric_lists(
|
|
|
57
57
|
for score_idx, score_threshold in enumerate(score_thresholds)
|
|
58
58
|
]
|
|
59
59
|
|
|
60
|
-
for label_idx, label in index_to_label
|
|
60
|
+
for label_idx, label in enumerate(index_to_label):
|
|
61
61
|
for score_idx, score_threshold in enumerate(score_thresholds):
|
|
62
62
|
|
|
63
63
|
kwargs = {
|
|
@@ -105,8 +105,8 @@ def _unpack_confusion_matrix_value(
|
|
|
105
105
|
confusion_matrix: NDArray[np.float64],
|
|
106
106
|
number_of_labels: int,
|
|
107
107
|
number_of_examples: int,
|
|
108
|
-
|
|
109
|
-
index_to_label:
|
|
108
|
+
index_to_datum_id: list[str],
|
|
109
|
+
index_to_label: list[str],
|
|
110
110
|
) -> dict[str, dict[str, dict[str, int | list[dict[str, str | float]]]]]:
|
|
111
111
|
"""
|
|
112
112
|
Unpacks a numpy array of confusion matrix counts and examples.
|
|
@@ -137,7 +137,7 @@ def _unpack_confusion_matrix_value(
|
|
|
137
137
|
),
|
|
138
138
|
"examples": [
|
|
139
139
|
{
|
|
140
|
-
"
|
|
140
|
+
"datum_id": index_to_datum_id[
|
|
141
141
|
datum_idx(gt_label_idx, pd_label_idx, example_idx)
|
|
142
142
|
],
|
|
143
143
|
"score": score_idx(
|
|
@@ -158,8 +158,8 @@ def _unpack_unmatched_ground_truths_value(
|
|
|
158
158
|
unmatched_ground_truths: NDArray[np.int32],
|
|
159
159
|
number_of_labels: int,
|
|
160
160
|
number_of_examples: int,
|
|
161
|
-
|
|
162
|
-
index_to_label:
|
|
161
|
+
index_to_datum_id: list[str],
|
|
162
|
+
index_to_label: list[str],
|
|
163
163
|
) -> dict[str, dict[str, int | list[dict[str, str]]]]:
|
|
164
164
|
"""
|
|
165
165
|
Unpacks a numpy array of unmatched ground truth counts and examples.
|
|
@@ -181,7 +181,11 @@ def _unpack_unmatched_ground_truths_value(
|
|
|
181
181
|
0,
|
|
182
182
|
),
|
|
183
183
|
"examples": [
|
|
184
|
-
{
|
|
184
|
+
{
|
|
185
|
+
"datum_id": index_to_datum_id[
|
|
186
|
+
datum_idx(gt_label_idx, example_idx)
|
|
187
|
+
]
|
|
188
|
+
}
|
|
185
189
|
for example_idx in range(number_of_examples)
|
|
186
190
|
if datum_idx(gt_label_idx, example_idx) >= 0
|
|
187
191
|
],
|
|
@@ -194,12 +198,12 @@ def unpack_confusion_matrix_into_metric_list(
|
|
|
194
198
|
results: tuple[NDArray[np.float64], NDArray[np.int32]],
|
|
195
199
|
score_thresholds: list[float],
|
|
196
200
|
number_of_examples: int,
|
|
197
|
-
|
|
198
|
-
index_to_label:
|
|
201
|
+
index_to_datum_id: list[str],
|
|
202
|
+
index_to_label: list[str],
|
|
199
203
|
) -> list[Metric]:
|
|
200
204
|
|
|
201
205
|
(confusion_matrix, unmatched_ground_truths) = results
|
|
202
|
-
|
|
206
|
+
_, n_labels, _, _ = confusion_matrix.shape
|
|
203
207
|
return [
|
|
204
208
|
Metric.confusion_matrix(
|
|
205
209
|
score_threshold=score_threshold,
|
|
@@ -209,7 +213,7 @@ def unpack_confusion_matrix_into_metric_list(
|
|
|
209
213
|
number_of_labels=n_labels,
|
|
210
214
|
number_of_examples=number_of_examples,
|
|
211
215
|
index_to_label=index_to_label,
|
|
212
|
-
|
|
216
|
+
index_to_datum_id=index_to_datum_id,
|
|
213
217
|
),
|
|
214
218
|
unmatched_ground_truths=_unpack_unmatched_ground_truths_value(
|
|
215
219
|
unmatched_ground_truths=unmatched_ground_truths[
|
|
@@ -218,7 +222,7 @@ def unpack_confusion_matrix_into_metric_list(
|
|
|
218
222
|
number_of_labels=n_labels,
|
|
219
223
|
number_of_examples=number_of_examples,
|
|
220
224
|
index_to_label=index_to_label,
|
|
221
|
-
|
|
225
|
+
index_to_datum_id=index_to_datum_id,
|
|
222
226
|
),
|
|
223
227
|
)
|
|
224
228
|
for score_idx, score_threshold in enumerate(score_thresholds)
|
|
@@ -1,13 +1,5 @@
|
|
|
1
1
|
from .annotation import Bitmask, BoundingBox, Detection, Polygon
|
|
2
|
-
from .
|
|
3
|
-
compute_bbox_iou,
|
|
4
|
-
compute_bitmask_iou,
|
|
5
|
-
compute_confusion_matrix,
|
|
6
|
-
compute_polygon_iou,
|
|
7
|
-
compute_precion_recall,
|
|
8
|
-
compute_ranked_pairs,
|
|
9
|
-
)
|
|
10
|
-
from .manager import DataLoader, Evaluator
|
|
2
|
+
from .manager import DataLoader, Evaluator, Filter
|
|
11
3
|
from .metric import Metric, MetricType
|
|
12
4
|
|
|
13
5
|
__all__ = [
|
|
@@ -17,12 +9,7 @@ __all__ = [
|
|
|
17
9
|
"Polygon",
|
|
18
10
|
"Metric",
|
|
19
11
|
"MetricType",
|
|
20
|
-
"compute_bbox_iou",
|
|
21
|
-
"compute_bitmask_iou",
|
|
22
|
-
"compute_polygon_iou",
|
|
23
|
-
"compute_ranked_pairs",
|
|
24
|
-
"compute_precion_recall",
|
|
25
|
-
"compute_confusion_matrix",
|
|
26
12
|
"DataLoader",
|
|
27
13
|
"Evaluator",
|
|
14
|
+
"Filter",
|
|
28
15
|
]
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Generic, TypeVar
|
|
2
3
|
|
|
3
4
|
import numpy as np
|
|
4
5
|
from numpy.typing import NDArray
|
|
@@ -12,6 +13,8 @@ class BoundingBox:
|
|
|
12
13
|
|
|
13
14
|
Parameters
|
|
14
15
|
----------
|
|
16
|
+
uid : str
|
|
17
|
+
A unique identifier.
|
|
15
18
|
xmin : float
|
|
16
19
|
The minimum x-coordinate of the bounding box.
|
|
17
20
|
xmax : float
|
|
@@ -29,16 +32,18 @@ class BoundingBox:
|
|
|
29
32
|
--------
|
|
30
33
|
Ground Truth Example:
|
|
31
34
|
|
|
32
|
-
>>> bbox = BoundingBox(xmin=10.0, xmax=50.0, ymin=20.0, ymax=60.0, labels=['cat'])
|
|
35
|
+
>>> bbox = BoundingBox(uid="xyz", xmin=10.0, xmax=50.0, ymin=20.0, ymax=60.0, labels=['cat'])
|
|
33
36
|
|
|
34
37
|
Prediction Example:
|
|
35
38
|
|
|
36
39
|
>>> bbox = BoundingBox(
|
|
40
|
+
... uid="abc",
|
|
37
41
|
... xmin=10.0, xmax=50.0, ymin=20.0, ymax=60.0,
|
|
38
42
|
... labels=['cat', 'dog'], scores=[0.9, 0.1]
|
|
39
43
|
... )
|
|
40
44
|
"""
|
|
41
45
|
|
|
46
|
+
uid: str
|
|
42
47
|
xmin: float
|
|
43
48
|
xmax: float
|
|
44
49
|
ymin: float
|
|
@@ -58,18 +63,6 @@ class BoundingBox:
|
|
|
58
63
|
|
|
59
64
|
@property
|
|
60
65
|
def extrema(self) -> tuple[float, float, float, float]:
|
|
61
|
-
"""
|
|
62
|
-
Returns the bounding box extrema.
|
|
63
|
-
|
|
64
|
-
Returns
|
|
65
|
-
-------
|
|
66
|
-
tuple[float, float, float, float]
|
|
67
|
-
A tuple in the form (xmin, xmax, ymin, ymax).
|
|
68
|
-
"""
|
|
69
|
-
return (self.xmin, self.xmax, self.ymin, self.ymax)
|
|
70
|
-
|
|
71
|
-
@property
|
|
72
|
-
def annotation(self) -> tuple[float, float, float, float]:
|
|
73
66
|
"""
|
|
74
67
|
Returns the annotation's data representation.
|
|
75
68
|
|
|
@@ -78,7 +71,7 @@ class BoundingBox:
|
|
|
78
71
|
tuple[float, float, float, float]
|
|
79
72
|
A tuple in the form (xmin, xmax, ymin, ymax).
|
|
80
73
|
"""
|
|
81
|
-
return self.
|
|
74
|
+
return (self.xmin, self.xmax, self.ymin, self.ymax)
|
|
82
75
|
|
|
83
76
|
|
|
84
77
|
@dataclass
|
|
@@ -88,7 +81,9 @@ class Polygon:
|
|
|
88
81
|
|
|
89
82
|
Parameters
|
|
90
83
|
----------
|
|
91
|
-
|
|
84
|
+
uid : str
|
|
85
|
+
A unique identifier.
|
|
86
|
+
shape : shapely.geometry.Polygon
|
|
92
87
|
A Shapely polygon object representing the shape.
|
|
93
88
|
labels : list of str
|
|
94
89
|
List of labels associated with the polygon.
|
|
@@ -101,15 +96,16 @@ class Polygon:
|
|
|
101
96
|
|
|
102
97
|
>>> from shapely.geometry import Polygon as ShapelyPolygon
|
|
103
98
|
>>> shape = ShapelyPolygon([(0, 0), (1, 0), (1, 1), (0, 1)])
|
|
104
|
-
>>> polygon = Polygon(shape=shape, labels=['building'])
|
|
99
|
+
>>> polygon = Polygon(uid="xyz", shape=shape, labels=['building'])
|
|
105
100
|
|
|
106
101
|
Prediction Example:
|
|
107
102
|
|
|
108
103
|
>>> polygon = Polygon(
|
|
109
|
-
... shape=shape, labels=['building'], scores=[0.95]
|
|
104
|
+
... uid="abc", shape=shape, labels=['building'], scores=[0.95]
|
|
110
105
|
... )
|
|
111
106
|
"""
|
|
112
107
|
|
|
108
|
+
uid: str
|
|
113
109
|
shape: ShapelyPolygon
|
|
114
110
|
labels: list[str]
|
|
115
111
|
scores: list[float] = field(default_factory=list)
|
|
@@ -129,19 +125,6 @@ class Polygon:
|
|
|
129
125
|
"If scores are defined, there must be a 1:1 pairing with labels."
|
|
130
126
|
)
|
|
131
127
|
|
|
132
|
-
@property
|
|
133
|
-
def extrema(self) -> tuple[float, float, float, float]:
|
|
134
|
-
"""
|
|
135
|
-
Returns the polygon's bounding box extrema.
|
|
136
|
-
|
|
137
|
-
Returns
|
|
138
|
-
-------
|
|
139
|
-
tuple[float, float, float, float]
|
|
140
|
-
A tuple in the form (xmin, xmax, ymin, ymax).
|
|
141
|
-
"""
|
|
142
|
-
xmin, ymin, xmax, ymax = self.shape.bounds
|
|
143
|
-
return (xmin, xmax, ymin, ymax)
|
|
144
|
-
|
|
145
128
|
|
|
146
129
|
@dataclass
|
|
147
130
|
class Bitmask:
|
|
@@ -150,6 +133,8 @@ class Bitmask:
|
|
|
150
133
|
|
|
151
134
|
Parameters
|
|
152
135
|
----------
|
|
136
|
+
uid : str
|
|
137
|
+
A unique identifier.
|
|
153
138
|
mask : NDArray[np.bool_]
|
|
154
139
|
A NumPy array of boolean values representing the mask.
|
|
155
140
|
labels : list of str
|
|
@@ -163,15 +148,16 @@ class Bitmask:
|
|
|
163
148
|
|
|
164
149
|
>>> import numpy as np
|
|
165
150
|
>>> mask = np.array([[True, False], [False, True]], dtype=np.bool_)
|
|
166
|
-
>>> bitmask = Bitmask(mask=mask, labels=['tree'])
|
|
151
|
+
>>> bitmask = Bitmask(uid="abc", mask=mask, labels=['tree'])
|
|
167
152
|
|
|
168
153
|
Prediction Example:
|
|
169
154
|
|
|
170
155
|
>>> bitmask = Bitmask(
|
|
171
|
-
... mask=mask, labels=['tree'], scores=[0.85]
|
|
156
|
+
... uid="xyz", mask=mask, labels=['tree'], scores=[0.85]
|
|
172
157
|
... )
|
|
173
158
|
"""
|
|
174
159
|
|
|
160
|
+
uid: str
|
|
175
161
|
mask: NDArray[np.bool_]
|
|
176
162
|
labels: list[str]
|
|
177
163
|
scores: list[float] = field(default_factory=list)
|
|
@@ -197,22 +183,12 @@ class Bitmask:
|
|
|
197
183
|
"If scores are defined, there must be a 1:1 pairing with labels."
|
|
198
184
|
)
|
|
199
185
|
|
|
200
|
-
@property
|
|
201
|
-
def extrema(self) -> tuple[float, float, float, float]:
|
|
202
|
-
"""
|
|
203
|
-
Returns the bounding box extrema of the mask.
|
|
204
186
|
|
|
205
|
-
|
|
206
|
-
-------
|
|
207
|
-
tuple[float, float, float, float]
|
|
208
|
-
A tuple in the form (xmin, xmax, ymin, ymax).
|
|
209
|
-
"""
|
|
210
|
-
rows, cols = np.nonzero(self.mask)
|
|
211
|
-
return (cols.min(), cols.max(), rows.min(), rows.max())
|
|
187
|
+
AnnotationType = TypeVar("AnnotationType", BoundingBox, Polygon, Bitmask)
|
|
212
188
|
|
|
213
189
|
|
|
214
190
|
@dataclass
|
|
215
|
-
class Detection:
|
|
191
|
+
class Detection(Generic[AnnotationType]):
|
|
216
192
|
"""
|
|
217
193
|
Detection data structure holding ground truths and predictions for object detection tasks.
|
|
218
194
|
|
|
@@ -220,9 +196,9 @@ class Detection:
|
|
|
220
196
|
----------
|
|
221
197
|
uid : str
|
|
222
198
|
Unique identifier for the image or sample.
|
|
223
|
-
groundtruths : list
|
|
199
|
+
groundtruths : list[BoundingBox] | list[Polygon] | list[Bitmask]
|
|
224
200
|
List of ground truth annotations.
|
|
225
|
-
predictions : list
|
|
201
|
+
predictions : list[BoundingBox] | list[Polygon] | list[Bitmask]
|
|
226
202
|
List of predicted annotations.
|
|
227
203
|
|
|
228
204
|
Examples
|
|
@@ -239,8 +215,8 @@ class Detection:
|
|
|
239
215
|
"""
|
|
240
216
|
|
|
241
217
|
uid: str
|
|
242
|
-
groundtruths: list[
|
|
243
|
-
predictions: list[
|
|
218
|
+
groundtruths: list[AnnotationType]
|
|
219
|
+
predictions: list[AnnotationType]
|
|
244
220
|
|
|
245
221
|
def __post_init__(self):
|
|
246
222
|
for prediction in self.predictions:
|