def register_lvis_instances(name, metadata, json_file, image_root): """ Register a dataset in LVIS's json annotation format for instance detection. Args: name (str): a name that identifies the dataset, e.g. "lvis_v0.5_train". metadata (dict): extra metadata associated with this dataset. It can be an empty dict. json_file (str): path to the json instance annotation file. image_root (str): directory which contains all the images. """ DatasetCatalog.register( name, lambda: load_lvis_json(json_file, image_root, name)) MetadataCatalog.get(name).set(json_file=json_file, image_root=image_root, evaluator_type="lvis", **metadata)
def build_evaluator(cls, cfg, dataset_name, output_folder=None): """ Create evaluator(s) for a given dataset. This uses the special metadata "evaluator_type" associated with each builtin dataset. For your own dataset, you can simply create an evaluator manually in your script and do not have to worry about the hacky if-else logic here. """ if output_folder is None: output_folder = os.path.join(cfg.OUTPUT_DIR, "inference") evaluator_list = [] evaluator_type = MetadataCatalog.get(dataset_name).evaluator_type if evaluator_type == "coco": evaluator_list.append( COCOEvaluator(dataset_name, cfg, True, output_folder)) if evaluator_type == "pascal_voc": return PascalVOCDetectionEvaluator(dataset_name) if evaluator_type == "lvis": return LVISEvaluator(dataset_name, cfg, True, output_folder) if len(evaluator_list) == 0: raise NotImplementedError( "no Evaluator for the dataset {} with the type {}".format( dataset_name, evaluator_type)) if len(evaluator_list) == 1: return evaluator_list[0] return DatasetEvaluators(evaluator_list)
def __init__(self, dataset_name, cfg, distributed, output_dir=None): """ Args: dataset_name (str): name of the dataset to be evaluated. It must have the following corresponding metadata: "json_file": the path to the LVIS format annotation cfg (CfgNode): config instance distributed (True): if True, will collect results from all ranks for evaluation. Otherwise, will evaluate the results in the current process. output_dir (str): optional, an output directory to dump results. """ from lvis import LVIS self._distributed = distributed self._output_dir = output_dir self._cpu_device = torch.device("cpu") self._logger = logging.getLogger(__name__) self._metadata = MetadataCatalog.get(dataset_name) json_file = PathManager.get_local_path(self._metadata.json_file) self._lvis_api = LVIS(json_file) # Test set json files do not contain annotations (evaluation must be # performed using the LVIS evaluation server). self._do_evaluation = len(self._lvis_api.get_ann_ids()) > 0
def register_meta_pascal_voc( name, metadata, dirname, split, year, keepclasses, sid): if keepclasses.startswith('base_novel'): thing_classes = metadata["thing_classes"][sid] elif keepclasses.startswith('base'): thing_classes = metadata["base_classes"][sid] elif keepclasses.startswith('novel'): thing_classes = metadata["novel_classes"][sid] DatasetCatalog.register( name, lambda: load_filtered_voc_instances( name, dirname, split, thing_classes) ) MetadataCatalog.get(name).set( thing_classes=thing_classes, dirname=dirname, year=year, split=split, base_classes=metadata["base_classes"][sid], novel_classes=metadata["novel_classes"][sid] )
def register_meta_coco(name, metadata, imgdir, annofile): DatasetCatalog.register( name, lambda: load_coco_json(annofile, imgdir, metadata, name), ) if '_base' in name or '_novel' in name: split = 'base' if '_base' in name else 'novel' metadata['thing_dataset_id_to_contiguous_id'] = \ metadata['{}_dataset_id_to_contiguous_id'.format(split)] metadata['thing_classes'] = metadata['{}_classes'.format(split)] MetadataCatalog.get(name).set( json_file=annofile, image_root=imgdir, evaluator_type="coco", dirname="datasets/coco", **metadata, )
def register_coco_instances(name, metadata, json_file, image_root): """ Register a dataset in COCO's json annotation format for instance detection. This is an example of how to register a new dataset. You can do something similar to this function, to register new datasets. Args: name (str): the name that identifies a dataset, e.g. "coco_2014_train". metadata (dict): extra metadata associated with this dataset. You can leave it as an empty dict. json_file (str): path to the json instance annotation file. image_root (str): directory which contains all the images. """ # 1. register a function which returns dicts DatasetCatalog.register(name, lambda: load_coco_json(json_file, image_root, name)) # 2. Optionally, add metadata about this dataset, # since they might be useful in evaluation, visualization or logging MetadataCatalog.get(name).set( json_file=json_file, image_root=image_root, evaluator_type="coco", **metadata )
def __init__(self, cfg): self.cfg = cfg.clone() # cfg can be modified by model self.model = build_model(self.cfg) self.model.eval() self.metadata = MetadataCatalog.get(cfg.DATASETS.TEST[0]) checkpointer = DetectionCheckpointer(self.model) checkpointer.load(cfg.MODEL.WEIGHTS) self.transform_gen = T.ResizeShortestEdge( [cfg.INPUT.MIN_SIZE_TEST, cfg.INPUT.MIN_SIZE_TEST], cfg.INPUT.MAX_SIZE_TEST) self.input_format = cfg.INPUT.FORMAT assert self.input_format in ["RGB", "BGR"], self.input_format
def __init__(self, dataset_name): """ Args: dataset_name (str): name of the dataset, e.g., "voc_2007_test" """ self._dataset_name = dataset_name meta = MetadataCatalog.get(dataset_name) self._anno_file_template = os.path.join(meta.dirname, "Annotations", "{}.xml") self._image_set_path = os.path.join(meta.dirname, "ImageSets", "Main", meta.split + ".txt") self._class_names = meta.thing_classes # add this two terms for calculating the mAP of different subset self._base_classes = meta.base_classes self._novel_classes = meta.novel_classes assert meta.year in [2007, 2012], meta.year self._is_2007 = meta.year == 2007 self._cpu_device = torch.device("cpu") self._logger = logging.getLogger(__name__)
return dataset_dicts if __name__ == "__main__": """ Test the LVIS json dataset loader. Usage: python -m fs3c.data.datasets.lvis \ path/to/json path/to/image_root dataset_name vis_limit """ import sys import numpy as np from fs3c.utils.logger import setup_logger from PIL import Image from fs3c.utils.visualizer import Visualizer logger = setup_logger(name=__name__) meta = MetadataCatalog.get(sys.argv[3]) dicts = load_lvis_json(sys.argv[1], sys.argv[2], sys.argv[3]) logger.info("Done loading {} samples.".format(len(dicts))) dirname = "lvis-data-vis" os.makedirs(dirname, exist_ok=True) for d in dicts[:int(sys.argv[4])]: img = np.array(Image.open(d["file_name"])) visualizer = Visualizer(img, metadata=meta) vis = visualizer.draw_dataset_dict(d) fpath = os.path.join(dirname, os.path.basename(d["file_name"])) vis.save(fpath)
parser.add_argument("--output", required=True, help="output directory") parser.add_argument("--dataset", help="name of the dataset", default="coco_2017_val") parser.add_argument("--conf-threshold", default=0.5, type=float, help="confidence threshold") args = parser.parse_args() logger = setup_logger() with PathManager.open(args.input, "r") as f: predictions = json.load(f) pred_by_image = defaultdict(list) for p in predictions: pred_by_image[p["image_id"]].append(p) dicts = list(DatasetCatalog.get(args.dataset)) metadata = MetadataCatalog.get(args.dataset) if hasattr(metadata, "thing_dataset_id_to_contiguous_id"): def dataset_id_map(ds_id): return metadata.thing_dataset_id_to_contiguous_id[ds_id] elif "lvis" in args.dataset: # LVIS results are in the same format as COCO results, but have a different # mapping from dataset category id to contiguous category id in [0, #categories - 1] def dataset_id_map(ds_id): return ds_id - 1 else: raise ValueError("Unsupported dataset: {}".format(args.dataset)) os.makedirs(args.output, exist_ok=True)
def register_pascal_voc(name, dirname, split, year): DatasetCatalog.register(name, lambda: load_voc_instances(dirname, split)) MetadataCatalog.get(name).set(thing_classes=CLASS_NAMES, dirname=dirname, year=year, split=split)
def __init__(self, dataset_name, cfg, distributed, output_dir=None): """ Args: dataset_name (str): name of the dataset to be evaluated. It must have either the following corresponding metadata: "json_file": the path to the COCO format annotation Or it must be in detectron2's standard dataset format so it can be converted to COCO format automatically. cfg (CfgNode): config instance distributed (True): if True, will collect results from all ranks for evaluation. Otherwise, will evaluate the results in the current process. output_dir (str): optional, an output directory to dump results. """ self._distributed = distributed self._output_dir = output_dir self._dataset_name = dataset_name self._cpu_device = torch.device("cpu") self._logger = logging.getLogger(__name__) self._metadata = MetadataCatalog.get(dataset_name) if not hasattr(self._metadata, "json_file"): self._logger.warning( f"json_file was not found in MetaDataCatalog for '{dataset_name}'" ) cache_path = convert_to_coco_json(dataset_name, output_dir) self._metadata.json_file = cache_path self._is_splits = "all" in dataset_name or "base" in dataset_name \ or "novel" in dataset_name self._base_classes = [ 8, 10, 11, 13, 14, 15, 22, 23, 24, 25, 27, 28, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 70, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 84, 85, 86, 87, 88, 89, 90, ] self._novel_classes = [ 1, 2, 3, 4, 5, 6, 7, 9, 16, 17, 18, 19, 20, 21, 44, 62, 63, 64, 67, 72 ] json_file = PathManager.get_local_path(self._metadata.json_file) with contextlib.redirect_stdout(io.StringIO()): self._coco_api = COCO(json_file) # Test set json files do not contain annotations (evaluation must be # performed using the COCO evaluation server). self._do_evaluation = "annotations" in self._coco_api.dataset
def register_all_pascal_voc(root="datasets"): SPLITS = [ ("voc_2007_trainval", "VOC2007", "trainval"), ("voc_2007_train", "VOC2007", "train"), ("voc_2007_val", "VOC2007", "val"), ("voc_2007_test", "VOC2007", "test"), ("voc_2012_trainval", "VOC2012", "trainval"), ("voc_2012_train", "VOC2012", "train"), ("voc_2012_val", "VOC2012", "val"), ] for name, dirname, split in SPLITS: year = 2007 if "2007" in name else 2012 register_pascal_voc(name, os.path.join(root, dirname), split, year) MetadataCatalog.get(name).evaluator_type = "pascal_voc" # register meta datasets METASPLITS = [ ("voc_2007_trainval_base1", "VOC2007", "trainval", "base1", 1), ("voc_2007_trainval_base2", "VOC2007", "trainval", "base2", 2), ("voc_2007_trainval_base3", "VOC2007", "trainval", "base3", 3), ("voc_2012_trainval_base1", "VOC2012", "trainval", "base1", 1), ("voc_2012_trainval_base2", "VOC2012", "trainval", "base2", 2), ("voc_2012_trainval_base3", "VOC2012", "trainval", "base3", 3), ("voc_2007_trainval_all1", "VOC2007", "trainval", "base_novel_1", 1), ("voc_2007_trainval_all2", "VOC2007", "trainval", "base_novel_2", 2), ("voc_2007_trainval_all3", "VOC2007", "trainval", "base_novel_3", 3), ("voc_2012_trainval_all1", "VOC2012", "trainval", "base_novel_1", 1), ("voc_2012_trainval_all2", "VOC2012", "trainval", "base_novel_2", 2), ("voc_2012_trainval_all3", "VOC2012", "trainval", "base_novel_3", 3), ("voc_2007_test_base1", "VOC2007", "test", "base1", 1), ("voc_2007_test_base2", "VOC2007", "test", "base2", 2), ("voc_2007_test_base3", "VOC2007", "test", "base3", 3), ("voc_2007_test_novel1", "VOC2007", "test", "novel1", 1), ("voc_2007_test_novel2", "VOC2007", "test", "novel2", 2), ("voc_2007_test_novel3", "VOC2007", "test", "novel3", 3), ("voc_2007_test_all1", "VOC2007", "test", "base_novel_1", 1), ("voc_2007_test_all2", "VOC2007", "test", "base_novel_2", 2), ("voc_2007_test_all3", "VOC2007", "test", "base_novel_3", 3), ] # register small meta datasets for fine-tuning stage for prefix in ["all", "novel"]: for sid in range(1, 4): for shot in [1, 2, 3, 5, 10]: for year in [2007, 2012]: for seed in range(100): seed = '' if seed == 0 else '_seed{}'.format(seed) name = "voc_{}_trainval_{}{}_{}shot{}".format( year, prefix, sid, shot, seed) dirname = "VOC{}".format(year) img_file = "{}_{}shot_split_{}_trainval".format( prefix, shot, sid) keepclasses = "base_novel_{}".format(sid) \ if prefix == 'all' else "novel{}".format(sid) METASPLITS.append( (name, dirname, img_file, keepclasses, sid)) for name, dirname, split, keepclasses, sid in METASPLITS: year = 2007 if "2007" in name else 2012 register_meta_pascal_voc(name, _get_builtin_metadata("pascal_voc_fewshot"), os.path.join(root, dirname), split, year, keepclasses, sid) MetadataCatalog.get(name).evaluator_type = "pascal_voc"
help="Modify config options using the command-line", default=None, nargs=argparse.REMAINDER, ) return parser.parse_args(in_args) if __name__ == "__main__": args = parse_args() logger = setup_logger() logger.info("Arguments: " + str(args)) cfg = setup(args) dirname = args.output_dir os.makedirs(dirname, exist_ok=True) metadata = MetadataCatalog.get(cfg.DATASETS.TRAIN[0]) def output(vis, fname): if args.show: print(fname) cv2.imshow("window", vis.get_image()[:, :, ::-1]) cv2.waitKey() else: filepath = os.path.join(dirname, fname) print("Saving to {} ...".format(filepath)) vis.save(filepath) scale = 2.0 if args.show else 1.0 if args.source == "dataloader": train_data_loader = build_detection_train_loader(cfg) for batch in train_data_loader: