Real-ESRGAN
135 строк · 4.9 Кб
1import argparse2import cv23import numpy as np4import os5import sys6from basicsr.utils import scandir7from multiprocessing import Pool8from os import path as osp9from tqdm import tqdm10
11
12def main(args):13"""A multi-thread tool to crop large images to sub-images for faster IO.14
15opt (dict): Configuration dict. It contains:
16n_thread (int): Thread number.
17compression_level (int): CV_IMWRITE_PNG_COMPRESSION from 0 to 9. A higher value means a smaller size
18and longer compression time. Use 0 for faster CPU decompression. Default: 3, same in cv2.
19input_folder (str): Path to the input folder.
20save_folder (str): Path to save folder.
21crop_size (int): Crop size.
22step (int): Step for overlapped sliding window.
23thresh_size (int): Threshold size. Patches whose size is lower than thresh_size will be dropped.
24
25Usage:
26For each folder, run this script.
27Typically, there are GT folder and LQ folder to be processed for DIV2K dataset.
28After process, each sub_folder should have the same number of subimages.
29Remember to modify opt configurations according to your settings.
30"""
31
32opt = {}33opt['n_thread'] = args.n_thread34opt['compression_level'] = args.compression_level35opt['input_folder'] = args.input36opt['save_folder'] = args.output37opt['crop_size'] = args.crop_size38opt['step'] = args.step39opt['thresh_size'] = args.thresh_size40extract_subimages(opt)41
42
43def extract_subimages(opt):44"""Crop images to subimages.45
46Args:
47opt (dict): Configuration dict. It contains:
48input_folder (str): Path to the input folder.
49save_folder (str): Path to save folder.
50n_thread (int): Thread number.
51"""
52input_folder = opt['input_folder']53save_folder = opt['save_folder']54if not osp.exists(save_folder):55os.makedirs(save_folder)56print(f'mkdir {save_folder} ...')57else:58print(f'Folder {save_folder} already exists. Exit.')59sys.exit(1)60
61# scan all images62img_list = list(scandir(input_folder, full_path=True))63
64pbar = tqdm(total=len(img_list), unit='image', desc='Extract')65pool = Pool(opt['n_thread'])66for path in img_list:67pool.apply_async(worker, args=(path, opt), callback=lambda arg: pbar.update(1))68pool.close()69pool.join()70pbar.close()71print('All processes done.')72
73
74def worker(path, opt):75"""Worker for each process.76
77Args:
78path (str): Image path.
79opt (dict): Configuration dict. It contains:
80crop_size (int): Crop size.
81step (int): Step for overlapped sliding window.
82thresh_size (int): Threshold size. Patches whose size is lower than thresh_size will be dropped.
83save_folder (str): Path to save folder.
84compression_level (int): for cv2.IMWRITE_PNG_COMPRESSION.
85
86Returns:
87process_info (str): Process information displayed in progress bar.
88"""
89crop_size = opt['crop_size']90step = opt['step']91thresh_size = opt['thresh_size']92img_name, extension = osp.splitext(osp.basename(path))93
94# remove the x2, x3, x4 and x8 in the filename for DIV2K95img_name = img_name.replace('x2', '').replace('x3', '').replace('x4', '').replace('x8', '')96
97img = cv2.imread(path, cv2.IMREAD_UNCHANGED)98
99h, w = img.shape[0:2]100h_space = np.arange(0, h - crop_size + 1, step)101if h - (h_space[-1] + crop_size) > thresh_size:102h_space = np.append(h_space, h - crop_size)103w_space = np.arange(0, w - crop_size + 1, step)104if w - (w_space[-1] + crop_size) > thresh_size:105w_space = np.append(w_space, w - crop_size)106
107index = 0108for x in h_space:109for y in w_space:110index += 1111cropped_img = img[x:x + crop_size, y:y + crop_size, ...]112cropped_img = np.ascontiguousarray(cropped_img)113cv2.imwrite(114osp.join(opt['save_folder'], f'{img_name}_s{index:03d}{extension}'), cropped_img,115[cv2.IMWRITE_PNG_COMPRESSION, opt['compression_level']])116process_info = f'Processing {img_name} ...'117return process_info118
119
120if __name__ == '__main__':121parser = argparse.ArgumentParser()122parser.add_argument('--input', type=str, default='datasets/DF2K/DF2K_HR', help='Input folder')123parser.add_argument('--output', type=str, default='datasets/DF2K/DF2K_HR_sub', help='Output folder')124parser.add_argument('--crop_size', type=int, default=480, help='Crop size')125parser.add_argument('--step', type=int, default=240, help='Step for overlapped sliding window')126parser.add_argument(127'--thresh_size',128type=int,129default=0,130help='Threshold size. Patches whose size is lower than thresh_size will be dropped.')131parser.add_argument('--n_thread', type=int, default=20, help='Thread number.')132parser.add_argument('--compression_level', type=int, default=3, help='Compression level')133args = parser.parse_args()134
135main(args)136