Skip to content

Commit 0b1e5c3

Browse files
author
Matt Sokoloff
committed
passing tests
1 parent 7b5b447 commit 0b1e5c3

File tree

7 files changed

+167
-137
lines changed

7 files changed

+167
-137
lines changed

labelbox/data/annotation_types/feature.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class FeatureSchema(BaseModel):
1919

2020
@root_validator
2121
def must_set_one(cls, values):
22+
2223
if values['schema_id'] is None and values['name'] is None:
2324
raise ValueError(
2425
"Must set either schema_id or name for all feature schemas")

labelbox/data/metrics/iou.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import numpy as np
88
from collections import defaultdict
99

10-
from ..annotation_types import Label, ObjectAnnotation, ClassificationAnnotation, Mask, Geometry
10+
from ..annotation_types import Label, ObjectAnnotation, ClassificationAnnotation, Mask, Geometry, Point, Line
1111
from ..annotation_types.annotation import BaseAnnotation
1212
from labelbox.data import annotation_types
1313

@@ -114,8 +114,10 @@ def subclassification_miou(
114114
return None if not len(classification_iou) else np.mean(classification_iou)
115115

116116

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:
119121
"""
120122
Computes an iou score for vector tools.
121123
@@ -127,15 +129,16 @@ def vector_miou(predictions: List[Geometry], labels: List[Geometry],
127129
miou score for the feature schema
128130
129131
"""
130-
pairs = _get_vector_pairs(predictions, labels)
132+
pairs = _get_vector_pairs(predictions, labels, buffer=buffer)
131133
pairs.sort(key=lambda triplet: triplet[2], reverse=True)
132134
solution_agreements = []
133135
solution_features = set()
134136
all_features = set()
135137
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)})
139142
if include_subclasses:
140143
classification_iou = subclassification_miou(
141144
pred.classifications, label.classifications)
@@ -181,14 +184,11 @@ def feature_miou(predictions: List[Union[ObjectAnnotation,
181184
return vector_miou(predictions,
182185
labels,
183186
include_subclasses=include_subclasses)
184-
elif isinstance(predictions[0].value, ClassificationAnnotation):
187+
elif isinstance(predictions[0], ClassificationAnnotation):
185188
return classification_miou(predictions, labels)
186189
else:
187190
raise ValueError(
188-
f"Unexpected annotation found. Found {type(predictions[0])}")
189-
190-
191-
191+
f"Unexpected annotation found. Found {type(predictions[0].value)}")
192192

193193

194194
def data_row_miou(ground_truth: Label,
@@ -206,7 +206,6 @@ def data_row_miou(ground_truth: Label,
206206
Returns:
207207
float indicating the iou score for this data row.
208208
"""
209-
210209
prediction_annotations = _create_name_lookup(predictions.annotations)
211210
ground_truth_annotations = _create_name_lookup(ground_truth.annotations)
212211
feature_schemas = set(prediction_annotations.keys()).union(
@@ -222,20 +221,33 @@ def data_row_miou(ground_truth: Label,
222221
return None
223222
return np.mean(ious)
224223

224+
225225
def _create_name_lookup(annotations: List[BaseAnnotation]):
226226
grouped_annotations = defaultdict(list)
227227
for annotation in annotations:
228-
grouped_annotations[annotation.name] = annotation
228+
grouped_annotations[annotation.name].append(annotation)
229229
return grouped_annotations
230230

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]]:
233236
"""
234237
# Get iou score for all pairs of labels and predictions
235238
"""
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
239251

240252

241253
def _polygon_iou(poly1: Polygon, poly2: Polygon) -> float:

labelbox/data/serialization/labelbox_v1/classification.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ def to_common(self) -> List[ClassificationAnnotation]:
8282
ClassificationAnnotation(value=classification.to_common(),
8383
classifications=[],
8484
name=classification.title,
85+
schema_id=classification.schema_id,
8586
extra={
8687
'value': classification.value,
8788
'feature_id': classification.feature_id

labelbox/data/serialization/labelbox_v1/label.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ def to_common(self):
4242
classifications = [
4343
VideoClassificationAnnotation(value=classification.to_common(),
4444
frame=self.frame_number,
45-
name=classification.title)
45+
name=classification.title,
46+
schema_id=classification.schema_id)
4647
for classification in self.classifications
4748
]
4849

labelbox/data/serialization/ndjson/classification.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Any, Dict, List, Union, Optional
22

3-
from pydantic import BaseModel, validator
3+
from pydantic import BaseModel, Field, validator
44

55
from labelbox.utils import camel_case
66
from ...annotation_types.annotation import ClassificationAnnotation, VideoClassificationAnnotation
@@ -55,7 +55,7 @@ def from_common(cls, text: Text, schema_id: Cuid) -> "NDTextSubclass":
5555

5656

5757
class NDChecklistSubclass(NDFeature):
58-
answer: List[NDFeature]
58+
answer: List[NDFeature] = Field(..., alias='answers')
5959

6060
def to_common(self) -> Checklist:
6161
return Checklist(answer=[

0 commit comments

Comments
 (0)