diff options
Diffstat (limited to 'megapixels/commands/processor/resize.py')
| -rw-r--r-- | megapixels/commands/processor/resize.py | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/megapixels/commands/processor/resize.py b/megapixels/commands/processor/resize.py new file mode 100644 index 00000000..7409ee6f --- /dev/null +++ b/megapixels/commands/processor/resize.py @@ -0,0 +1,150 @@ +""" +Crop images to prepare for training +""" + +import click +import cv2 as cv +from PIL import Image, ImageOps, ImageFilter + +from app.settings import types +from app.utils import click_utils +from app.settings import app_cfg as cfg + +""" +Filter Q-Down Q-Up Speed +NEAREST ⭐⭐⭐⭐⭐ +BOX ⭐ ⭐⭐⭐⭐ +BILINEAR ⭐ ⭐ ⭐⭐⭐ +HAMMING ⭐⭐ ⭐⭐⭐ +BICUBIC ⭐⭐⭐ ⭐⭐⭐ ⭐⭐ +LANCZOS ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐ +""" +methods = { + 'lanczos': Image.LANCZOS, + 'bicubic': Image.BICUBIC, + 'hamming': Image.HAMMING, + 'bileaner': Image.BILINEAR, + 'box': Image.BOX, + 'nearest': Image.NEAREST + } +centerings = { + 'tl': (0.0, 0.0), + 'tc': (0.5, 0.0), + 'tr': (0.0, 0.0), + 'lc': (0.0, 0.5), + 'cc': (0.5, 0.5), + 'rc': (1.0, 0.5), + 'bl': (0.0, 1.0), + 'bc': (1.0, 0.5), + 'br': (1.0, 1.0) +} + +@click.command() +@click.option('-i', '--input', 'opt_dir_in', required=True, + help='Input directory') +@click.option('-o', '--output', 'opt_dir_out', required=True, + help='Output directory') +@click.option('-e', '--ext', 'opt_glob_ext', + default='png', type=click.Choice(['jpg', 'png']), + help='File glob ext') +@click.option('--size', 'opt_size', + type=(int, int), default=(256, 256), + help='Max output size') +@click.option('--method', 'opt_scale_method', + type=click.Choice(methods.keys()), + default='lanczos', + help='Scaling method to use') +@click.option('--equalize', 'opt_equalize', is_flag=True, + help='Equalize historgram') +@click.option('--sharpen', 'opt_sharpen', is_flag=True, + help='Unsharp mask') +@click.option('--center', 'opt_center', default='cc', type=click.Choice(centerings.keys()), + help='Crop focal point') +@click.option('--slice', 'opt_slice', type=(int, int), default=(None, None), + help='Slice the input list') +@click.option('-t', '--threads', 'opt_threads', default=8, + help='Number of threads') +@click.pass_context +def cli(ctx, opt_dir_in, opt_dir_out, opt_glob_ext, opt_size, opt_scale_method, + opt_equalize, opt_sharpen, opt_center, opt_slice, opt_threads): + """Crop, mirror images""" + + import os + from os.path import join + from pathlib import Path + from glob import glob + from tqdm import tqdm + from multiprocessing.dummy import Pool as ThreadPool + from functools import partial + + from app.utils import logger_utils, file_utils, im_utils + + # ------------------------------------------------- + # init + + log = logger_utils.Logger.getLogger() + + + # ------------------------------------------------- + # process here + + def pool_resize(fp_im, opt_size, scale_method): + # Threaded image resize function + try: + pbar.update(1) + try: + im = Image.open(fp_im).convert('RGB') + im.verify() + except Exception as e: + log.warn('Could not open: {}'.format(fp_im)) + log.error(e) + return False + + #im = ImageOps.fit(im, opt_size, method=scale_method, centering=centering) + + if opt_equalize: + im_np = im_utils.pil2np(im) + im_np_eq = eq_hist_yuv(im_np) + im_np = cv.addWeighted(im_np_eq, 0.35, im_np, 0.65, 0) + im = im_utils.np2pil(im_np) + + if opt_sharpen: + im = im.filter(ImageFilter.UnsharpMask) + + fp_out = join(opt_dir_out, Path(fp_im).name) + im.save(fp_out) + return True + except: + return False + + #centering = centerings[opt_center] + #scale_method = methods[opt_scale_method] + + # get list of files to process + fp_ims = glob(join(opt_dir_in, '*.{}'.format(opt_glob_ext))) + if opt_slice: + fp_ims = fp_ims[opt_slice[0]:opt_slice[1]] + log.info('processing {:,} files'.format(len(fp_ims))) + + + # ensure output dir exists + file_utils.mkdirs(opt_dir_out) + + # setup multithreading + pbar = tqdm(total=len(fp_ims)) + #pool_resize = partial(pool_resize, opt_size=opt_size, scale_method=scale_method, centering=centering) + pool_resize = partial(pool_resize, opt_size=opt_size) + #result_list = pool.map(prod_x, data_list) + pool = ThreadPool(opt_threads) + with tqdm(total=len(fp_ims)) as pbar: + results = pool.map(pool_resize, fp_ims) + pbar.close() + + log.info('Resized: {} / {} images'.format(results.count(True), len(fp_ims))) + + + +def eq_hist_yuv(im): + im_yuv = cv.cvtColor(im, cv.COLOR_BGR2YUV) + im_yuv[:,:,0] = cv.equalizeHist(im_yuv[:,:,0]) + return cv.cvtColor(im_yuv, cv.COLOR_YUV2BGR) |
