Skip to content

Commit a777ceb

Browse files
committed
Exports only COCO properties
1 parent 968bdf7 commit a777ceb

File tree

7 files changed

+66
-62
lines changed

7 files changed

+66
-62
lines changed

backend/database/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ def upsert(model, query=None, update=None):
4040
return new_model
4141

4242

43-
def fix_ids(objs):
44-
objects_list = json.loads(objs.to_json().replace('\"_id\"', '\"id\"'))
45-
return objects_list
43+
def fix_ids(q):
44+
json_obj = json.loads(q.to_json().replace('\"_id\"', '\"id\"'))
45+
return json_obj
4646

4747

4848
def create_from_json(json_file):

backend/database/annotations.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
class AnnotationModel(DynamicDocument):
1212

13+
COCO_PROPERTIES = ["id", "image_id", "category_id", "segmentation", \
14+
"iscrowd", "color", "area", "bbox", "metadata", \
15+
"keypoints"]
16+
1317
id = SequenceField(primary_key=True)
1418
image_id = IntField(required=True)
1519
category_id = IntField(required=True)
@@ -41,13 +45,15 @@ class AnnotationModel(DynamicDocument):
4145
def __init__(self, image_id=None, **data):
4246

4347
from .images import ImageModel
44-
image = ImageModel.objects(id=image_id).first()
4548

46-
if image is not None:
47-
data['image_id'] = image_id
48-
data['width'] = image.width
49-
data['height'] = image.height
50-
data['dataset_id'] = image.dataset_id
49+
if image_id is not None:
50+
image = ImageModel.objects(id=image_id).first()
51+
52+
if image is not None:
53+
data['image_id'] = image_id
54+
data['width'] = image.width
55+
data['height'] = image.height
56+
data['dataset_id'] = image.dataset_id
5157

5258
super(AnnotationModel, self).__init__(**data)
5359

backend/database/categories.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77

88
class CategoryModel(DynamicDocument):
99

10+
COCO_PROPERTIES = ["id", "name", "supercategory", "color", "metadata",\
11+
"keypoint_edges", "keypoint_labels"]
12+
1013
id = SequenceField(primary_key=True)
1114
name = StringField(required=True, unique_with=['creator'])
1215
supercategory = StringField(default='')

backend/database/images.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
from .annotations import AnnotationModel
1111

1212
class ImageModel(DynamicDocument):
13-
13+
14+
COCO_PROPERTIES = ["id", "width", "height", "file_name", "path", "license",\
15+
"flickr_url", "coco_url", "date_captured", "dataset_id"]
16+
1417
# -- Contants
1518
THUMBNAIL_DIRECTORY = '.thumbnail'
1619
PATTERN = (".gif", ".png", ".jpg", ".jpeg", ".bmp")
@@ -37,6 +40,7 @@ class ImageModel(DynamicDocument):
3740
thumbnail_url = StringField()
3841
image_url = StringField()
3942
coco_url = StringField()
43+
date_captured = DateTimeField()
4044

4145
metadata = DictField()
4246
license = IntField()

backend/webserver/api/images.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,5 @@ def get(self, image_id):
204204
if not current_user.can_download(image):
205205
return {"message": "You do not have permission to download the images's annotations"}, 403
206206

207-
return coco_util.get_image_coco(image)
207+
return coco_util.get_image_coco(image_id)
208208

backend/webserver/util/coco_util.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pycocotools.mask as mask
22

