CoolFace
Apppublic

jawahar-konathala/Tryon2

sourceHugging Facecc-by-nc-sa-4.0updated 2y agoView on Hugging Face
0likes
lvis.py269 linesDownload Raw Back to datasets
1# Copyright (c) Facebook, Inc. and its affiliates.2import logging3import os4 5from detectron2.data import DatasetCatalog, MetadataCatalog6from detectron2.structures import BoxMode7from detectron2.utils.file_io import PathManager8from fvcore.common.timer import Timer9 10from .builtin_meta import _get_coco_instances_meta11from .lvis_v0_5_categories import LVIS_CATEGORIES as LVIS_V0_5_CATEGORIES12from .lvis_v1_categories import LVIS_CATEGORIES as LVIS_V1_CATEGORIES13from .lvis_v1_category_image_count import (14    LVIS_CATEGORY_IMAGE_COUNT as LVIS_V1_CATEGORY_IMAGE_COUNT,15)16 17"""18This file contains functions to parse LVIS-format annotations into dicts in the19"Detectron2 format".20"""21 22logger = logging.getLogger(__name__)23 24__all__ = ["load_lvis_json", "register_lvis_instances", "get_lvis_instances_meta"]25 26 27def register_lvis_instances(name, metadata, json_file, image_root):28    """29    Register a dataset in LVIS's json annotation format for instance detection and segmentation.30 31    Args:32        name (str): a name that identifies the dataset, e.g. "lvis_v0.5_train".33        metadata (dict): extra metadata associated with this dataset. It can be an empty dict.34        json_file (str): path to the json instance annotation file.35        image_root (str or path-like): directory which contains all the images.36    """37    DatasetCatalog.register(name, lambda: load_lvis_json(json_file, image_root, name))38    MetadataCatalog.get(name).set(39        json_file=json_file, image_root=image_root, evaluator_type="lvis", **metadata40    )41 42 43def load_lvis_json(44    json_file, image_root, dataset_name=None, extra_annotation_keys=None45):46    """47    Load a json file in LVIS's annotation format.48 49    Args:50        json_file (str): full path to the LVIS json annotation file.51        image_root (str): the directory where the images in this json file exists.52        dataset_name (str): the name of the dataset (e.g., "lvis_v0.5_train").53            If provided, this function will put "thing_classes" into the metadata54            associated with this dataset.55        extra_annotation_keys (list[str]): list of per-annotation keys that should also be56            loaded into the dataset dict (besides "bbox", "bbox_mode", "category_id",57            "segmentation"). The values for these keys will be returned as-is.58 59    Returns:60        list[dict]: a list of dicts in Detectron2 standard format. (See61        `Using Custom Datasets </tutorials/datasets.html>`_ )62 63    Notes:64        1. This function does not read the image files.65           The results do not have the "image" field.66    """67    from lvis import LVIS68 69    json_file = PathManager.get_local_path(json_file)70 71    timer = Timer()72    lvis_api = LVIS(json_file)73    if timer.seconds() > 1:74        logger.info(75            "Loading {} takes {:.2f} seconds.".format(json_file, timer.seconds())76        )77 78    if dataset_name is not None:79        meta = get_lvis_instances_meta(dataset_name)80        MetadataCatalog.get(dataset_name).set(**meta)81 82    # sort indices for reproducible results83    img_ids = sorted(lvis_api.imgs.keys())84    # imgs is a list of dicts, each looks something like:85    # {'license': 4,86    #  'url': 'http://farm6.staticflickr.com/5454/9413846304_881d5e5c3b_z.jpg',87    #  'file_name': 'COCO_val2014_000000001268.jpg',88    #  'height': 427,89    #  'width': 640,90    #  'date_captured': '2013-11-17 05:57:24',91    #  'id': 1268}92    imgs = lvis_api.load_imgs(img_ids)93    # anns is a list[list[dict]], where each dict is an annotation94    # record for an object. The inner list enumerates the objects in an image95    # and the outer list enumerates over images. Example of anns[0]:96    # [{'segmentation': [[192.81,97    #     247.09,98    #     ...99    #     219.03,100    #     249.06]],101    #   'area': 1035.749,102    #   'image_id': 1268,103    #   'bbox': [192.81, 224.8, 74.73, 33.43],104    #   'category_id': 16,105    #   'id': 42986},106    #  ...]107    anns = [lvis_api.img_ann_map[img_id] for img_id in img_ids]108 109    # Sanity check that each annotation has a unique id110    ann_ids = [ann["id"] for anns_per_image in anns for ann in anns_per_image]111    assert len(set(ann_ids)) == len(112        ann_ids113    ), "Annotation ids in '{}' are not unique".format(json_file)114 115    imgs_anns = list(zip(imgs, anns))116 117    logger.info(118        "Loaded {} images in the LVIS format from {}".format(len(imgs_anns), json_file)119    )120 121    if extra_annotation_keys:122        logger.info(123            "The following extra annotation keys will be loaded: {} ".format(124                extra_annotation_keys125            )126        )127    else:128        extra_annotation_keys = []129 130    def get_file_name(img_root, img_dict):131        # Determine the path including the split folder ("train2017", "val2017", "test2017") from132        # the coco_url field. Example:133        #   'coco_url': 'http://images.cocodataset.org/train2017/000000155379.jpg'134        split_folder, file_name = img_dict["coco_url"].split("/")[-2:]135        return os.path.join(img_root + split_folder, file_name)136 137    dataset_dicts = []138 139    for (img_dict, anno_dict_list) in imgs_anns:140        record = {}141        record["file_name"] = get_file_name(image_root, img_dict)142        record["height"] = img_dict["height"]143        record["width"] = img_dict["width"]144        record["not_exhaustive_category_ids"] = img_dict.get(145            "not_exhaustive_category_ids", []146        )147        record["neg_category_ids"] = img_dict.get("neg_category_ids", [])148        image_id = record["image_id"] = img_dict["id"]149 150        objs = []151        for anno in anno_dict_list:152            # Check that the image_id in this annotation is the same as153            # the image_id we're looking at.154            # This fails only when the data parsing logic or the annotation file is buggy.155            assert anno["image_id"] == image_id156            obj = {"bbox": anno["bbox"], "bbox_mode": BoxMode.XYWH_ABS}157            # LVIS data loader can be used to load COCO dataset categories. In this case `meta`158            # variable will have a field with COCO-specific category mapping.159            if dataset_name is not None and "thing_dataset_id_to_contiguous_id" in meta:160                obj["category_id"] = meta["thing_dataset_id_to_contiguous_id"][161                    anno["category_id"]162                ]163            else:164                obj["category_id"] = (165                    anno["category_id"] - 1166                )  # Convert 1-indexed to 0-indexed167            segm = anno["segmentation"]  # list[list[float]]168            # filter out invalid polygons (< 3 points)169            valid_segm = [170                poly for poly in segm if len(poly) % 2 == 0 and len(poly) >= 6171            ]172            assert len(segm) == len(173                valid_segm174            ), "Annotation contains an invalid polygon with < 3 points"175            assert len(segm) > 0176            obj["segmentation"] = segm177            for extra_ann_key in extra_annotation_keys:178                obj[extra_ann_key] = anno[extra_ann_key]179            objs.append(obj)180        record["annotations"] = objs181        dataset_dicts.append(record)182 183    return dataset_dicts184 185 186def get_lvis_instances_meta(dataset_name):187    """188    Load LVIS metadata.189 190    Args:191        dataset_name (str): LVIS dataset name without the split name (e.g., "lvis_v0.5").192 193    Returns:194        dict: LVIS metadata with keys: thing_classes195    """196    if "cocofied" in dataset_name:197        return _get_coco_instances_meta()198    if "v0.5" in dataset_name:199        return _get_lvis_instances_meta_v0_5()200    elif "v1" in dataset_name:201        return _get_lvis_instances_meta_v1()202    raise ValueError("No built-in metadata for dataset {}".format(dataset_name))203 204 205def _get_lvis_instances_meta_v0_5():206    assert len(LVIS_V0_5_CATEGORIES) == 1230207    cat_ids = [k["id"] for k in LVIS_V0_5_CATEGORIES]208    assert min(cat_ids) == 1 and max(cat_ids) == len(209        cat_ids210    ), "Category ids are not in [1, #categories], as expected"211    # Ensure that the category list is sorted by id212    lvis_categories = sorted(LVIS_V0_5_CATEGORIES, key=lambda x: x["id"])213    thing_classes = [k["synonyms"][0] for k in lvis_categories]214    meta = {"thing_classes": thing_classes}215    return meta216 217 218def _get_lvis_instances_meta_v1():219    assert len(LVIS_V1_CATEGORIES) == 1203220    cat_ids = [k["id"] for k in LVIS_V1_CATEGORIES]221    assert min(cat_ids) == 1 and max(cat_ids) == len(222        cat_ids223    ), "Category ids are not in [1, #categories], as expected"224    # Ensure that the category list is sorted by id225    lvis_categories = sorted(LVIS_V1_CATEGORIES, key=lambda x: x["id"])226    thing_classes = [k["synonyms"][0] for k in lvis_categories]227    meta = {228        "thing_classes": thing_classes,229        "class_image_count": LVIS_V1_CATEGORY_IMAGE_COUNT,230    }231    return meta232 233 234def main() -> None:235    global logger236    """237    Test the LVIS json dataset loader.238 239    Usage:240        python -m detectron2.data.datasets.lvis \241            path/to/json path/to/image_root dataset_name vis_limit242    """243    import sys244 245    import detectron2.data.datasets  # noqa  # add pre-defined metadata246    import numpy as np247    from detectron2.utils.logger import setup_logger248    from detectron2.utils.visualizer import Visualizer249    from PIL import Image250 251    logger = setup_logger(name=__name__)252    meta = MetadataCatalog.get(sys.argv[3])253 254    dicts = load_lvis_json(sys.argv[1], sys.argv[2], sys.argv[3])255    logger.info("Done loading {} samples.".format(len(dicts)))256 257    dirname = "lvis-data-vis"258    os.makedirs(dirname, exist_ok=True)259    for d in dicts[: int(sys.argv[4])]:260        img = np.array(Image.open(d["file_name"]))261        visualizer = Visualizer(img, metadata=meta)262        vis = visualizer.draw_dataset_dict(d)263        fpath = os.path.join(dirname, os.path.basename(d["file_name"]))264        vis.save(fpath)265 266 267if __name__ == "__main__":268    main()  # pragma: no cover269