Spaces:
Build error
Build error
""" | |
COCO dataset which returns image_id for evaluation. | |
Mostly copy-paste from https://github.com/pytorch/vision/blob/13b35ff/references/detection/coco_utils.py | |
""" | |
import torch | |
import json | |
from PIL import Image, ImageDraw | |
from .modulated_coco import ConvertCocoPolysToMask | |
from .tsv import ODTSVDataset | |
from pycocotools.coco import COCO | |
from maskrcnn_benchmark.structures.bounding_box import BoxList | |
import random | |
from .od_to_grounding import convert_object_detection_to_grounding_optimized_for_od, check_for_positive_overflow, sanity_check_target_after_processing | |
class CocoDetectionTSV(ODTSVDataset): | |
def __init__(self, | |
name, | |
yaml_file, | |
transforms, | |
return_tokens, | |
tokenizer, | |
extra_fields, | |
random_sample_negative=-1, | |
add_detection_prompt=False, | |
add_detection_prompt_advanced=False, | |
use_od_data_aug=False, | |
control_probabilities={}, | |
disable_shuffle=False, | |
prompt_engineer_version="v2", | |
prompt_limit_negative=-1, | |
positive_question_probability=0.6, | |
negative_question_probability=0.8, | |
full_question_probability=0.5, | |
disable_clip_to_image=False, | |
separation_tokens=" ", | |
no_mask_for_od=False, | |
max_num_labels=-1, | |
max_query_len=256, | |
**kwargs | |
): | |
super(CocoDetectionTSV, self).__init__(yaml_file, extra_fields, **kwargs) | |
self._transforms = transforms | |
self.name = name | |
self.max_query_len = max_query_len | |
self.prepare = ConvertCocoPolysToMask( | |
return_masks=False, | |
return_tokens=return_tokens, | |
tokenizer=tokenizer, | |
max_query_len=max_query_len | |
) | |
self.tokenizer = tokenizer | |
self.control_probabilities = control_probabilities | |
self.random_sample_negative = random_sample_negative | |
self.add_detection_prompt = add_detection_prompt | |
self.add_detection_prompt_advanced = add_detection_prompt_advanced | |
self.use_od_data_aug = use_od_data_aug | |
self.prompt_engineer_version = prompt_engineer_version | |
self.prompt_limit_negative = prompt_limit_negative | |
self.positive_question_probability = positive_question_probability | |
self.negative_question_probability = negative_question_probability | |
self.full_question_probability = full_question_probability | |
self.separation_tokens = separation_tokens | |
self.disable_clip_to_image = disable_clip_to_image | |
self.disable_shuffle = disable_shuffle | |
self.no_mask_for_od = no_mask_for_od | |
self.max_num_labels = max_num_labels | |
def __len__(self): | |
return super(CocoDetectionTSV, self).__len__() | |
def categories(self, no_background=True): | |
categories = self.coco.dataset["categories"] | |
label_list = {} | |
for index, i in enumerate(categories): | |
# assert(index + 1 == i["id"]) | |
if not no_background or (i["name"] != "__background__" and i['id'] != 0): | |
label_list[i["id"]] = i["name"] | |
return label_list | |
def __getitem__(self, idx): | |
# tgt is a BoxList | |
img, target, _, scale = super(CocoDetectionTSV, self).__getitem__(idx) | |
image_id = self.get_img_id(idx) | |
restricted_negative_list = None | |
if not self.disable_clip_to_image: | |
target = target.clip_to_image(remove_empty=True) | |
original_box_num = len(target) | |
target, positive_caption_length = check_for_positive_overflow(target, self.ind_to_class, self.tokenizer, self.max_query_len-2) # leave some space for the special tokens | |
if len(target) < original_box_num: | |
print("WARNING: removed {} boxes due to positive caption overflow".format(original_box_num - len(target))) | |
annotations, caption, greenlight_span_for_masked_lm_objective, label_to_positions = convert_object_detection_to_grounding_optimized_for_od( | |
target=target, | |
image_id=image_id, | |
ind_to_class=self.ind_to_class, | |
disable_shuffle=self.disable_shuffle, | |
add_detection_prompt=self.add_detection_prompt, | |
add_detection_prompt_advanced=self.add_detection_prompt_advanced, | |
random_sample_negative=self.random_sample_negative, | |
control_probabilities=self.control_probabilities, | |
restricted_negative_list=restricted_negative_list, | |
separation_tokens=self.separation_tokens, | |
max_num_labels=self.max_num_labels, | |
positive_caption_length=positive_caption_length, | |
tokenizer=self.tokenizer, | |
max_seq_length=self.max_query_len-2 | |
) | |
# assert(len(self.tokenizer.tokenize(caption)) <= self.max_query_len-2) | |
# print(caption) | |
anno = {"image_id": image_id, "annotations": annotations, "caption": caption, "label_to_positions": label_to_positions} | |
anno["greenlight_span_for_masked_lm_objective"] = greenlight_span_for_masked_lm_objective | |
if self.no_mask_for_od: | |
anno["greenlight_span_for_masked_lm_objective"].append((-1, -1, -1)) | |
img, anno = self.prepare(img, anno, box_format="xyxy") | |
if self._transforms is not None: | |
img, target = self._transforms(img, target) | |
# add additional property | |
for ann in anno: | |
target.add_field(ann, anno[ann]) | |
sanity_check_target_after_processing(target) | |
return img, target, idx | |
def get_raw_image(self, idx): | |
image, *_ = super(CocoDetectionTSV, self).__getitem__(idx) | |
return image | |
def get_img_id(self, idx): | |
line_no = self.get_line_no(idx) | |
if self.label_tsv is not None: | |
row = self.label_tsv.seek(line_no) | |
img_id = row[0] | |
try: | |
return int(img_id) | |
except: | |
return idx | |