-
Notifications
You must be signed in to change notification settings - Fork 472
/
Copy pathannotations.py
executable file
·119 lines (87 loc) · 3.35 KB
/
annotations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import imantics as im
import json
from mongoengine import *
from .datasets import DatasetModel
from .categories import CategoryModel
from .events import Event
from flask_login import current_user
class AnnotationModel(DynamicDocument):
COCO_PROPERTIES = ["id", "image_id", "category_id", "segmentation", "rle",
"iscrowd", "color", "area", "bbox", "metadata",
"keypoints", "isbbox"]
id = SequenceField(primary_key=True)
image_id = IntField(required=True)
category_id = IntField(required=True)
dataset_id = IntField()
segmentation = ListField(default=[]) #segmentation in polygon format
rle = DictField(default={}) #segmentation in RLE format (Compressed RLE)
area = IntField(default=0)
bbox = ListField(default=[0, 0, 0, 0])
iscrowd = BooleanField(default=False)
isbbox = BooleanField(default=False)
creator = StringField(required=True)
width = IntField()
height = IntField()
color = StringField()
keypoints = ListField(default=[])
metadata = DictField(default={})
paper_object = ListField(default=[])
deleted = BooleanField(default=False)
deleted_date = DateTimeField()
milliseconds = IntField(default=0)
events = EmbeddedDocumentListField(Event)
def __init__(self, image_id=None, **data):
from .images import ImageModel
if image_id is not None:
image = ImageModel.objects(id=image_id).first()
if image is not None:
data['image_id'] = image_id
data['width'] = image.width
data['height'] = image.height
data['dataset_id'] = image.dataset_id
super(AnnotationModel, self).__init__(**data)
def save(self, copy=False, *args, **kwargs):
if self.dataset_id and not copy:
dataset = DatasetModel.objects(id=self.dataset_id).first()
if dataset is not None:
self.metadata = dataset.default_annotation_metadata.copy()
if self.color is None:
self.color = im.Color.random().hex
if current_user:
self.creator = current_user.username
else:
self.creator = 'system'
return super(AnnotationModel, self).save(*args, **kwargs)
def is_empty(self):
return len(self.segmentation) == 0 or self.area == 0
def mask(self):
""" Returns binary mask of annotation """
mask = np.zeros((self.height, self.width))
pts = [
np.array(anno).reshape(-1, 2).round().astype(int)
for anno in self.segmentation
]
mask = cv2.fillPoly(mask, pts, 1)
return mask
def clone(self):
""" Creates a clone """
create = json.loads(self.to_json())
del create['_id']
return AnnotationModel(**create)
def __call__(self):
category = CategoryModel.objects(id=self.category_id).first()
if category:
category = category()
data = {
'image': None,
'category': category,
'color': self.color,
'polygons': self.segmentation,
'width': self.width,
'height': self.height,
'metadata': self.metadata
}
return im.Annotation(**data)
def add_event(self, e):
self.update(push__events=e)
__all__ = ["AnnotationModel"]