diff options
| author | adamhrv <adam@ahprojects.com> | 2018-12-05 12:00:15 +0100 |
|---|---|---|
| committer | adamhrv <adam@ahprojects.com> | 2018-12-05 12:00:15 +0100 |
| commit | 90abf459d1df1f21960c1d653a1f936d1ec30256 (patch) | |
| tree | facab8e9bac6c56e69c369c2140cdbea218a01df /megapixels/datasets/commands | |
| parent | 0529d4cd1618016319e995c37aa118bf8c2d501b (diff) | |
.
Diffstat (limited to 'megapixels/datasets/commands')
| -rw-r--r-- | megapixels/datasets/commands/crop.py | 104 | ||||
| -rw-r--r-- | megapixels/datasets/commands/extract.py | 86 | ||||
| -rw-r--r-- | megapixels/datasets/commands/face.py | 117 | ||||
| -rw-r--r-- | megapixels/datasets/commands/resize.py | 81 |
4 files changed, 0 insertions, 388 deletions
diff --git a/megapixels/datasets/commands/crop.py b/megapixels/datasets/commands/crop.py deleted file mode 100644 index 778be0c4..00000000 --- a/megapixels/datasets/commands/crop.py +++ /dev/null @@ -1,104 +0,0 @@ -""" -Crop images to prepare for training -""" - -import click -from PIL import Image, ImageOps, ImageFilter, ImageDraw - -from app.settings import types -from app.utils import click_utils -from app.settings import app_cfg as cfg - -@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_ext', - default='jpg', type=click.Choice(['jpg', 'png']), - help='File glob ext') -@click.option('--size', 'opt_size', - type=(int, int), default=(256, 256), - help='Output image size') -@click.option('-t', '--crop-type', 'opt_crop_type', - default='center', type=click.Choice(['center', 'mirror', 'face', 'person', 'none']), - help='Force fit image center location') -@click.pass_context -def cli(ctx, opt_dir_in, opt_dir_out, opt_ext, opt_size, opt_crop_type): - """Crop, mirror images""" - - import os - from os.path import join - from pathlib import Path - from glob import glob - from tqdm import tqdm - - - from app.utils import logger_utils, file_utils, im_utils - - # ------------------------------------------------- - # process here - - log = logger_utils.Logger.getLogger() - log.info('crop images') - - # get list of files to process - fp_ims = glob(join(opt_dir_in, '*.{}'.format(opt_ext))) - log.debug('files: {}'.format(len(fp_ims))) - - # ensure output dir exists - file_utils.mkdirs(opt_dir_out) - - for fp_im in tqdm(fp_ims): - im = process_crop(fp_im, opt_size, opt_crop_type) - fp_out = join(opt_dir_out, Path(fp_im).name) - im.save(fp_out) - - -def process_crop(fp_im, opt_size, crop_type): - im = Image.open(fp_im) - if crop_type == 'center': - im = crop_square_fit(im, opt_size) - elif crop_type == 'mirror': - im = mirror_crop_square(im, opt_size) - return im - -def crop_square_fit(im, size, center=(0.5, 0.5)): - return ImageOps.fit(im, size, method=Image.BICUBIC, centering=center) - -def mirror_crop_square(im, size): - # force to even dims - if im.size[0] % 2 or im.size[1] % 2: - im = ImageOps.fit(im, ((im.size[0] // 2) * 2, (im.size[1] // 2) * 2)) - - # create new square image - min_size, max_size = (min(im.size), max(im.size)) - orig_w, orig_h = im.size - margin = (max_size - min_size) // 2 - w, h = (max_size, max_size) - im_new = Image.new('RGB', (w, h), color=(0, 0, 0)) - - #crop (l, t, r, b) - if orig_w > orig_h: - # landscape, mirror expand T/B - im_top = ImageOps.mirror(im.crop((0, 0, margin, w))) - im_bot = ImageOps.mirror(im.crop((orig_h - margin, 0, orig_h, w))) - im_new.paste(im_top, (0, 0)) - im_new.paste(im, (margin, 0, orig_h + margin, w)) - im_new.paste(im_bot, (h - margin, 0)) - elif orig_h > orig_w: - # portrait, mirror expand L/R - im_left = ImageOps.mirror(im.crop((0, 0, margin, h))) - im_right = ImageOps.mirror(im.crop((orig_w - margin, 0, orig_w, h))) - im_new.paste(im_left, (0, 0)) - im_new.paste(im, (margin, 0, orig_w + margin, h)) - im_new.paste(im_right, (w - margin, 0)) - - return im_new.resize(size) - - -def center_crop_face(): - pass - -def center_crop_person(): - pass
\ No newline at end of file diff --git a/megapixels/datasets/commands/extract.py b/megapixels/datasets/commands/extract.py deleted file mode 100644 index 4e77a978..00000000 --- a/megapixels/datasets/commands/extract.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -Crop images to prepare for training -""" - -import click - -from app.settings import types -from app.utils import click_utils -from app.settings import app_cfg as cfg - -@click.command() -@click.option('-i', '--input', 'opt_fp_in', required=True, - help='Input CSV') -@click.option('--media', 'opt_dir_media', required=True, - help='Input image/video directory') -@click.option('-o', '--output', 'opt_dir_out', required=True, - help='Output directory for extracted ROI images') -@click.option('--size', 'opt_size', - type=(int, int), default=(300, 300), - help='Output image size') -@click.option('--slice', 'opt_slice', type=(int, int), default=(None, None), - help='Slice list of files') -@click.option('--padding', 'opt_padding', default=0, - help='Facial padding') -@click.option('--ext', 'opt_ext_out', default='jpg', type=click.Choice(['jpg', 'png']), - help='Output image type') -@click.pass_context -def cli(ctx, opt_fp_in, opt_dir_media, opt_dir_out, opt_size, opt_slice, - opt_padding, opt_ext_out): - """Extrace ROIs to images""" - - import os - from os.path import join - from pathlib import Path - from glob import glob - - from tqdm import tqdm - import numpy as np - from PIL import Image, ImageOps, ImageFilter, ImageDraw - import cv2 as cv - import pandas as pd - - from app.utils import logger_utils, file_utils, im_utils - from app.models.bbox import BBox - # ------------------------------------------------- - # process here - log = logger_utils.Logger.getLogger() - - df_rois = pd.read_csv(opt_fp_in) - if opt_slice: - df_rois = df_rois[opt_slice[0]:opt_slice[1]] - - log.info('Processing {:,} rows'.format(len(df_rois))) - - file_utils.mkdirs(opt_dir_out) - - df_rois_grouped = df_rois.groupby(['fn']) # group by fn/filename - groups = df_rois_grouped.groups - - for group in groups: - - # get image - group_rows = df_rois_grouped.get_group(group) - - row = group_rows.iloc[0] - fp_im = join(opt_dir_media, '{fn}{ext}'.format(**row)) #TODO change to ext - im = Image.open(fp_im) - - - for idx, roi in group_rows.iterrows(): - log.info('{}'.format(roi['fn'])) - # get bbox to im dimensions - xywh = [roi['x'], roi['y'], roi['w'] , roi['h']] - bbox = BBox.from_xywh(*xywh) - dim = im.size - bbox_dim = bbox.to_dim(dim) - # expand - bbox_dim_exp = bbox_dim.expand_dim(opt_padding, dim) - # crop - x1y2 = bbox_dim_exp.pt_tl + bbox_dim_exp.pt_br - im_crop = im.crop(box=x1y2) - # save - idx_zpad = file_utils.zpad(idx, zeros=3) - fp_im_out = join(opt_dir_out, '{}_{}.{}'.format(roi['fn'], idx_zpad, opt_ext_out)) - im_crop.save(fp_im_out) - diff --git a/megapixels/datasets/commands/face.py b/megapixels/datasets/commands/face.py deleted file mode 100644 index 6b7b18b7..00000000 --- a/megapixels/datasets/commands/face.py +++ /dev/null @@ -1,117 +0,0 @@ -""" -Crop images to prepare for training -""" - -import click -# from PIL import Image, ImageOps, ImageFilter, ImageDraw - -from app.settings import types -from app.utils import click_utils -from app.settings import app_cfg as cfg - -@click.command() -@click.option('-i', '--input', 'opt_dir_in', required=True, - help='Input directory') -@click.option('-o', '--output', 'opt_fp_out', required=True, - help='Output CSV') -@click.option('-e', '--ext', 'opt_ext', - default='jpg', type=click.Choice(['jpg', 'png']), - help='File glob ext') -@click.option('--size', 'opt_size', - type=(int, int), default=(300, 300), - help='Output image size') -@click.option('-t', '--detector-type', 'opt_detector_type', - type=cfg.FaceDetectNetVar, - default=click_utils.get_default(types.FaceDetectNet.DLIB_CNN), - help=click_utils.show_help(types.FaceDetectNet)) -@click.option('-g', '--gpu', 'opt_gpu', default=0, - help='GPU index') -@click.option('--conf', 'opt_conf_thresh', default=0.85, type=click.FloatRange(0,1), - help='Confidence minimum threshold') -@click.option('--pyramids', 'opt_pyramids', default=0, type=click.IntRange(0,4), - help='Number pyramids to upscale for DLIB detectors') -@click.option('--slice', 'opt_slice', type=(int, int), default=(None, None), - help='Slice list of files') -@click.option('--display/--no-display', 'opt_display', is_flag=True, default=False, - help='Display detections to debug') -@click.pass_context -def cli(ctx, opt_dir_in, opt_fp_out, opt_ext, opt_size, opt_detector_type, - opt_gpu, opt_conf_thresh, opt_pyramids, opt_slice, opt_display): - """Extrace face""" - - import sys - import os - from os.path import join - from pathlib import Path - from glob import glob - from tqdm import tqdm - import numpy as np - import dlib # must keep a local reference for dlib - import cv2 as cv - import pandas as pd - - from app.utils import logger_utils, file_utils, im_utils - from app.processors import face_detector - - # ------------------------------------------------- - # init here - - log = logger_utils.Logger.getLogger() - - if opt_detector_type == types.FaceDetectNet.CVDNN: - detector = face_detector.DetectorCVDNN() - elif opt_detector_type == types.FaceDetectNet.DLIB_CNN: - detector = face_detector.DetectorDLIBCNN(opt_gpu) - elif opt_detector_type == types.FaceDetectNet.DLIB_HOG: - detector = face_detector.DetectorDLIBHOG() - elif opt_detector_type == types.FaceDetectNet.HAAR: - log.error('{} not yet implemented'.format(opt_detector_type.name)) - return - - - # ------------------------------------------------- - # process here - - # get list of files to process - fp_ims = glob(join(opt_dir_in, '*.{}'.format(opt_ext))) - if opt_slice: - fp_ims = fp_ims[opt_slice[0]:opt_slice[1]] - log.debug('processing {:,} files'.format(len(fp_ims))) - - - data = [] - - for fp_im in tqdm(fp_ims): - im = cv.imread(fp_im) - bboxes = detector.detect(im, opt_size=opt_size, opt_pyramids=opt_pyramids) - fpp_im = Path(fp_im) - for bbox in bboxes: - roi = { - 'fn': fpp_im.stem, - 'ext': fpp_im.suffix, - 'x': bbox.x, - 'y': bbox.y, - 'w': bbox.w, - 'h': bbox.h} - dim = bbox.to_dim(im.shape[:2][::-1]) # w,h - data.append(roi) - - # debug display - if opt_display and len(bboxes): - im_md = im_utils.resize(im, width=opt_size[0]) - for bbox in bboxes: - dim = bbox.to_dim(im_md.shape[:2][::-1]) - cv.rectangle(im_md, dim.pt_tl, dim.pt_br, (0,255,0), 3) - cv.imshow('', im_md) - while True: - k = cv.waitKey(1) & 0xFF - if k == 27 or k == ord('q'): # ESC - cv.destroyAllWindows() - sys.exit() - elif k != 255: - # any key to continue - break - - # save date - df = pd.DataFrame.from_dict(data) - df.to_csv(opt_fp_out)
\ No newline at end of file diff --git a/megapixels/datasets/commands/resize.py b/megapixels/datasets/commands/resize.py deleted file mode 100644 index 5e2d31aa..00000000 --- a/megapixels/datasets/commands/resize.py +++ /dev/null @@ -1,81 +0,0 @@ -""" -Crop images to prepare for training -""" - -import click - -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 ⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐ -""" - -@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='jpg', type=click.Choice(['jpg', 'png']), - help='File glob ext') -@click.option('--size', 'opt_size', - type=(int, int), default=(256, 256), - help='Output image size (square)') -@click.option('--method', 'opt_scale_method', - type=click.Choice(['LANCZOS', 'BICUBIC', 'HAMMING', 'BILINEAR', 'BOX', 'NEAREST']), - default='LANCZOS', - help='Scaling method to use') -@click.pass_context -def cli(ctx, opt_dir_in, opt_dir_out, opt_glob_ext, opt_size, opt_scale_method): - """Crop, mirror images""" - - import os - from os.path import join - from pathlib import Path - from glob import glob - from tqdm import tqdm - from PIL import Image, ImageOps, ImageFilter - from app.utils import logger_utils, file_utils, im_utils - - # ------------------------------------------------- - # init - - log = logger_utils.Logger.getLogger() - - methods = { - 'LANCZOS': Image.LANCZOS, - 'BICUBIC': Image.BICUBIC, - 'HAMMING': Image.HAMMING, - 'BILINEAR': Image.BILINEAR, - 'BOX': Image.BOX, - 'NEAREST': Image.NEAREST - } - - # ------------------------------------------------- - # process here - - # get list of files to process - fp_ims = glob(join(opt_dir_in, '*.{}'.format(opt_glob_ext))) - log.info('processing {:,} files'.format(len(fp_ims))) - - # set scale method - scale_method = methods[opt_scale_method] - - # ensure output dir exists - file_utils.mkdirs(opt_dir_out) - - # resize and save images - for fp_im in tqdm(fp_ims): - im = Image.open(fp_im) - im = ImageOps.fit(im, opt_size, method=scale_method, centering=(0.5, 0.5)) - fp_out = join(opt_dir_out, Path(fp_im).name) - im.save(fp_out) - |
