|  |  | 
					
						
						|  | import json | 
					
						
						|  | import logging | 
					
						
						|  | import os | 
					
						
						|  |  | 
					
						
						|  | from detectron2.data import DatasetCatalog, MetadataCatalog | 
					
						
						|  | from detectron2.data.datasets.builtin_meta import CITYSCAPES_CATEGORIES | 
					
						
						|  | from detectron2.utils.file_io import PathManager | 
					
						
						|  |  | 
					
						
						|  | """ | 
					
						
						|  | This file contains functions to register the Cityscapes panoptic dataset to the DatasetCatalog. | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | logger = logging.getLogger(__name__) | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def get_cityscapes_panoptic_files(image_dir, gt_dir, json_info): | 
					
						
						|  | files = [] | 
					
						
						|  |  | 
					
						
						|  | cities = PathManager.ls(image_dir) | 
					
						
						|  | logger.info(f"{len(cities)} cities found in '{image_dir}'.") | 
					
						
						|  | image_dict = {} | 
					
						
						|  | for city in cities: | 
					
						
						|  | city_img_dir = os.path.join(image_dir, city) | 
					
						
						|  | for basename in PathManager.ls(city_img_dir): | 
					
						
						|  | image_file = os.path.join(city_img_dir, basename) | 
					
						
						|  |  | 
					
						
						|  | suffix = "_leftImg8bit.png" | 
					
						
						|  | assert basename.endswith(suffix), basename | 
					
						
						|  | basename = os.path.basename(basename)[: -len(suffix)] | 
					
						
						|  |  | 
					
						
						|  | image_dict[basename] = image_file | 
					
						
						|  |  | 
					
						
						|  | for ann in json_info["annotations"]: | 
					
						
						|  | image_file = image_dict.get(ann["image_id"], None) | 
					
						
						|  | assert image_file is not None, "No image {} found for annotation {}".format( | 
					
						
						|  | ann["image_id"], ann["file_name"] | 
					
						
						|  | ) | 
					
						
						|  | label_file = os.path.join(gt_dir, ann["file_name"]) | 
					
						
						|  | segments_info = ann["segments_info"] | 
					
						
						|  |  | 
					
						
						|  | files.append((image_file, label_file, segments_info)) | 
					
						
						|  |  | 
					
						
						|  | assert len(files), "No images found in {}".format(image_dir) | 
					
						
						|  | assert PathManager.isfile(files[0][0]), files[0][0] | 
					
						
						|  | assert PathManager.isfile(files[0][1]), files[0][1] | 
					
						
						|  | return files | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def load_cityscapes_panoptic(image_dir, gt_dir, gt_json, meta): | 
					
						
						|  | """ | 
					
						
						|  | Args: | 
					
						
						|  | image_dir (str): path to the raw dataset. e.g., "~/cityscapes/leftImg8bit/train". | 
					
						
						|  | gt_dir (str): path to the raw annotations. e.g., | 
					
						
						|  | "~/cityscapes/gtFine/cityscapes_panoptic_train". | 
					
						
						|  | gt_json (str): path to the json file. e.g., | 
					
						
						|  | "~/cityscapes/gtFine/cityscapes_panoptic_train.json". | 
					
						
						|  | meta (dict): dictionary containing "thing_dataset_id_to_contiguous_id" | 
					
						
						|  | and "stuff_dataset_id_to_contiguous_id" to map category ids to | 
					
						
						|  | contiguous ids for training. | 
					
						
						|  |  | 
					
						
						|  | Returns: | 
					
						
						|  | list[dict]: a list of dicts in Detectron2 standard format. (See | 
					
						
						|  | `Using Custom Datasets </tutorials/datasets.html>`_ ) | 
					
						
						|  | """ | 
					
						
						|  |  | 
					
						
						|  | def _convert_category_id(segment_info, meta): | 
					
						
						|  | if segment_info["category_id"] in meta["thing_dataset_id_to_contiguous_id"]: | 
					
						
						|  | segment_info["category_id"] = meta["thing_dataset_id_to_contiguous_id"][ | 
					
						
						|  | segment_info["category_id"] | 
					
						
						|  | ] | 
					
						
						|  | else: | 
					
						
						|  | segment_info["category_id"] = meta["stuff_dataset_id_to_contiguous_id"][ | 
					
						
						|  | segment_info["category_id"] | 
					
						
						|  | ] | 
					
						
						|  | return segment_info | 
					
						
						|  |  | 
					
						
						|  | assert os.path.exists( | 
					
						
						|  | gt_json | 
					
						
						|  | ), "Please run `python cityscapesscripts/preparation/createPanopticImgs.py` to generate label files." | 
					
						
						|  | with open(gt_json) as f: | 
					
						
						|  | json_info = json.load(f) | 
					
						
						|  | files = get_cityscapes_panoptic_files(image_dir, gt_dir, json_info) | 
					
						
						|  | ret = [] | 
					
						
						|  | for image_file, label_file, segments_info in files: | 
					
						
						|  | sem_label_file = ( | 
					
						
						|  | image_file.replace("leftImg8bit", "gtFine").split(".")[0] + "_labelTrainIds.png" | 
					
						
						|  | ) | 
					
						
						|  | segments_info = [_convert_category_id(x, meta) for x in segments_info] | 
					
						
						|  | ret.append( | 
					
						
						|  | { | 
					
						
						|  | "file_name": image_file, | 
					
						
						|  | "image_id": "_".join( | 
					
						
						|  | os.path.splitext(os.path.basename(image_file))[0].split("_")[:3] | 
					
						
						|  | ), | 
					
						
						|  | "sem_seg_file_name": sem_label_file, | 
					
						
						|  | "pan_seg_file_name": label_file, | 
					
						
						|  | "segments_info": segments_info, | 
					
						
						|  | } | 
					
						
						|  | ) | 
					
						
						|  | assert len(ret), f"No images found in {image_dir}!" | 
					
						
						|  | assert PathManager.isfile( | 
					
						
						|  | ret[0]["sem_seg_file_name"] | 
					
						
						|  | ), "Please generate labelTrainIds.png with cityscapesscripts/preparation/createTrainIdLabelImgs.py" | 
					
						
						|  | assert PathManager.isfile( | 
					
						
						|  | ret[0]["pan_seg_file_name"] | 
					
						
						|  | ), "Please generate panoptic annotation with python cityscapesscripts/preparation/createPanopticImgs.py" | 
					
						
						|  | return ret | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | _RAW_CITYSCAPES_PANOPTIC_SPLITS = { | 
					
						
						|  | "cityscapes_fine_panoptic_train": ( | 
					
						
						|  | "cityscapes/leftImg8bit/train", | 
					
						
						|  | "cityscapes/gtFine/cityscapes_panoptic_train", | 
					
						
						|  | "cityscapes/gtFine/cityscapes_panoptic_train.json", | 
					
						
						|  | ), | 
					
						
						|  | "cityscapes_fine_panoptic_val": ( | 
					
						
						|  | "cityscapes/leftImg8bit/val", | 
					
						
						|  | "cityscapes/gtFine/cityscapes_panoptic_val", | 
					
						
						|  | "cityscapes/gtFine/cityscapes_panoptic_val.json", | 
					
						
						|  | ), | 
					
						
						|  |  | 
					
						
						|  | } | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | def register_all_cityscapes_panoptic(root): | 
					
						
						|  | meta = {} | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | thing_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] | 
					
						
						|  | thing_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] | 
					
						
						|  | stuff_classes = [k["name"] for k in CITYSCAPES_CATEGORIES] | 
					
						
						|  | stuff_colors = [k["color"] for k in CITYSCAPES_CATEGORIES] | 
					
						
						|  |  | 
					
						
						|  | meta["thing_classes"] = thing_classes | 
					
						
						|  | meta["thing_colors"] = thing_colors | 
					
						
						|  | meta["stuff_classes"] = stuff_classes | 
					
						
						|  | meta["stuff_colors"] = stuff_colors | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  |  | 
					
						
						|  | thing_dataset_id_to_contiguous_id = {} | 
					
						
						|  | stuff_dataset_id_to_contiguous_id = {} | 
					
						
						|  |  | 
					
						
						|  | for k in CITYSCAPES_CATEGORIES: | 
					
						
						|  | if k["isthing"] == 1: | 
					
						
						|  | thing_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] | 
					
						
						|  | else: | 
					
						
						|  | stuff_dataset_id_to_contiguous_id[k["id"]] = k["trainId"] | 
					
						
						|  |  | 
					
						
						|  | meta["thing_dataset_id_to_contiguous_id"] = thing_dataset_id_to_contiguous_id | 
					
						
						|  | meta["stuff_dataset_id_to_contiguous_id"] = stuff_dataset_id_to_contiguous_id | 
					
						
						|  |  | 
					
						
						|  | for key, (image_dir, gt_dir, gt_json) in _RAW_CITYSCAPES_PANOPTIC_SPLITS.items(): | 
					
						
						|  | image_dir = os.path.join(root, image_dir) | 
					
						
						|  | gt_dir = os.path.join(root, gt_dir) | 
					
						
						|  | gt_json = os.path.join(root, gt_json) | 
					
						
						|  |  | 
					
						
						|  | DatasetCatalog.register( | 
					
						
						|  | key, lambda x=image_dir, y=gt_dir, z=gt_json: load_cityscapes_panoptic(x, y, z, meta) | 
					
						
						|  | ) | 
					
						
						|  | MetadataCatalog.get(key).set( | 
					
						
						|  | panoptic_root=gt_dir, | 
					
						
						|  | image_root=image_dir, | 
					
						
						|  | panoptic_json=gt_json, | 
					
						
						|  | gt_dir=gt_dir.replace("cityscapes_panoptic_", ""), | 
					
						
						|  | evaluator_type="cityscapes_panoptic_seg", | 
					
						
						|  | ignore_label=255, | 
					
						
						|  | label_divisor=1000, | 
					
						
						|  | **meta, | 
					
						
						|  | ) | 
					
						
						|  |  |