diff options
Diffstat (limited to 'megapixels/commands/cv/face_frames.py')
| -rw-r--r-- | megapixels/commands/cv/face_frames.py | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/megapixels/commands/cv/face_frames.py b/megapixels/commands/cv/face_frames.py new file mode 100644 index 00000000..76f23af1 --- /dev/null +++ b/megapixels/commands/cv/face_frames.py @@ -0,0 +1,82 @@ +from glob import glob +import os +from os.path import join +from pathlib import Path + +import click + + + + +@click.command() +@click.option('-i', '--input', 'opt_fp_in', required=True, + help='Input directory to glob') +@click.option('-o', '--output', 'opt_fp_out', required=True, + help='Output directory for face frames') +@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.pass_context +def cli(ctx, opt_fp_in, opt_fp_out, opt_size, opt_slice): + """Split video to face frames""" + + from tqdm import tqdm + import dlib + import pandas as pd + from PIL import Image, ImageOps, ImageFilter + import cv2 as cv + import numpy as np + + from app.processors import face_detector + from app.utils import logger_utils, file_utils, im_utils + from app.settings import types + from app.utils import click_utils + from app.settings import app_cfg as cfg + from app.models.bbox import BBox + + log = logger_utils.Logger.getLogger() + + # ------------------------------------------------- + # process + + detector = face_detector.DetectorDLIBCNN() + + # get file list + fp_videos = glob(join(opt_fp_in, '*.mp4')) + fp_videos += glob(join(opt_fp_in, '*.webm')) + fp_videos += glob(join(opt_fp_in, '*.mkv')) + + min_distance_per = .025 # minimum distance percentage to save new face image + face_interval = 5 + frame_interval_count = 0 + frame_count = 0 + bbox_prev = BBox(0,0,0,0) + file_utils.mkdirs(opt_fp_out) + dnn_size = opt_size + max_dim = max(dnn_size) + px_thresh = int(max_dim * min_distance_per) + + for fp_video in tqdm(fp_videos): + # load video + video = cv.VideoCapture(fp_video) + # iterate through frames + while video.isOpened(): + res, frame = video.read() + if not res: + break + # increment frames, save frame if interval has passed + frame_count += 1 # for naming + frame_interval_count += 1 # for interval + bboxes = detector.detect(frame, opt_size=dnn_size, opt_pyramids=0) + if len(bboxes) > 0 and frame_interval_count >= face_interval: + dim = frame.shape[:2][::-1] + d = bboxes[0].to_dim(dim).distance(bbox_prev) + if d > px_thresh: + # save frame + zfc = file_utils.zpad(frame_count) + fp_frame = join(opt_fp_out, '{}_{}.jpg'.format(Path(fp_video).stem, zfc)) + cv.imwrite(fp_frame, frame) + frame_interval_count = 0 + bbox_prev = bboxes[0] |
