7
7
import numpy as np
8
8
from collections import defaultdict
9
9
10
- from ..annotation_types import Label , ObjectAnnotation , ClassificationAnnotation , Mask , Geometry
10
+ from ..annotation_types import Label , ObjectAnnotation , ClassificationAnnotation , Mask , Geometry , Point , Line
11
11
from ..annotation_types .annotation import BaseAnnotation
12
12
from labelbox .data import annotation_types
13
13
@@ -114,8 +114,10 @@ def subclassification_miou(
114
114
return None if not len (classification_iou ) else np .mean (classification_iou )
115
115
116
116
117
- def vector_miou (predictions : List [Geometry ], labels : List [Geometry ],
118
- include_subclasses ) -> float :
117
+ def vector_miou (predictions : List [ObjectAnnotation ],
118
+ labels : List [ObjectAnnotation ],
119
+ include_subclasses ,
120
+ buffer = 70. ) -> float :
119
121
"""
120
122
Computes an iou score for vector tools.
121
123
@@ -127,15 +129,16 @@ def vector_miou(predictions: List[Geometry], labels: List[Geometry],
127
129
miou score for the feature schema
128
130
129
131
"""
130
- pairs = _get_vector_pairs (predictions , labels )
132
+ pairs = _get_vector_pairs (predictions , labels , buffer = buffer )
131
133
pairs .sort (key = lambda triplet : triplet [2 ], reverse = True )
132
134
solution_agreements = []
133
135
solution_features = set ()
134
136
all_features = set ()
135
137
for pred , label , agreement in pairs :
136
- all_features .update ({pred .uuid , label .uuid })
137
- if pred .uuid not in solution_features and label .uuid not in solution_features :
138
- solution_features .update ({pred .uuid , label .uuid })
138
+ all_features .update ({id (pred ), id (label )})
139
+ if id (pred ) not in solution_features and id (
140
+ label ) not in solution_features :
141
+ solution_features .update ({id (pred ), id (label )})
139
142
if include_subclasses :
140
143
classification_iou = subclassification_miou (
141
144
pred .classifications , label .classifications )
@@ -181,14 +184,11 @@ def feature_miou(predictions: List[Union[ObjectAnnotation,
181
184
return vector_miou (predictions ,
182
185
labels ,
183
186
include_subclasses = include_subclasses )
184
- elif isinstance (predictions [0 ]. value , ClassificationAnnotation ):
187
+ elif isinstance (predictions [0 ], ClassificationAnnotation ):
185
188
return classification_miou (predictions , labels )
186
189
else :
187
190
raise ValueError (
188
- f"Unexpected annotation found. Found { type (predictions [0 ])} " )
189
-
190
-
191
-
191
+ f"Unexpected annotation found. Found { type (predictions [0 ].value )} " )
192
192
193
193
194
194
def data_row_miou (ground_truth : Label ,
@@ -206,7 +206,6 @@ def data_row_miou(ground_truth: Label,
206
206
Returns:
207
207
float indicating the iou score for this data row.
208
208
"""
209
-
210
209
prediction_annotations = _create_name_lookup (predictions .annotations )
211
210
ground_truth_annotations = _create_name_lookup (ground_truth .annotations )
212
211
feature_schemas = set (prediction_annotations .keys ()).union (
@@ -222,20 +221,33 @@ def data_row_miou(ground_truth: Label,
222
221
return None
223
222
return np .mean (ious )
224
223
224
+
225
225
def _create_name_lookup (annotations : List [BaseAnnotation ]):
226
226
grouped_annotations = defaultdict (list )
227
227
for annotation in annotations :
228
- grouped_annotations [annotation .name ] = annotation
228
+ grouped_annotations [annotation .name ]. append ( annotation )
229
229
return grouped_annotations
230
230
231
- def _get_vector_pairs (predictions : List [Geometry ],
232
- ground_truths : List [Geometry ]):
231
+
232
+ def _get_vector_pairs (
233
+ predictions : List [ObjectAnnotation ],
234
+ ground_truths : List [ObjectAnnotation ], buffer : float
235
+ ) -> List [Tuple [ObjectAnnotation , ObjectAnnotation , float ]]:
233
236
"""
234
237
# Get iou score for all pairs of labels and predictions
235
238
"""
236
- return [(prediction , ground_truth ,
237
- _polygon_iou (prediction .shapely , ground_truth .shapely ))
238
- for prediction , ground_truth in product (predictions , ground_truths )]
239
+ pairs = []
240
+ for prediction , ground_truth in product (predictions , ground_truths ):
241
+ if isinstance (prediction .value , Geometry ) and isinstance (
242
+ ground_truth .value , Geometry ):
243
+ if isinstance (prediction .value , (Line , Point )):
244
+ score = _polygon_iou (prediction .value .shapely .buffer (buffer ),
245
+ ground_truth .value .shapely .buffer (buffer ))
246
+ else :
247
+ score = _polygon_iou (prediction .value .shapely ,
248
+ ground_truth .value .shapely )
249
+ pairs .append ((prediction , ground_truth , score ))
250
+ return pairs
239
251
240
252
241
253
def _polygon_iou (poly1 : Polygon , poly2 : Polygon ) -> float :
0 commit comments