summaryrefslogtreecommitdiff
path: root/megapixels/commands/cv/face_frames.py
diff options
context:
space:
mode:
Diffstat (limited to 'megapixels/commands/cv/face_frames.py')
-rw-r--r--megapixels/commands/cv/face_frames.py82
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]