Skip to content

Commit

Permalink
Support for VGGFace2 dataset format (#2865)
Browse files Browse the repository at this point in the history
* Add support for VGGFace2  dataset format

* Add VGGFace2  to documentation

* fix format description

* Update Datumaro version

* fix linter

* fix test

* fix base.txt

Co-authored-by: Zhiltsov Max <zhiltsov.max35@gmail.com>
  • Loading branch information
yasakova-anastasia and zhiltsov-max committed Mar 9, 2021
1 parent 62cc956 commit 7a2dcff
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ For more information about supported formats look at the
| [LabelMe 3.0](http://labelme.csail.mit.edu/Release3.0) | X | X |
| [ImageNet](http://www.image-net.org) | X | X |
| [CamVid](http://mi.eng.cam.ac.uk/research/projects/VideoRec/CamVid/) | X | X |
| [VGGFace2](https://github.com/ox-vgg/vgg_face2) | X | X |

## Deep learning serverless functions for automatic labeling

Expand Down
32 changes: 32 additions & 0 deletions cvat/apps/dataset_manager/formats/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- [TF detection API](#tfrecord)
- [ImageNet](#imagenet)
- [CamVid](#camvid)
- [VGGFace2](#vggface2)

## How to add a new annotation format support<a id="how-to-add"></a>

Expand Down Expand Up @@ -874,3 +875,34 @@ has own color which corresponds to a label.
Uploaded file: a zip archive of the structure above

- supported annotations: Polygons

### [VGGFace2](https://github.com/ox-vgg/vgg_face2)<a id="vggface2" />

#### VGGFace2 Dumper

Downloaded file: a zip archive of the following structure:

```bash
taskname.zip/
├── labels.txt # optional
├── <any_subset_name>/
| ├── label0/
| | └── image1.jpg
| └── label1/
| └── image2.jpg
└── bb_landmark/
├── loose_bb_<any_subset_name>.csv
└── loose_landmark_<any_subset_name>.csv
# labels.txt
# n000001 car
label0 <class0>
label1 <class1>
```

- supported annotations: Rectangles, Points (landmarks - groups of 5 points)

#### VGGFace2 Loader

Uploaded file: a zip archive of the structure above

- supported annotations: Rectangles, Points (landmarks - groups of 5 points)
1 change: 1 addition & 0 deletions cvat/apps/dataset_manager/formats/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,3 +95,4 @@ def make_exporter(name):
import cvat.apps.dataset_manager.formats.yolo
import cvat.apps.dataset_manager.formats.imagenet
import cvat.apps.dataset_manager.formats.camvid
import cvat.apps.dataset_manager.formats.vggface2
32 changes: 32 additions & 0 deletions cvat/apps/dataset_manager/formats/vggface2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (C) 2021 Intel Corporation
#
# SPDX-License-Identifier: MIT

import zipfile
from tempfile import TemporaryDirectory

from datumaro.components.dataset import Dataset

from cvat.apps.dataset_manager.bindings import CvatTaskDataExtractor, \
import_dm_annotations
from cvat.apps.dataset_manager.util import make_zip_archive

from .registry import dm_env, exporter, importer


@exporter(name='VGGFace2', ext='ZIP', version='1.0')
def _export(dst_file, task_data, save_images=False):
dataset = Dataset.from_extractors(CvatTaskDataExtractor(
task_data, include_images=save_images), env=dm_env)
with TemporaryDirectory() as temp_dir:
dataset.export(temp_dir, 'vgg_face2', save_images=save_images)

make_zip_archive(temp_dir, dst_file)

@importer(name='VGGFace2', ext='ZIP', version='1.0')
def _import(src_file, task_data):
with TemporaryDirectory() as tmp_dir:
zipfile.ZipFile(src_file).extractall(tmp_dir)

dataset = Dataset.import_from(tmp_dir, 'vgg_face2', env=dm_env)
import_dm_annotations(dataset, task_data)
6 changes: 6 additions & 0 deletions cvat/apps/dataset_manager/tests/test_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def test_export_formats_query(self):
'YOLO 1.1',
'ImageNet 1.0',
'CamVid 1.0',
'VGGFace2 1.0',
})

def test_import_formats_query(self):
Expand All @@ -300,6 +301,7 @@ def test_import_formats_query(self):
'YOLO 1.1',
'ImageNet 1.0',
'CamVid 1.0',
'VGGFace2 1.0',
})

def test_exports(self):
Expand All @@ -312,6 +314,9 @@ def check(file_path):
self.skipTest("Format is disabled")

format_name = f.DISPLAY_NAME
if format_name == "VGGFace2 1.0":
self.skipTest("Format does not support multiple shapes for one item")

for save_images in { True, False }:
images = self._generate_task_images(3)
task = self._generate_task(images)
Expand All @@ -337,6 +342,7 @@ def test_empty_images_are_exported(self):
('YOLO 1.1', 'yolo'),
('ImageNet 1.0', 'imagenet_txt'),
('CamVid 1.0', 'camvid'),
('VGGFace2 1.0', 'vgg_face2'),
]:
with self.subTest(format=format_name):
if not dm.formats.registry.EXPORT_FORMATS[format_name].ENABLED:
Expand Down
20 changes: 17 additions & 3 deletions cvat/apps/engine/tests/test_rest_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
from glob import glob
from io import BytesIO
from unittest import mock
import open3d as o3d
import struct

import av
import numpy as np
Expand Down Expand Up @@ -739,7 +737,7 @@ def _run_api_v1_users(self, user):

return response

def _check_response(self, user, response, is_full):
def _check_response(self, user, response, is_full=True):
self.assertEqual(response.status_code, status.HTTP_200_OK)
for user_info in response.data['results']:
db_user = getattr(self, user_info['username'])
Expand Down Expand Up @@ -3770,6 +3768,17 @@ def _get_initial_annotation(annotation_format):
"occluded": False,
}]

points_wo_attrs = [{
"frame": 1,
"label_id": task["labels"][1]["id"],
"group": 0,
"source": "manual",
"attributes": [],
"points": [20.0, 0.1, 10, 3.22, 4, 7, 10, 30, 1, 2],
"type": "points",
"occluded": False,
}]

tags_wo_attrs = [{
"frame": 2,
"label_id": task["labels"][1]["id"],
Expand Down Expand Up @@ -3855,6 +3864,11 @@ def _get_initial_annotation(annotation_format):
annotations["shapes"] = rectangle_shapes_wo_attrs \
+ polygon_shapes_wo_attrs

elif annotation_format == "VGGFace2 1.0":
annotations["tags"] = tags_wo_attrs
annotations["shapes"] = points_wo_attrs \
+ rectangle_shapes_wo_attrs

else:
raise Exception("Unknown format {}".format(annotation_format))

Expand Down

0 comments on commit 7a2dcff

Please sign in to comment.