| import contextlib
|
| import copy
|
| import io
|
| import logging
|
| import os
|
| import random
|
|
|
| import numpy as np
|
| import pycocotools.mask as mask_util
|
| from detectron2.structures import Boxes, BoxMode, PolygonMasks, RotatedBoxes
|
| from detectron2.utils.file_io import PathManager
|
| from fvcore.common.timer import Timer
|
| from PIL import Image
|
|
|
| """
|
| This file contains functions to parse RefCOCO-format annotations into dicts in "Detectron2 format".
|
| """
|
|
|
|
|
| logger = logging.getLogger(__name__)
|
|
|
| __all__ = ["load_refcoco_json"]
|
|
|
|
|
| def load_grefcoco_json(
|
| refer_root,
|
| dataset_name,
|
| splitby,
|
| split,
|
| image_root,
|
| extra_annotation_keys=None,
|
| extra_refer_keys=None,
|
| ):
|
| if dataset_name == "refcocop":
|
| dataset_name = "refcoco+"
|
| if dataset_name == "refcoco" or dataset_name == "refcoco+":
|
| splitby == "unc"
|
| if dataset_name == "refcocog":
|
| assert splitby == "umd" or splitby == "google"
|
|
|
| dataset_id = "_".join([dataset_name, splitby, split])
|
|
|
| from .grefer import G_REFER
|
|
|
| logger.info("Loading dataset {} ({}-{}) ...".format(dataset_name, splitby, split))
|
| logger.info("Refcoco root: {}".format(refer_root))
|
| timer = Timer()
|
| refer_root = PathManager.get_local_path(refer_root)
|
| with contextlib.redirect_stdout(io.StringIO()):
|
| refer_api = G_REFER(data_root=refer_root, dataset=dataset_name, splitBy=splitby)
|
| if timer.seconds() > 1:
|
| logger.info(
|
| "Loading {} takes {:.2f} seconds.".format(dataset_id, timer.seconds())
|
| )
|
|
|
| ref_ids = refer_api.getRefIds(split=split)
|
| img_ids = refer_api.getImgIds(ref_ids)
|
| refs = refer_api.loadRefs(ref_ids)
|
| imgs = [refer_api.loadImgs(ref["image_id"])[0] for ref in refs]
|
| anns = [refer_api.loadAnns(ref["ann_id"]) for ref in refs]
|
| imgs_refs_anns = list(zip(imgs, refs, anns))
|
|
|
| logger.info(
|
| "Loaded {} images, {} referring object sets in G_RefCOCO format from {}".format(
|
| len(img_ids), len(ref_ids), dataset_id
|
| )
|
| )
|
|
|
| dataset_dicts = []
|
|
|
| ann_keys = ["iscrowd", "bbox", "category_id"] + (extra_annotation_keys or [])
|
| ref_keys = ["raw", "sent_id"] + (extra_refer_keys or [])
|
|
|
| ann_lib = {}
|
|
|
| NT_count = 0
|
| MT_count = 0
|
|
|
| for img_dict, ref_dict, anno_dicts in imgs_refs_anns:
|
| record = {}
|
| record["source"] = "grefcoco"
|
| record["file_name"] = os.path.join(image_root, img_dict["file_name"])
|
| record["height"] = img_dict["height"]
|
| record["width"] = img_dict["width"]
|
| image_id = record["image_id"] = img_dict["id"]
|
|
|
|
|
|
|
| assert ref_dict["image_id"] == image_id
|
| assert ref_dict["split"] == split
|
| if not isinstance(ref_dict["ann_id"], list):
|
| ref_dict["ann_id"] = [ref_dict["ann_id"]]
|
|
|
|
|
| if None in anno_dicts:
|
| assert anno_dicts == [None]
|
| assert ref_dict["ann_id"] == [-1]
|
| record["empty"] = True
|
| obj = {key: None for key in ann_keys if key in ann_keys}
|
| obj["bbox_mode"] = BoxMode.XYWH_ABS
|
| obj["empty"] = True
|
| obj = [obj]
|
|
|
|
|
| else:
|
| record["empty"] = False
|
| obj = []
|
| for anno_dict in anno_dicts:
|
| ann_id = anno_dict["id"]
|
| if anno_dict["iscrowd"]:
|
| continue
|
| assert anno_dict["image_id"] == image_id
|
| assert ann_id in ref_dict["ann_id"]
|
|
|
| if ann_id in ann_lib:
|
| ann = ann_lib[ann_id]
|
| else:
|
| ann = {key: anno_dict[key] for key in ann_keys if key in anno_dict}
|
| ann["bbox_mode"] = BoxMode.XYWH_ABS
|
| ann["empty"] = False
|
|
|
| segm = anno_dict.get("segmentation", None)
|
| assert segm
|
| if isinstance(segm, dict):
|
| if isinstance(segm["counts"], list):
|
|
|
| segm = mask_util.frPyObjects(segm, *segm["size"])
|
| else:
|
|
|
| segm = [
|
| poly
|
| for poly in segm
|
| if len(poly) % 2 == 0 and len(poly) >= 6
|
| ]
|
| if len(segm) == 0:
|
| num_instances_without_valid_segmentation += 1
|
| continue
|
| ann["segmentation"] = segm
|
| ann_lib[ann_id] = ann
|
|
|
| obj.append(ann)
|
|
|
| record["annotations"] = obj
|
|
|
|
|
| sents = ref_dict["sentences"]
|
| for sent in sents:
|
| ref_record = record.copy()
|
| ref = {key: sent[key] for key in ref_keys if key in sent}
|
| ref["ref_id"] = ref_dict["ref_id"]
|
| ref_record["sentence"] = ref
|
| dataset_dicts.append(ref_record)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| return dataset_dicts
|
|
|
|
|
| if __name__ == "__main__":
|
| """
|
| Test the COCO json dataset loader.
|
|
|
| Usage:
|
| python -m detectron2.data.datasets.coco \
|
| path/to/json path/to/image_root dataset_name
|
|
|
| "dataset_name" can be "coco_2014_minival_100", or other
|
| pre-registered ones
|
| """
|
| import sys
|
|
|
| REFCOCO_PATH = "/mnt/lustre/hhding/code/ReLA/datasets"
|
| COCO_TRAIN_2014_IMAGE_ROOT = "/mnt/lustre/hhding/code/ReLA/datasets/images"
|
| REFCOCO_DATASET = "grefcoco"
|
| REFCOCO_SPLITBY = "unc"
|
| REFCOCO_SPLIT = "train"
|
|
|
|
|
| dicts = load_grefcoco_json(
|
| REFCOCO_PATH,
|
| REFCOCO_DATASET,
|
| REFCOCO_SPLITBY,
|
| REFCOCO_SPLIT,
|
| COCO_TRAIN_2014_IMAGE_ROOT,
|
| )
|
| print(1)
|
|
|