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

Add Cityscapes format #3758

Merged
merged 13 commits into from
Nov 9, 2021
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 @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add a tutorial on attaching cloud storage AWS-S3 (<https://github.com/openvinotoolkit/cvat/pull/3745>)
and Azure Blob Container (<https://github.com/openvinotoolkit/cvat/pull/3778>)
- The feature to remove annotations in a specified range of frames (<https://github.com/openvinotoolkit/cvat/pull/3617>)
- Add Cityscapes format (<https://github.com/openvinotoolkit/cvat/pull/3758>)
- Add Open Images V6 format (<https://github.com/openvinotoolkit/cvat/pull/3679>)

### Changed
Expand Down
47 changes: 47 additions & 0 deletions cvat/apps/dataset_manager/formats/cityscapes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright (C) 2021 Intel Corporation
#
# SPDX-License-Identifier: MIT

import os.path as osp
from tempfile import TemporaryDirectory

from datumaro.components.dataset import Dataset
from datumaro.plugins.cityscapes_format import write_label_map
from pyunpack import Archive

from cvat.apps.dataset_manager.bindings import (GetCVATDataExtractor,
import_dm_annotations)
from cvat.apps.dataset_manager.util import make_zip_archive

from .registry import dm_env, exporter, importer
from .utils import make_colormap


@exporter(name='Cityscapes', ext='ZIP', version='1.0')
def _export(dst_file, instance_data, save_images=False):
dataset = Dataset.from_extractors(GetCVATDataExtractor(
instance_data, include_images=save_images), env=dm_env)
dataset.transform('polygons_to_masks')
dataset.transform('boxes_to_masks')
dataset.transform('merge_instance_segments')
with TemporaryDirectory() as temp_dir:
dataset.export(temp_dir, 'cityscapes', save_images=save_images,
apply_colormap=True, label_map={label: info[0]
for label, info in make_colormap(instance_data).items()})

make_zip_archive(temp_dir, dst_file)

@importer(name='Cityscapes', ext='ZIP', version='1.0')
def _import(src_file, instance_data):
with TemporaryDirectory() as tmp_dir:
Archive(src_file.name).extractall(tmp_dir)

labelmap_file = osp.join(tmp_dir, 'label_colors.txt')
if not osp.isfile(labelmap_file):
colormap = {label: info[0]
for label, info in make_colormap(instance_data).items()}
write_label_map(labelmap_file, colormap)

dataset = Dataset.import_from(tmp_dir, 'cityscapes', env=dm_env)
dataset.transform('masks_to_polygons')
import_dm_annotations(dataset, instance_data)
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 @@ -121,5 +121,6 @@ def make_exporter(name):
import cvat.apps.dataset_manager.formats.icdar
import cvat.apps.dataset_manager.formats.velodynepoint
import cvat.apps.dataset_manager.formats.pointcloud
import cvat.apps.dataset_manager.formats.cityscapes
import cvat.apps.dataset_manager.formats.openimages

18 changes: 18 additions & 0 deletions cvat/apps/dataset_manager/tests/assets/annotations.json
Original file line number Diff line number Diff line change
Expand Up @@ -1197,5 +1197,23 @@
}
],
"tracks": []
},
"Cityscapes 1.0": {
"version": 0,
"tags": [],
"shapes": [
{
"type": "polygon",
"occluded": false,
"z_order": 0,
"points": [11.9, 21.5, 35.2, 21.9, 33.6, 31.9, 12.4, 30.47],
"frame": 0,
"label_id": null,
"group": 0,
"source": "manual",
"attributes": []
}
],
"tracks": []
}
}
58 changes: 55 additions & 3 deletions cvat/apps/dataset_manager/tests/assets/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
}
]
},
"icdar_localization_and_recognition": {
"ICDAR Localization 1.0": {
"name": "icdar localization/recogntion task",
"overlap": 0,
"segment_size": 100,
Expand All @@ -74,7 +74,27 @@
}
]
},
"icdar_segmentation": {
"ICDAR Recognition 1.0": {
"name": "icdar localization/recogntion task",
"overlap": 0,
"segment_size": 100,
"owner_id": 1,
"assignee_id": 2,
"labels": [
{
"name": "icdar",
"attributes": [
{
"name": "text",
"mutable": false,
"input_type": "text",
"values": ["word_1", "word_2", "word_3"]
}
]
}
]
},
"ICDAR Segmentation 1.0": {
"name": "icdar segmentation task",
"overlap": 0,
"segment_size": 100,
Expand Down Expand Up @@ -112,7 +132,7 @@
}
]
},
"market1501": {
"Market-1501 1.0": {
"name": "market1501 task",
"overlap": 0,
"segment_size": 100,
Expand Down Expand Up @@ -144,6 +164,38 @@
}
]
},
"Cityscapes 1.0": {
"name": "cityscapes task",
"overlap": 0,
"segment_size": 100,
"owner_id": 1,
"assignee_id": 2,
"labels": [
{
"name": "car",
"color": "#2080c0",
"attributes": [
{
"name": "is_crowd",
"mutable": false,
"input_type": "checkbox",
"default_value": "false",
"values": ["false", "true"]
}
]
},
{
"name": "person",
"color": "#c06060",
"attributes": []
},
{
"name": "background",
"color": "#000000",
"attributes": []
}
]
},
"wrong_checkbox_value": {
"name": "wrong checkbox value task",
"overlap": 0,
Expand Down
27 changes: 12 additions & 15 deletions cvat/apps/dataset_manager/tests/test_formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from cvat.apps.engine.models import Task


def generate_image_file(filename, size=(100, 50)):
def generate_image_file(filename, size=(100, 100)):
f = BytesIO()
image = Image.new('RGB', size=size)
image.save(f, 'jpeg')
Expand Down Expand Up @@ -296,6 +296,7 @@ def test_export_formats_query(self):
'ICDAR Segmentation 1.0',
'Kitti Raw Format 1.0',
'Sly Point Cloud Format 1.0',
'Cityscapes 1.0',
'Open Images V6 1.0'
})

