Skip to content

Commit 95e5267

Browse files
committed
Export category selection
1 parent d205435 commit 95e5267

File tree

7 files changed

+138
-49
lines changed

7 files changed

+138
-49
lines changed

backend/database/datasets.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,21 @@ def import_coco(self, coco_json):
6969
"name": task.name
7070
}
7171

72-
def export_coco(self, style="COCO"):
72+
def export_coco(self, categories=None, style="COCO"):
7373

7474
from workers.tasks import export_annotations
7575

76+
if categories is None or len(categories) == 0:
77+
categories = self.categories
78+
7679
task = TaskModel(
7780
name=f"Exporting {self.name} into {style} format",
7881
dataset_id=self.id,
7982
group="Annotation Export"
8083
)
8184
task.save()
8285

83-
cel_task = export_annotations.delay(task.id, self.id)
86+
cel_task = export_annotations.delay(task.id, self.id, categories)
8487

8588
return {
8689
"celery_id": cel_task.id,

backend/database/exports.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ExportModel(DynamicDocument):
1010
dataset_id = IntField(required=True)
1111
path = StringField(required=True)
1212
tags = ListField(default=[])
13+
categories = ListField(default=[])
1314
created_at = DateTimeField(default=datetime.datetime.utcnow)
1415

1516
def get_file(self):

backend/webserver/api/datasets.py

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
coco_upload = reqparse.RequestParser()
4343
coco_upload.add_argument('coco', location='files', type=FileStorage, required=True, help='Json coco')
4444

45+
export = reqparse.RequestParser()
46+
export.add_argument('categories', type=str, default=None, required=False, help='Ids of categories to export')
4547

4648
update_dataset = reqparse.RequestParser()
4749
update_dataset.add_argument('categories', location='json', type=list, help="New list of categories")
@@ -173,6 +175,7 @@ def get(self, dataset_id):
173175

174176
@api.route('/<int:dataset_id>')
175177
class DatasetId(Resource):
178+
176179
@login_required
177180
def delete(self, dataset_id):
178181
""" Deletes dataset by ID (only owners)"""
@@ -341,13 +344,16 @@ def get(self, dataset_id):
341344

342345
subdirectories = [f for f in sorted(os.listdir(directory))
343346
if os.path.isdir(directory + f) and not f.startswith('.')]
347+
348+
categories = CategoryModel.objects(id__in=dataset.categories).only('id', 'name')
344349

345350
return {
346351
"pagination": pagination.export(),
347352
"images": images_json,
348353
"folder": folder,
349354
"directory": directory,
350355
"dataset": query_util.fix_ids(dataset),
356+
"categories": query_util.fix_ids(categories),
351357
"subdirectories": subdirectories
352358
}
353359

@@ -384,6 +390,26 @@ def get(self, dataset_id):
384390
@api.route('/<int:dataset_id>/export')
385391
class DatasetExport(Resource):
386392

393+
@api.expect(export)
394+
@login_required
395+
def get(self, dataset_id):
396+
397+
args = export.parse_args()
398+
categories = args.get('categories')
399+
400+
if len(categories) == 0:
401+
categories = []
402+
403+
if len(categories) > 0 or isinstance(categories, str):
404+
categories = [int(c) for c in categories.split(',')]
405+
406+
dataset = DatasetModel.objects(id=dataset_id).first()
407+
408+
if not dataset:
409+
return {'message': 'Invalid dataset ID'}, 400
410+
411+
return dataset.export_coco(categories=categories)
412+
387413
@api.expect(coco_upload)
388414
@login_required
389415
def post(self, dataset_id):
@@ -412,7 +438,7 @@ def get(self, dataset_id):
412438
if not current_user.can_download(dataset):
413439
return {"message": "You do not have permission to download the dataset's annotations"}, 403
414440

415-
return coco_util.get_dataset_coco(dataset)
441+
return coco_util.get_dataseext_coco(dataset)
416442

417443
@api.expect(coco_upload)
418444
@login_required
@@ -459,16 +485,3 @@ def get(self, dataset_id):
459485

460486
return dataset.scan()
461487

462-
463-
@api.route('/<int:dataset_id>/export')
464-
class DatasetScan(Resource):
465-
466-
@login_required
467-
def get(self, dataset_id):
468-
469-
dataset = DatasetModel.objects(id=dataset_id).first()
470-
471-
if not dataset:
472-
return {'message': 'Invalid dataset ID'}, 400
473-
474-
return dataset.export_coco()

backend/workers/tasks/data.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121

2222
@shared_task
23-
def export_annotations(task_id, dataset_id):
23+
def export_annotations(task_id, dataset_id, categories):
2424

2525
task = TaskModel.objects.get(id=task_id)
2626
dataset = DatasetModel.objects.get(id=dataset_id)
@@ -30,11 +30,11 @@ def export_annotations(task_id, dataset_id):
3030

3131
task.info("Beginning Export (COCO Format)")
3232

33-
db_categories = CategoryModel.objects(id__in=dataset.categories, deleted=False) \
33+
db_categories = CategoryModel.objects(id__in=categories, deleted=False) \
3434
.only(*CategoryModel.COCO_PROPERTIES)
3535
db_images = ImageModel.objects(deleted=False, annotated=True, dataset_id=dataset.id)\
3636
.only(*ImageModel.COCO_PROPERTIES)
37-
db_annotations = AnnotationModel.objects(deleted=False)
37+
db_annotations = AnnotationModel.objects(deleted=False, category_id__in=categories)
3838

3939
total_items = db_categories.count()
4040

@@ -48,6 +48,7 @@ def export_annotations(task_id, dataset_id):
4848
progress = 0
4949

5050
# iterate though all categoires and upsert
51+
category_names = []
5152
for category in fix_ids(db_categories):
5253

5354
if len(category.get('keypoint_labels', [])) > 0:
@@ -61,6 +62,7 @@ def export_annotations(task_id, dataset_id):
6162

6263
task.info(f"Adding category: {category.get('name')}")
6364
coco.get('categories').append(category)
65+
category_names.append(category.get('name'))
6466

6567
progress += 1
6668
task.set_progress((progress/total_items)*100, socket=socket)
@@ -111,7 +113,7 @@ def export_annotations(task_id, dataset_id):
111113
json.dump(coco, fp)
112114

113115
task.info("Creating export object")
114-
export = ExportModel(dataset_id=dataset.id, path=file_path, tags=["COCO"])
116+
export = ExportModel(dataset_id=dataset.id, path=file_path, tags=["COCO", *category_names])
115117
export.save()
116118

117119
task.set_progress(100, socket=socket)

client/src/components/Pagination.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ export default {
9595

9696
<style>
9797
.page {
98-
display:block;
99-
margin:0 auto;
98+
display: block;
99+
margin: 0 auto;
100100
}
101101
</style>

client/src/models/datasets.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ export default {
3030
scan(id) {
3131
return axios.get(`${baseURL}/${id}/scan`);
3232
},
33-
exportingCOCO(id) {
34-
return axios.get(`${baseURL}/${id}/export`);
33+
exportingCOCO(id, categories) {
34+
return axios.get(`${baseURL}/${id}/export?categories=${categories}`);
3535
},
3636
getCoco(id) {
3737
return axios.get(`${baseURL}/${id}/coco`);

0 commit comments

Comments
 (0)