Download lib/datasets.py from DAIR-Group/SpiS-GAN: direct link, hf CLI and curl.
- Browser
- Download file 5.12 kB
-
https://huggingface.co/DAIR-Group/SpiS-GAN/resolve/main/lib/datasets.py
- Command line
-
hf download hf://DAIR-Group/SpiS-GAN/lib/datasets.py
-
curl -L -o datasets.py https://huggingface.co/DAIR-Group/SpiS-GAN/resolve/main/lib/datasets.py
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) | |
| 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 | |
| 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)) | |
| 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 |