dsp-repro-bundle / datamodules /ref_table.py
junwatu's picture
Upload folder using huggingface_hub
c881b77 verified
Raw
History Blame Contribute Delete
3.4 kB
import functools
import imagesize
import torch
import os
import json
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class RefTable:
def __init__(self, config, filter_dict=None):
self.phase = config.phase
self.categories_base, self.categories_novel = config.dataset.categories.base, config.dataset.categories.novel
self.categories = config.dataset.categories.get('all', None) or (self.categories_novel + self.categories_base)
self.image_patch_path = config.dataset.image_patch_path
self.filter_dict = filter_dict
self.augment = config.dataset.get('ref_augment', False)
cache_path = os.path.join(self.image_patch_path, "image_sizes.json")
if not os.path.exists(cache_path):
raise FileNotFoundError(f"File Not Found: {cache_path}")
with open(cache_path, 'r') as f:
self.img_size_cache = json.load(f)
self.ref_table, self.base_ref_table, self.novel_ref_table = self.build_ref_table()
def build_ref_table(self):
ref_table, base_ref_table, novel_ref_table = {}, {}, {}
for category in self.categories:
category_dir = os.path.join(self.image_patch_path, category)
patch_list = os.listdir(category_dir)
patch_list = list(filter(lambda s: s.endswith('.jpg'), patch_list))
# Filter the patch list to avoid data leakage of few-shot learning
if self.phase == 'novel' and category in self.categories_novel:
assert self.filter_dict is not None
patch_list = list(filter(lambda patch_name: patch_name.rsplit('_', 1)[0] in self.filter_dict[category], patch_list))
if self.augment:
aug_category_dir = os.path.join(self.image_patch_path, category, 'augmented')
aug_patch_list = os.listdir(aug_category_dir)
aug_patch_list = list(filter(lambda patch_name: patch_name.startswith(tuple(self.filter_dict[category])), aug_patch_list))
aug_patch_list = list(map(lambda patch_name: f"augmented/{patch_name}", aug_patch_list))
patch_list += aug_patch_list
def get_size(img_name):
return self.img_size_cache.get(img_name, [0, 1])
patch_list = sorted(patch_list, key = lambda img: get_size(img)[0] * get_size(img)[1], reverse=True)
# Only build novel ref table at novel phase
if self.phase == 'novel' and category in self.categories_novel:
novel_ref_table[category] = {
img: get_size(img)[0] / get_size(img)[1] for img in patch_list[:200]
}
elif category in self.categories_base:
base_ref_table[category] = {
img: get_size(img)[0] / get_size(img)[1] for img in patch_list[:200]
}
ref_table = novel_ref_table | base_ref_table
return ref_table, base_ref_table, novel_ref_table
def __call__(self, phase=None):
if phase is None:
return self.ref_table
if phase == 'base':
return self.base_ref_table
if phase == 'novel':
return self.novel_ref_table