12
12
from labelbox .data import annotation_types
13
13
14
14
15
- def mask_miou (predictions : List [Mask ], ground_truths : List [Mask ], resize_height = None , resize_width = None ) -> float :
15
+ def mask_miou (predictions : List [Mask ],
16
+ ground_truths : List [Mask ],
17
+ resize_height = None ,
18
+ resize_width = None ) -> float :
16
19
"""
17
20
Creates prediction and label binary mask for all features with the same feature schema id.
18
21
Masks are flattened and treated as one class.
@@ -24,12 +27,22 @@ def mask_miou(predictions: List[Mask], ground_truths: List[Mask], resize_height
24
27
Returns:
25
28
float indicating iou score
26
29
"""
27
- prediction_np = np .max ([pred .raster (binary = True , height = resize_height , width = resize_width ) for pred in predictions ], axis = 0 )
28
- ground_truth_np = np .max ([ground_truth .raster (binary = True , height = resize_height , width = resize_width ) for ground_truth in ground_truths ], axis = 0 )
30
+ prediction_np = np .max ([
31
+ pred .raster (binary = True , height = resize_height , width = resize_width )
32
+ for pred in predictions
33
+ ],
34
+ axis = 0 )
35
+ ground_truth_np = np .max ([
36
+ ground_truth .raster (
37
+ binary = True , height = resize_height , width = resize_width )
38
+ for ground_truth in ground_truths
39
+ ],
40
+ axis = 0 )
29
41
if prediction_np .shape != ground_truth_np .shape :
30
- raise ValueError ("Prediction and mask must have the same shape."
31
- f" Found { prediction_np .shape } /{ ground_truth_np .shape } ."
32
- " Add resize params to fix this." )
42
+ raise ValueError (
43
+ "Prediction and mask must have the same shape."
44
+ f" Found { prediction_np .shape } /{ ground_truth_np .shape } ."
45
+ " Add resize params to fix this." )
33
46
return _mask_iou (ground_truth_np , prediction_np )
34
47
35
48
@@ -59,9 +72,12 @@ def classification_miou(predictions: List[ClassificationAnnotation],
59
72
if isinstance (prediction .value , Text ):
60
73
return float (prediction .value .answer == label .value .answer )
61
74
elif isinstance (prediction .value , Radio ):
62
- return float (prediction .value .answer .schema_id == label .value .answer .schema_id )
75
+ return float (
76
+ prediction .value .answer .schema_id == label .value .answer .schema_id )
63
77
elif isinstance (prediction .value , Checklist ):
64
- schema_ids_pred = {answer .schema_id for answer in prediction .value .answer }
78
+ schema_ids_pred = {
79
+ answer .schema_id for answer in prediction .value .answer
80
+ }
65
81
schema_ids_label = {answer .schema_id for answer in label .value .answer }
66
82
return float (
67
83
len (schema_ids_label & schema_ids_pred ) /
@@ -135,8 +151,10 @@ def vector_miou(predictions: List[Geometry], labels: List[Geometry],
135
151
return np .mean (solution_agreements )
136
152
137
153
138
- def feature_miou (predictions : List [Union [ObjectAnnotation , ClassificationAnnotation ]],
139
- labels : List [Union [ObjectAnnotation , ClassificationAnnotation ]],
154
+ def feature_miou (predictions : List [Union [ObjectAnnotation ,
155
+ ClassificationAnnotation ]],
156
+ labels : List [Union [ObjectAnnotation ,
157
+ ClassificationAnnotation ]],
140
158
include_subclasses = True ) -> Optional [float ]:
141
159
"""
142
160
Computes iou score for all features with the same feature schema id.
@@ -166,7 +184,8 @@ def feature_miou(predictions: List[Union[ObjectAnnotation, ClassificationAnnotat
166
184
elif isinstance (predictions [0 ].value , ClassificationAnnotation ):
167
185
return classification_miou (predictions , labels )
168
186
else :
169
- raise ValueError (f"Unexpected annotation found. Found { type (predictions [0 ])} " )
187
+ raise ValueError (
188
+ f"Unexpected annotation found. Found { type (predictions [0 ])} " )
170
189
171
190
172
191
def _create_schema_lookup (annotations : List [BaseAnnotation ]):
@@ -175,10 +194,11 @@ def _create_schema_lookup(annotations: List[BaseAnnotation]):
175
194
grouped_annotations [annotation .schema_id ] = annotation
176
195
return grouped_annotations
177
196
197
+
178
198
def data_row_miou (ground_truth : Label ,
179
- predictions : Label ,
180
- include_classifications = True ,
181
- include_subclasses = True ) -> float :
199
+ predictions : Label ,
200
+ include_classifications = True ,
201
+ include_subclasses = True ) -> float :
182
202
"""
183
203
# At this point all object should have schema ids.
184
204
@@ -191,9 +211,12 @@ def data_row_miou(ground_truth: Label,
191
211
float indicating the iou score for this data row.
192
212
"""
193
213
annotation_types = None if include_classifications else Geometry
194
- prediction_annotations = predictions .get_annotations_by_attr (attr = "name" , annotation_types = annotation_types )
195
- ground_truth_annotations = ground_truth .get_annotations_by_attr (attr = "name" , annotation_types = annotation_types )
196
- feature_schemas = set (prediction_annotations .keys ()).union (set (ground_truth_annotations .keys ()))
214
+ prediction_annotations = predictions .get_annotations_by_attr (
215
+ attr = "name" , annotation_types = annotation_types )
216
+ ground_truth_annotations = ground_truth .get_annotations_by_attr (
217
+ attr = "name" , annotation_types = annotation_types )
218
+ feature_schemas = set (prediction_annotations .keys ()).union (
219
+ set (ground_truth_annotations .keys ()))
197
220
ious = [
198
221
feature_miou (prediction_annotations [feature_schema ],
199
222
ground_truth_annotations [feature_schema ],
@@ -206,13 +229,13 @@ def data_row_miou(ground_truth: Label,
206
229
return np .mean (ious )
207
230
208
231
209
- def _get_vector_pairs (predictions : List [Geometry ], ground_truths : List [Geometry ]):
232
+ def _get_vector_pairs (predictions : List [Geometry ],
233
+ ground_truths : List [Geometry ]):
210
234
"""
211
235
# Get iou score for all pairs of labels and predictions
212
236
"""
213
237
return [(prediction , ground_truth ,
214
- _polygon_iou (prediction .shapely ,
215
- ground_truth .shapely ))
238
+ _polygon_iou (prediction .shapely , ground_truth .shapely ))
216
239
for prediction , ground_truth in product (predictions , ground_truths )]
217
240
218
241
@@ -238,4 +261,3 @@ def _instance_urls_to_binary_mask(urls: List[str],
238
261
masks = _remove_opacity_channel ([url_to_numpy (url ) for url in urls ])
239
262
return np .sum ([np .all (mask == color , axis = - 1 ) for mask in masks ],
240
263
axis = 0 ) > 0
241
-
0 commit comments