Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Datumaro] Allow empty COCO dataset export #1272

Merged
merged 3 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
-

### Fixed
- Annotation-less tasks now can be exported as empty datasets in COCO ([#1277](https://github.com/opencv/cvat/issues/1277))
- Frame name matching for video annotations import -
allowed `frame_XXXXXX[.ext]` format ([#1274](https://github.com/opencv/cvat/pull/1274))

Expand Down
36 changes: 22 additions & 14 deletions datumaro/datumaro/plugins/coco_format/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,20 +329,24 @@ def save_categories(self, dataset):
label_categories = dataset.categories().get(AnnotationType.label)
if label_categories is None:
return
points_categories = dataset.categories().get(AnnotationType.points)
if points_categories is None:
return

for idx, kp_cat in points_categories.items.items():
label_cat = label_categories.items[idx]
point_categories = dataset.categories().get(AnnotationType.points)

for idx, label_cat in enumerate(label_categories.items):
cat = {
'id': 1 + idx,
'name': _cast(label_cat.name, str, ''),
'supercategory': _cast(label_cat.parent, str, ''),
'keypoints': [str(l) for l in kp_cat.labels],
'skeleton': [int(i) for i in kp_cat.adjacent],
'keypoints': [],
'skeleton': [],
}

if point_categories is not None:
kp_cat = point_categories.items.get(idx)
if kp_cat is not None:
cat.update({
'keypoints': [str(l) for l in kp_cat.labels],
'skeleton': [int(i) for i in kp_cat.adjacent],
})
self.categories.append(cat)

def save_annotations(self, item):
Expand Down Expand Up @@ -447,14 +451,19 @@ class _Converter:
def __init__(self, extractor, save_dir,
tasks=None, save_images=False, segmentation_mode=None,
crop_covered=False):
assert tasks is None or isinstance(tasks, (CocoTask, list))
assert tasks is None or isinstance(tasks, (CocoTask, list, str))
if tasks is None:
tasks = list(self._TASK_CONVERTER)
elif isinstance(tasks, CocoTask):
tasks = [tasks]
elif isinstance(tasks, str):
tasks = [CocoTask[tasks]]
else:
for t in tasks:
assert t in CocoTask
for i, t in enumerate(tasks):
if isinstance(t, str):
tasks[i] = CocoTask[t]
else:
assert t in CocoTask, t
self._tasks = tasks

self._extractor = extractor
Expand Down Expand Up @@ -546,9 +555,8 @@ def convert(self):
task_conv.save_annotations(item)

for task, task_conv in task_converters.items():
if not task_conv.is_empty():
task_conv.write(osp.join(self._ann_dir,
'%s_%s.json' % (task.name, subset_name)))
task_conv.write(osp.join(self._ann_dir,
'%s_%s.json' % (task.name, subset_name)))

class CocoConverter(Converter, CliPlugin):
@staticmethod
Expand Down
5 changes: 4 additions & 1 deletion datumaro/tests/test_coco_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -632,10 +632,13 @@ def __iter__(self):

def categories(self):
label_cat = LabelCategories()
point_cat = PointsCategories()
for label in range(10):
label_cat.add('label_' + str(label))
point_cat.add(label)
return {
AnnotationType.label: label_cat,
AnnotationType.points: point_cat,
}

with TestDir() as test_dir:
Expand All @@ -651,4 +654,4 @@ def __iter__(self):

with TestDir() as test_dir:
self._test_save_and_load(TestExtractor(),
CocoConverter(), test_dir)
CocoConverter(tasks='image_info'), test_dir)