SpiS-GAN / lib /datasets.py
hoainam1706's picture
Upload folder using huggingface_hub
8bc5625 verified
Raw
History Blame Contribute Delete
5.12 kB
import os, h5py
import numpy as np
from PIL import Image
import torch
from torch.utils.data import Dataset
from torchvision.transforms import Compose, Normalize, ToTensor
from lib.alphabet import strLabelConverter
from lib.path_config import data_roots, data_paths
class Hdf5Dataset(Dataset):
def __init__(self, root, split, transforms=None, alphabet_key='all'): # Change here for alphabet key
super(Hdf5Dataset, self).__init__()
self.root = root
self._load_h5py(split)
self.transforms = transforms
self.label_converter = strLabelConverter(alphabet_key)
def _load_h5py(self, split):
self.file_path = os.path.join(self.root, split)
h5f = h5py.File(self.file_path, 'r')
self.imgs, self.lbs = h5f['imgs'][:], h5f['lbs'][:]
self.img_seek_idxs, self.lb_seek_idxs = h5f['img_seek_idxs'][:], h5f['lb_seek_idxs'][:]
self.img_lens, self.lb_lens = h5f['img_lens'][:], h5f['lb_lens'][:]
self.wids = h5f['wids'][:]
def __getitem__(self, idx):
img_seek_idx, img_len = self.img_seek_idxs[idx], self.img_lens[idx]
lb_seek_idx, lb_len = self.lb_seek_idxs[idx], self.lb_lens[idx]
img = self.imgs[:, img_seek_idx : img_seek_idx + img_len]
text = ''.join(chr(ch) for ch in self.lbs[lb_seek_idx : lb_seek_idx + lb_len])
lb = self.label_converter.encode(text)
wid = self.wids[idx]
img = Image.fromarray(img, mode='L')
if self.transforms is not None:
img = self.transforms(img)
return img, lb, wid
def __len__(self):
return len(self.img_lens)
@staticmethod
def collect_fn(batch):
def _recalc_len(leng, scale):
tmp = leng % scale
return leng + scale - tmp if tmp != 0 else leng
imgs, lbs, wids, lb_lens, img_lens, pad_img_lens = [], [], [], [], [], []
for img, lb, wid in batch:
if isinstance(img, torch.Tensor):
img = img.numpy()
imgs.append(img)
lbs.append(lb)
wids.append(wid)
lb_lens.append(len(lb))
img_lens.append(img.shape[-1])
pad_img_lens.append(_recalc_len(img.shape[-1], img.shape[-2] // 2))
bz = len(lb_lens)
imgHeight = imgs[0].shape[-2]
max_img_len = max(pad_img_lens)
pad_imgs = -np.ones((bz, 1, imgHeight, max_img_len))
for i, (img, img_len) in enumerate(zip(imgs, img_lens)):
pad_imgs[i, 0, :, :img_len] = img
max_lb_len = max(lb_lens)
pad_lbs = np.zeros((bz, max_lb_len))
for i, (lb, lb_len) in enumerate(zip(lbs, lb_lens)):
pad_lbs[i, :lb_len] = lb
imgs = torch.from_numpy(pad_imgs).float()
img_lens = torch.Tensor(pad_img_lens).int()
lbs = torch.from_numpy(pad_lbs).int()
lb_lens = torch.Tensor(lb_lens).int()
wids = torch.Tensor(wids).long()
return imgs, img_lens, lbs, lb_lens, wids
@staticmethod
def sort_collect_fn(batch):
imgs, lbs, wids = zip(*batch)
img_lens = np.array([img.size(-1) for img in imgs]).astype(np.int32)
idx = np.argsort(img_lens)[::-1]
imgs = [imgs[i] for i in idx]
lbs = [lbs[i] for i in idx]
wids = [wids[i] for i in idx]
return Hdf5Dataset.collect_fn(zip(imgs, lbs, wids))
@staticmethod
def merge_batch(batch1, batch2, device):
imgs1, img_lens1, lbs1, lb_lens1, wids1 = batch1
imgs2, img_lens2, lbs2, lb_lens2, wids2 = batch2
bz1, bz2 = imgs1.size(0), imgs2.size(0)
max_img_len = max(img_lens1.max(), img_lens2.max()).item()
pad_imgs = -torch.ones((bz1 + bz2, imgs1.size(1), imgs1.size(2), max_img_len)).float().to(device)
pad_imgs[:bz1, :, :, :imgs1.size(-1)] = imgs1
pad_imgs[bz1:, :, :, :imgs2.size(-1)] = imgs2
max_lb_len = max(lb_lens1.max(), lb_lens2.max()).item()
pad_lbs = torch.zeros((bz1 + bz2, max_lb_len)).long().to(device)
pad_lbs[:bz1, :lbs1.size(-1)] = lbs1
pad_lbs[bz1:, :lbs2.size(-1)] = lbs2
merge_img_lens = torch.cat([img_lens1, img_lens2]).to(device)
merge_lb_lens = torch.cat([lb_lens1, lb_lens2]).to(device)
merge_wids = torch.cat([wids1, wids2]).long().to(device)
return pad_imgs, merge_img_lens, pad_lbs, merge_lb_lens, merge_wids
def get_dataset(name, split):
tag = '_'.join(name.split('_')[:2])
alphabet_key = 'vnondb' if tag.startswith('vnondb') else 'all'
transforms = [ToTensor(), Normalize([0.5], [0.5])]
dataset = Hdf5Dataset(data_roots[tag],
data_paths[name][split],
transforms=Compose(transforms),
alphabet_key=alphabet_key)
return dataset
def get_collect_fn(sort_input=False):
if sort_input:
return Hdf5Dataset.sort_collect_fn
else:
return Hdf5Dataset.collect_fn
def get_max_image_width(dset):
max_image_width = 0
for img, _, _ in dset:
max_image_width = max(max_image_width, img.size(-1))
return max_image_width