summaryrefslogtreecommitdiff
path: root/megapixels/commands/cv/csv_to_faces.py
diff options
context:
space:
mode:
Diffstat (limited to 'megapixels/commands/cv/csv_to_faces.py')
-rw-r--r--megapixels/commands/cv/csv_to_faces.py105
1 files changed, 0 insertions, 105 deletions
diff --git a/megapixels/commands/cv/csv_to_faces.py b/megapixels/commands/cv/csv_to_faces.py
deleted file mode 100644
index 64c8b965..00000000
--- a/megapixels/commands/cv/csv_to_faces.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-Reads in CSV of ROIs and extracts facial regions with padding
-"""
-
-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('-m', '--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('--slice', 'opt_slice', type=(int, int), default=(None, None),
- help='Slice list of files')
-@click.option('--padding', 'opt_padding', default=0.25,
- help='Facial padding as percentage of face width')
-@click.option('--ext', 'opt_ext_out', default='png', type=click.Choice(['jpg', 'png']),
- help='Output image type')
-@click.option('--min', 'opt_min', default=(60, 60),
- help='Minimum original face size')
-@click.pass_context
-def cli(ctx, opt_fp_in, opt_dir_media, opt_dir_out, opt_slice,
- opt_padding, opt_ext_out, opt_min):
- """Converts 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, dtype={'subdir': str, 'fn': str})
- 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
- skipped = []
-
- for group in tqdm(groups):
- # get image
- group_rows = df_rois_grouped.get_group(group)
-
- row = group_rows.iloc[0]
- fp_im = join(opt_dir_media, str(row['subdir']), '{fn}.{ext}'.format(**row)) # TODO change to ext
- 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)
- continue
-
- for idx, roi in group_rows.iterrows():
- # 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
- opt_padding_px = int(opt_padding * bbox_dim.width)
- bbox_dim_exp = bbox_dim.expand_dim(opt_padding_px, dim)
- # crop
- x1y2 = bbox_dim_exp.pt_tl + bbox_dim_exp.pt_br
- im_crop = im.crop(box=x1y2)
-
- # strip exif, create new image and paste data
- im_crop_data = list(im_crop.getdata())
- im_crop_no_exif = Image.new(im_crop.mode, im_crop.size)
- im_crop_no_exif.putdata(im_crop_data)
-
- # save
- idx_zpad = file_utils.zpad(idx, zeros=3)
- subdir = '' if roi['subdir'] == '.' else '{}_'.format(roi['subdir'])
- subdir = subdir.replace('/', '_')
- fp_im_out = join(opt_dir_out, '{}{}{}.{}'.format(subdir, roi['fn'], idx_zpad, opt_ext_out))
- # threshold size and save
- if im_crop_no_exif.size[0] < opt_min[0] or im_crop_no_exif.size[1] < opt_min[1]:
- skipped.append(fp_im_out)
- log.info('Face too small: {}, idx: {}'.format(fp_im, idx))
- else:
- im_crop_no_exif.save(fp_im_out)
-
- log.info('Skipped {:,} images'.format(len(skipped)))