|
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) |
|
|