layout / utils /database /annotations.py
hassanshka's picture
Add missing important files: _app_.py, utils/, CVAT_download/, manifest.json, and documentation
989ec3c
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
import numpy as np
import cv2
class AnnotationModel(DynamicDocument):
COCO_PROPERTIES = ["id", "image_id", "category_id", "segmentation",
"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=[])
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"]