Download upstream/dataset/dataset.py from Yanmou/DoU: direct link, hf CLI and curl.
- Browser
- Download file 5.24 kB
-
https://huggingface.co/Yanmou/DoU/resolve/main/upstream/dataset/dataset.py
- Command line
-
hf download hf://Yanmou/DoU/upstream/dataset/dataset.py
-
curl -L -o dataset.py https://huggingface.co/Yanmou/DoU/resolve/main/upstream/dataset/dataset.py
5.24 kB
| from torch.utils.data import Dataset, DataLoader | |
| from torchvision.datasets import ImageFolder | |
| from PIL import Image | |
| import csv | |
| import math | |
| import torchvision.transforms as transforms | |
| from torchvision.transforms import functional as TF | |
| import numpy as np | |
| from random import random, choice, shuffle | |
| import cv2 | |
| from scipy.ndimage.filters import gaussian_filter | |
| from io import BytesIO | |
| # ============== Dataset ============== | |
| class ImageDataset(Dataset): | |
| """ | |
| CSV format: two columns -> path, label | |
| """ | |
| def __init__(self, csv_path: str, is_train=False, opt=None): | |
| self.items = [] | |
| self.is_train = is_train | |
| self.opt = opt | |
| with open(csv_path, "r", newline="", encoding="utf-8") as f: | |
| reader = csv.DictReader(f) | |
| assert "path" in reader.fieldnames and "label" in reader.fieldnames, \ | |
| f"{csv_path} must contain columns: path,label" | |
| for r in reader: | |
| path = r["path"] | |
| label = int(r["label"]) | |
| self.items.append((path, label)) | |
| if is_train: | |
| self.preprocess = transforms.Compose([ | |
| transforms.Lambda(lambda img: translate_duplicate(img, 224)), | |
| transforms.Lambda(lambda img: data_augment(img, opt)), | |
| transforms.RandomCrop(224), | |
| transforms.RandomHorizontalFlip(), | |
| transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.48145466, 0.4578275, 0.40821073], | |
| std=[0.26862954, 0.26130258, 0.27577711]), | |
| ]) | |
| else: | |
| self.preprocess = transforms.Compose([ | |
| transforms.Lambda(lambda img: translate_duplicate(img, 224)), | |
| transforms.CenterCrop(224), | |
| transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.48145466, 0.4578275, 0.40821073], | |
| std=[0.26862954, 0.26130258, 0.27577711]), | |
| ]) | |
| def __len__(self): | |
| return len(self.items) | |
| def __getitem__(self, idx): | |
| path, label = self.items[idx] | |
| rgb = Image.open(path).convert("RGB") | |
| rgb = self.preprocess(rgb) | |
| return rgb, label | |
| class ImageFolderWithPaths(ImageFolder): | |
| def __init__(self, root, transform=None): | |
| super().__init__(root) | |
| self.original_samples = self.samples | |
| self.transform = transform if transform is not None else transforms.Compose([ | |
| transforms.Lambda(lambda img: translate_duplicate(img, 224)), | |
| transforms.CenterCrop(224), | |
| transforms.ToTensor(), | |
| transforms.Normalize(mean=[0.48145466, 0.4578275, 0.40821073], | |
| std=[0.26862954, 0.26130258, 0.27577711]), | |
| ]) | |
| def __getitem__(self, item): | |
| path, target = self.samples[item] | |
| target = 0 if '0_real' in path else 1 | |
| img = self.loader(path) | |
| img = self.transform(img) | |
| return img, target | |
| def __len__(self): | |
| return len(self.samples) | |
| def translate_duplicate(img, cropSize): | |
| if min(img.size) < cropSize: | |
| width, height = img.size | |
| new_width = width * math.ceil(cropSize / width) | |
| new_height = height * math.ceil(cropSize / height) | |
| new_img = Image.new(img.mode, (new_width, new_height)) | |
| for i in range(0, new_width, width): | |
| for j in range(0, new_height, height): | |
| new_img.paste(img, (i, j)) | |
| return new_img | |
| else: | |
| return img | |
| def data_augment(img, opt): | |
| img = np.array(img) | |
| if img.ndim == 2: | |
| img = np.expand_dims(img, axis=2) | |
| img = np.repeat(img, 3, axis=2) | |
| if random() < opt.blur_prob: | |
| sig = sample_continuous(opt.blur_sig) | |
| gaussian_blur(img, sig) | |
| if random() < opt.jpg_prob: | |
| method = sample_discrete(opt.jpg_method) | |
| qual = sample_discrete(opt.jpg_qual) | |
| img = jpeg_from_key(img, qual, method) | |
| return Image.fromarray(img) | |
| def sample_continuous(s): | |
| if len(s) == 1: | |
| return s[0] | |
| if len(s) == 2: | |
| rg = s[1] - s[0] | |
| return random() * rg + s[0] | |
| raise ValueError("Length of iterable s should be 1 or 2.") | |
| def sample_discrete(s): | |
| if len(s) == 1: | |
| return s[0] | |
| return choice(s) | |
| def gaussian_blur(img, sigma): | |
| gaussian_filter(img[:, :, 0], output=img[:, :, 0], sigma=sigma) | |
| gaussian_filter(img[:, :, 1], output=img[:, :, 1], sigma=sigma) | |
| gaussian_filter(img[:, :, 2], output=img[:, :, 2], sigma=sigma) | |
| def cv2_jpg(img, compress_val): | |
| img_cv2 = img[:, :, ::-1] | |
| encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), compress_val] | |
| result, encimg = cv2.imencode('.jpg', img_cv2, encode_param) | |
| decimg = cv2.imdecode(encimg, 1) | |
| return decimg[:, :, ::-1] | |
| def pil_jpg(img, compress_val): | |
| out = BytesIO() | |
| img = Image.fromarray(img) | |
| img.save(out, format='jpeg', quality=compress_val) | |
| img = Image.open(out) | |
| # Load from memory before BytesIO is closed | |
| img = np.array(img) | |
| out.close() | |
| return img | |
| jpeg_dict = {'cv2': cv2_jpg, 'pil': pil_jpg} | |
| def jpeg_from_key(img, compress_val, key): | |
| method = jpeg_dict[key] | |
| return method(img, compress_val) | |