From 4bdaf3c083e2f32fe0a3ffb771851e2dde525ca4 Mon Sep 17 00:00:00 2001 From: Kirill Sizov Date: Tue, 9 Nov 2021 14:48:53 +0300 Subject: [PATCH] Add Cityscapes format (#3758) --- CHANGELOG.md | 1 + .../dataset_manager/formats/cityscapes.py | 47 ++++++ cvat/apps/dataset_manager/formats/registry.py | 1 + .../tests/assets/annotations.json | 18 +++ .../dataset_manager/tests/assets/tasks.json | 58 ++++++- .../dataset_manager/tests/test_formats.py | 27 ++-- .../tests/test_rest_api_formats.py | 105 ++++++------- cvat/apps/engine/tests/test_rest_api.py | 4 +- .../advanced/formats/format-cityscapes.md | 142 ++++++++++++++++++ 9 files changed, 333 insertions(+), 70 deletions(-) create mode 100644 cvat/apps/dataset_manager/formats/cityscapes.py create mode 100644 site/content/en/docs/manual/advanced/formats/format-cityscapes.md diff --git a/CHANGELOG.md b/CHANGELOG.md index f887011b2..c188474d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 () and Azure Blob Container () - The feature to remove annotations in a specified range of frames () +- Add Cityscapes format () - Add Open Images V6 format () ### Changed diff --git a/cvat/apps/dataset_manager/formats/cityscapes.py b/cvat/apps/dataset_manager/formats/cityscapes.py new file mode 100644 index 000000000..607f84971 --- /dev/null +++ b/cvat/apps/dataset_manager/formats/cityscapes.py @@ -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) diff --git a/cvat/apps/dataset_manager/formats/registry.py b/cvat/apps/dataset_manager/formats/registry.py index b8f57b51e..660c3aa13 100644 --- a/cvat/apps/dataset_manager/formats/registry.py +++ b/cvat/apps/dataset_manager/formats/registry.py @@ -121,5 +121,6 @@ import cvat.apps.dataset_manager.formats.market1501 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 diff --git a/cvat/apps/dataset_manager/tests/assets/annotations.json b/cvat/apps/dataset_manager/tests/assets/annotations.json index 7940299ca..d9943d86f 100644 --- a/cvat/apps/dataset_manager/tests/assets/annotations.json +++ b/cvat/apps/dataset_manager/tests/assets/annotations.json @@ -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": [] } } diff --git a/cvat/apps/dataset_manager/tests/assets/tasks.json b/cvat/apps/dataset_manager/tests/assets/tasks.json index 23ea55e2a..f2a168599 100644 --- a/cvat/apps/dataset_manager/tests/assets/tasks.json +++ b/cvat/apps/dataset_manager/tests/assets/tasks.json @@ -54,7 +54,7 @@ } ] }, - "icdar_localization_and_recognition": { + "ICDAR Localization 1.0": { "name": "icdar localization/recogntion task", "overlap": 0, "segment_size": 100, @@ -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, @@ -112,7 +132,7 @@ } ] }, - "market1501": { + "Market-1501 1.0": { "name": "market1501 task", "overlap": 0, "segment_size": 100, @@ -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, diff --git a/cvat/apps/dataset_manager/tests/test_formats.py b/cvat/apps/dataset_manager/tests/test_formats.py index b2b65ba4a..a02b19944 100644 --- a/cvat/apps/dataset_manager/tests/test_formats.py +++ b/cvat/apps/dataset_manager/tests/test_formats.py @@ -27,7 +27,7 @@ from cvat.apps.dataset_manager.util import make_zip_archive 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') @@ -296,6 +296,7 @@ class TaskExportTest(_DbTestBase): 'ICDAR Segmentation 1.0', 'Kitti Raw Format 1.0', 'Sly Point Cloud Format 1.0', + 'Cityscapes 1.0', 'Open Images V6 1.0' }) @@ -323,6 +324,7 @@ class TaskExportTest(_DbTestBase): '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' @@ -372,6 +374,7 @@ class TaskExportTest(_DbTestBase): ('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: @@ -382,16 +385,6 @@ class TaskExportTest(_DbTestBase): 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) @@ -702,6 +695,10 @@ class TaskAnnotationsImportTest(_DbTestBase): } ] }, + { + "name": "background", + "attributes": [], + }, {"name": "person"} ] @@ -838,7 +835,7 @@ class TaskAnnotationsImportTest(_DbTestBase): { "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 @@ -879,10 +876,10 @@ class TaskAnnotationsImportTest(_DbTestBase): 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, diff --git a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py index 200161196..1b2aadcfe 100644 --- a/cvat/apps/dataset_manager/tests/test_rest_api_formats.py +++ b/cvat/apps/dataset_manager/tests/test_rest_api_formats.py @@ -355,12 +355,12 @@ class TaskDumpUploadTest(_DbTestBase): with self.subTest(format=dump_format_name): images = self._generate_task_images(3) # create task with annotations - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) + if dump_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[dump_format_name], images) else: task = self._create_task(tasks["main"], images) task_id = task["id"] @@ -368,7 +368,8 @@ class TaskDumpUploadTest(_DbTestBase): "MOT 1.1", "MOTS PNG 1.0", \ "PASCAL VOC 1.1", "Segmentation mask 1.1", \ "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", "Datumaro 1.0"\ + "WiderFace 1.0", "VGGFace2 1.0", "Cityscapes 1.0", \ + "Datumaro 1.0"\ ]: self._create_annotations(task, dump_format_name, "default") else: @@ -417,12 +418,12 @@ class TaskDumpUploadTest(_DbTestBase): for user, edata in list(expected.items()): # remove all annotations from task (create new task without annotation) images = self._generate_task_images(3) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) + if upload_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[upload_format_name], images) else: task = self._create_task(tasks["main"], images) task_id = task["id"] @@ -460,12 +461,12 @@ class TaskDumpUploadTest(_DbTestBase): with self.subTest(format=dump_format_name): # create task with annotations video = self._generate_task_videos(1) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], video) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], video) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], video) + if dump_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[dump_format_name], video) else: task = self._create_task(tasks["main"], video) task_id = task["id"] @@ -474,7 +475,7 @@ class TaskDumpUploadTest(_DbTestBase): "MOT 1.1", "MOTS PNG 1.0", \ "PASCAL VOC 1.1", "Segmentation mask 1.1", \ "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", \ + "WiderFace 1.0", "VGGFace2 1.0", "Cityscapes 1.0" \ ]: self._create_annotations(task, dump_format_name, "default") else: @@ -521,12 +522,12 @@ class TaskDumpUploadTest(_DbTestBase): for user, edata in list(expected.items()): # remove all annotations from task (create new task without annotation) video = self._generate_task_videos(1) - if upload_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], video) - elif upload_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], video) - elif upload_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], video) + if upload_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[upload_format_name], video) else: task = self._create_task(tasks["main"], video) task_id = task["id"] @@ -802,12 +803,12 @@ class TaskDumpUploadTest(_DbTestBase): with self.subTest(format=dump_format_name): images = self._generate_task_images(3) # create task with annotations - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) + if dump_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[dump_format_name], images) else: task = self._create_task(tasks["main"], images) task_id = task["id"] @@ -871,6 +872,7 @@ class TaskDumpUploadTest(_DbTestBase): with self.subTest(format=upload_format_name): if upload_format_name in [ "MOTS PNG 1.0", # issue #2925 and changed points values + "Cityscapes 1.0" # formats doesn't support empty annotations ]: self.skipTest("Format is fail") images = self._generate_task_images(3) @@ -899,25 +901,26 @@ class TaskDumpUploadTest(_DbTestBase): "MOTS PNG 1.0", # issue #2925 and changed points values 'Kitti Raw Format 1.0', 'Sly Point Cloud Format 1.0', - 'Datumaro 3D 1.0' + 'Datumaro 3D 1.0', + "Cityscapes 1.0" # expanding annotations due to background mask ]: self.skipTest("Format is fail") images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) + if dump_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[dump_format_name], images) else: task = self._create_task(tasks["main"], images) task_id = task["id"] if dump_format_name in [ - "MOT 1.1", "MOTS PNG 1.0", \ - "PASCAL VOC 1.1", "Segmentation mask 1.1", \ - "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", \ - "WiderFace 1.0", "VGGFace2 1.0", "Datumaro 1.0",\ - "Open Images V6 1.0" \ + "MOT 1.1", "MOTS PNG 1.0", + "PASCAL VOC 1.1", "Segmentation mask 1.1", + "TFRecord 1.0", "YOLO 1.1", "ImageNet 1.0", + "WiderFace 1.0", "VGGFace2 1.0", "Cityscapes 1.0", + "Datumaro 1.0", "Open Images V6 1.0" ]: self._create_annotations(task, dump_format_name, "default") else: @@ -1009,19 +1012,19 @@ class TaskDumpUploadTest(_DbTestBase): "Open Images V6 1.0", # changed points values 'Kitti Raw Format 1.0', 'Sly Point Cloud Format 1.0', + 'Cityscapes 1.0', # changed points value 'Datumaro 3D 1.0' ]: self.skipTest("Format is fail") # create task images = self._generate_task_images(3) - if dump_format_name == "Market-1501 1.0": - task = self._create_task(tasks["market1501"], images) - elif dump_format_name in ["ICDAR Localization 1.0", - "ICDAR Recognition 1.0"]: - task = self._create_task(tasks["icdar_localization_and_recognition"], images) - elif dump_format_name == "ICDAR Segmentation 1.0": - task = self._create_task(tasks["icdar_segmentation"], images) + if dump_format_name in [ + "Market-1501 1.0", "Cityscapes 1.0", \ + "ICDAR Localization 1.0", "ICDAR Recognition 1.0", \ + "ICDAR Segmentation 1.0" + ]: + task = self._create_task(tasks[dump_format_name], images) else: task = self._create_task(tasks["main"], images) diff --git a/cvat/apps/engine/tests/test_rest_api.py b/cvat/apps/engine/tests/test_rest_api.py index 9a97bd100..71328f4fd 100644 --- a/cvat/apps/engine/tests/test_rest_api.py +++ b/cvat/apps/engine/tests/test_rest_api.py @@ -4810,7 +4810,9 @@ class TaskAnnotationAPITestCase(JobAnnotationAPITestCase): annotations["tags"] = tags_wo_attrs annotations["shapes"] = points_wo_attrs \ + rectangle_shapes_wo_attrs - + elif annotation_format == "Cityscapes 1.0": + annotations["shapes"] = points_wo_attrs \ + + rectangle_shapes_wo_attrs elif annotation_format == "Open Images V6 1.0": annotations["tags"] = tags_wo_attrs annotations["shapes"] = rectangle_shapes_wo_attrs \ diff --git a/site/content/en/docs/manual/advanced/formats/format-cityscapes.md b/site/content/en/docs/manual/advanced/formats/format-cityscapes.md new file mode 100644 index 000000000..e8b70aba0 --- /dev/null +++ b/site/content/en/docs/manual/advanced/formats/format-cityscapes.md @@ -0,0 +1,142 @@ +--- +linkTitle: 'Cityscapes' +weight: 16 +--- + +# [Cityscapes](https://www.cityscapes-dataset.com/login/) + +- [Format specification](https://github.com/mcordts/cityscapesScripts#the-cityscapes-dataset) + +- Supported annotations + + - Polygons (segmentation task) + +- Supported attributes + - 'is_crowd' (boolean, should be defined for labels as `checkbox` -es) + Specifies if the annotation label can distinguish between different instances. + If False, the annotation id field encodes the instance id. + +# Cityscapes export + +Downloaded file: a zip archive of the following structure: + +``` +. +├── label_color.txt +├── gtFine +│ ├── +│ │ └── +│ │ ├── image_0_gtFine_instanceIds.png +│ │ ├── image_0_gtFine_color.png +│ │ ├── image_0_gtFine_labelIds.png +│ │ ├── image_1_gtFine_instanceIds.png +│ │ ├── image_1_gtFine_color.png +│ │ ├── image_1_gtFine_labelIds.png +│ │ ├── ... +└── imgsFine # if saving images was requested + └── leftImg8bit + ├── + │ └── + │ ├── image_0_leftImg8bit.png + │ ├── image_1_leftImg8bit.png + │ ├── ... +``` + +- `label_color.txt` a file that describes the color for each label + +``` +# label_color.txt example +# r g b label_name +0 0 0 background +0 255 0 tree +... +``` + +- `*_gtFine_color.png` class labels encoded by its color. +- `*_gtFine_labelIds.png` class labels are encoded by its index. +- `*_gtFine_instanceIds.png` class and instance labels encoded + by an instance ID. The pixel values encode class and the individual instance: + the integer part of a division by 1000 of each ID provides class ID, + the remainder is the instance ID. If a certain annotation describes multiple + instances, then the pixels have the regular ID of that class + +# Cityscapes annotations import + +Uploaded file: a zip archive with the following structure: + +``` +. +├── label_color.txt # optional +└── gtFine + └── + ├── image_0_gtFine_instanceIds.png + ├── image_1_gtFine_instanceIds.png + ├── ... +``` + +# Creating task with Cityscapes dataset + +Create a task with the labels you need +or you can use the labels and colors of the original dataset. +To work with the Cityscapes format, you must have a black color label +for the background. + +Original Cityscapes color map: + +
+ +```JSON +[ + {"name": "unlabeled", "color": "#000000", "attributes": []}, + {"name": "egovehicle", "color": "#000000", "attributes": []}, + {"name": "rectificationborder", "color": "#000000", "attributes": []}, + {"name": "outofroi", "color": "#000000", "attributes": []}, + {"name": "static", "color": "#000000", "attributes": []}, + {"name": "dynamic", "color": "#6f4a00", "attributes": []}, + {"name": "ground", "color": "#510051", "attributes": []}, + {"name": "road", "color": "#804080", "attributes": []}, + {"name": "sidewalk", "color": "#f423e8", "attributes": []}, + {"name": "parking", "color": "#faaaa0", "attributes": []}, + {"name": "railtrack", "color": "#e6968c", "attributes": []}, + {"name": "building", "color": "#464646", "attributes": []}, + {"name": "wall", "color": "#66669c", "attributes": []}, + {"name": "fence", "color": "#be9999", "attributes": []}, + {"name": "guardrail", "color": "#b4a5b4", "attributes": []}, + {"name": "bridge", "color": "#966464", "attributes": []}, + {"name": "tunnel", "color": "#96785a", "attributes": []}, + {"name": "pole", "color": "#999999", "attributes": []}, + {"name": "polegroup", "color": "#999999", "attributes": []}, + {"name": "trafficlight", "color": "#faaa1e", "attributes": []}, + {"name": "trafficsign", "color": "#dcdc00", "attributes": []}, + {"name": "vegetation", "color": "#6b8e23", "attributes": []}, + {"name": "terrain", "color": "#98fb98", "attributes": []}, + {"name": "sky", "color": "#4682b4", "attributes": []}, + {"name": "person", "color": "#dc143c", "attributes": []}, + {"name": "rider", "color": "#ff0000", "attributes": []}, + {"name": "car", "color": "#00008e", "attributes": []}, + {"name": "truck", "color": "#000046", "attributes": []}, + {"name": "bus", "color": "#003c64", "attributes": []}, + {"name": "caravan", "color": "#00005a", "attributes": []}, + {"name": "trailer", "color": "#00006e", "attributes": []}, + {"name": "train", "color": "#005064", "attributes": []}, + {"name": "motorcycle", "color": "#0000e6", "attributes": []}, + {"name": "bicycle", "color": "#770b20", "attributes": []}, + {"name": "licenseplate", "color": "#00000e", "attributes": []} +] + +``` + +
+ +Upload images when creating a task: + +``` +images.zip/ + ├── image_0.jpg + ├── image_1.jpg + ├── ... + +``` + +After creating the task, upload the Cityscapes annotations as described +in the previous section. -- GitLab