3-
from .query_util import fix_ids
43
from database import (
4+
fix_ids,
55
ImageModel,
66
DatasetModel,
77
CategoryModel,
@@ -102,52 +102,52 @@ def get_annotations_iou(annotation_a, annotation_b):
102102
return ious[0][0]
103103

104104

105-
def get_image_coco(image):
105+
def get_image_coco(image_id):
106106
"""
107107
Generates coco for an image
108108
109109
:param image: ImageModel
110110
:return: Coco in dictionary format
111111
"""
112-
dataset = DatasetModel.objects(id=image.dataset_id).first()
113-
image = fix_ids(image)
112+
image = ImageModel.objects(id=image_id)\
113+
.only(*ImageModel.COCO_PROPERTIES)
114+
115+
image = fix_ids(image)[0]
116+
dataset = DatasetModel.objects(id=image.get('dataset_id')).first()
114117

115-
bulk_categories = CategoryModel.objects(deleted=False) \
116-
.exclude('deleted_date').in_bulk(dataset.categories).items()
118+
bulk_categories = CategoryModel.objects(id__in=dataset.categories, deleted=False) \
119+
.only(*CategoryModel.COCO_PROPERTIES)
117120

121+
print(bulk_categories)
122+
123+
db_annotations = AnnotationModel.objects(deleted=False, image_id=image_id)
118124
categories = []
119125
annotations = []
120126

121-
for category in bulk_categories:
122-
category = category[1]
123-
category_annotations = AnnotationModel.objects(
124-
deleted=False, category_id=category.id, image_id=image.get('id')
125-
).exclude('paper_object', 'deleted_date').all()
127+
for category in fix_ids(bulk_categories):
128+
129+
category_annotations = db_annotations\
130+
.filter(category_id=category.get('id'))\
131+
.only(*AnnotationModel.COCO_PROPERTIES)
126132

127-
if len(category_annotations) == 0:
133+
if category_annotations.count() == 0:
128134
continue
129135

136+
category_annotations = fix_ids(category_annotations)
130137
for annotation in category_annotations:
131-
annotation = fix_ids(annotation)
132138

133139
has_segmentation = len(annotation.get('segmentation', [])) > 0
134140
has_keypoints = len(annotation.get('keypoints', [])) > 0
135141

136142
if has_segmentation or has_keypoints:
137-
del annotation['deleted']
138143

139-
if not has_keypoints:
140-
del annotation['keypoints']
141-
else:
144+
if has_keypoints:
142145
arr = np.array(annotation.get('keypoints', []))
143146
arr = arr[2::3]
144147
annotation['num_keypoints'] = len(arr[arr > 0])
145-
148+
146149
annotations.append(annotation)
147150

148-
category = fix_ids(category)
149-
del category['deleted']
150-
151151
if len(category.get('keypoint_labels')) > 0:
152152
category['keypoints'] = category.pop('keypoint_labels')
153153
category['skeleton'] = category.pop('keypoint_edges')
@@ -157,8 +157,6 @@ def get_image_coco(image):
157157

158158
categories.append(category)
159159

160-
del image['deleted']
161-
162160
coco = {
163161
"images": [image],
164162
"categories": categories,

backend/workers/tasks/data.py

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,34 @@ def export_annotations(task_id, dataset_id):
2727

2828
task.info("Beginning Export (COCO Format)")
2929

30-
categories = CategoryModel.objects(deleted=False) \
31-
.exclude('deleted_date').in_bulk(dataset.categories).items()
30+
db_categories = CategoryModel.objects(id__in=dataset.categories, deleted=False) \
31+
.only(*CategoryModel.COCO_PROPERTIES)
32+
db_images = ImageModel.objects(deleted=False, annotated=True, dataset_id=dataset.id)\
33+
.only(*ImageModel.COCO_PROPERTIES)
34+
db_annotations = AnnotationModel.objects(deleted=False)
3235

33-
total_items = len(dataset.categories)
36+
total_items = db_categories.count()
3437
dataset = fix_ids(dataset)
3538

36-
images = ImageModel.objects(deleted=False, annotated=True, dataset_id=dataset.get('id')).exclude('deleted_date')
37-
all_annotations = AnnotationModel.objects(deleted=False).exclude('deleted_date', 'paper_object')
38-
3939
coco = {
4040
'images': [],
4141
'categories': [],
4242
'annotations': []
4343
}
4444

45-
total_items += images.count()
45+
total_items += db_images.count()
4646
progress = 0
47-
for category in categories:
48-
category = fix_ids(category[1])
4947

50-
del category['deleted']
48+
# iterate though all categoires and upsert
49+
for category in fix_ids(db_categories):
50+
5151
if len(category.get('keypoint_labels', [])) > 0:
5252
category['keypoints'] = category.pop('keypoint_labels', [])
5353
category['skeleton'] = category.pop('keypoint_edges', [])
5454
else:
5555
if 'keypoint_edges' in category:
5656
del category['keypoint_edges']
57-
if 'keypoint_labels' in categories:
57+
if 'keypoint_labels' in category:
5858
del category['keypoint_labels']
5959

6060
task.info(f"Adding category: {category.get('name')}")
@@ -63,22 +63,23 @@ def export_annotations(task_id, dataset_id):
6363
progress += 1
6464
task.set_progress((progress/total_items)*100, socket=socket)
6565

66-
total_annotations = 0
67-
total_images = 0
68-
for image in images:
69-
annotations = all_annotations.filter(image_id=image.id)
70-
if annotations.count() == 0:
71-
continue
66+
total_annotations = db_annotations.count()
67+
total_images = db_images.count()
68+
for image in fix_ids(db_images):
69+
70+
progress += 1
71+
task.set_progress((progress/total_items)*100, socket=socket)
7272

73-
annotations = fix_ids(annotations.all())
73+
annotations = db_annotations.filter(image_id=image.get('id'))\
74+
.only(*AnnotationModel.COCO_PROPERTIES)
75+
annotations = fix_ids(annotations)
7476
num_annotations = 0
7577
for annotation in annotations:
7678

7779
has_keypoints = len(annotation.get('keypoints', [])) > 0
7880
has_segmentation = len(annotation.get('segmentation', [])) > 0
7981

8082
if has_keypoints or has_segmentation:
81-
del annotation['deleted']
8283

8384
if not has_keypoints:
8485
if 'keypoints' in annotation:
@@ -91,16 +92,8 @@ def export_annotations(task_id, dataset_id):
9192
num_annotations += 1
9293
coco.get('annotations').append(annotation)
9394

94-
task.info(f'Exporting {num_annotations} annotations for image {image.id}')
95-
total_annotations += num_annotations
96-
97-
image = fix_ids(image)
98-
del image['deleted']
95+
task.info(f"Exporting {num_annotations} annotations for image {image.get('id')}")
9996
coco.get('images').append(image)
100-
total_images += 1
101-
102-
progress += 1
103-
task.set_progress((progress/total_items)*100, socket=socket)
10497

10598
file_path = dataset.get('directory') + '/coco.json'
10699
with open(file_path, 'w') as fp:

0 commit comments

Comments
 (0)