Expand Down Expand Up @@ -323,6 +324,7 @@ def test_import_formats_query(self):
'ICDAR Segmentation 1.0',
'Kitti Raw Format 1.0',
'Sly Point Cloud Format 1.0',
'Cityscapes 1.0',
'Open Images V6 1.0',
'Datumaro 1.0',
'Datumaro 3D 1.0'
Expand Down Expand Up @@ -372,6 +374,7 @@ def test_empty_images_are_exported(self):
('ICDAR Recognition 1.0', 'icdar_word_recognition'),
('ICDAR Localization 1.0', 'icdar_text_localization'),
('ICDAR Segmentation 1.0', 'icdar_text_segmentation'),
# ('Cityscapes 1.0', 'cityscapes'), does not support, empty annotations
]:
with self.subTest(format=format_name):
if not dm.formats.registry.EXPORT_FORMATS[format_name].ENABLED:
Expand All @@ -382,16 +385,6 @@ def test_empty_images_are_exported(self):

def check(file_path):
def load_dataset(src):
if importer_name == 'datumaro_project':
project = datumaro.components.project. \
Project.load(src)

# NOTE: can't import cvat.utils.cli
# for whatever reason, so remove the dependency
#
project.config.remove('sources')

return project.make_dataset()
return datumaro.components.dataset. \
Dataset.import_from(src, importer_name, env=dm_env)

Expand Down Expand Up @@ -702,6 +695,10 @@ def _generate_task(self, images, annotation_format, **overrides):
}
]
},
{
"name": "background",
"attributes": [],
},
{"name": "person"}
]

Expand Down Expand Up @@ -838,7 +835,7 @@ def _generate_annotations(self, task, annotation_format):
{
"frame": 0,
"attributes": [],
"points": [1.0, 2.1, 10.6, 53.22, 100, 300.222],
"points": [1.0, 2.1, 10.6, 53.22, 90, 90.222],
"type": "polygon",
"occluded": False,
"outside": False
Expand Down Expand Up @@ -879,10 +876,10 @@ def _generate_annotations(self, task, annotation_format):
elif annotation_format == "MOTS PNG 1.0":
tracks = [track_wo_attrs]
else:
shapes = [rectangle_shape_wo_attrs,
shapes = [rectangle_shape_wo_attrs, \
rectangle_shape_with_attrs]
tags = tag_wo_attrs
tracks = track_wo_attrs
tags = [tag_wo_attrs]
tracks = [track_wo_attrs]

annotations = {
"version": 0,
Expand Down
Loading