P-PD / utils /tools.py
mrneuralnet's picture
Initial commit
e875957
raw
history blame
3.67 kB
import os
import cv2
import torch
import numpy as np
from PIL import Image
from dlib import cnn_face_detection_model_v1 as face_detect_model
def center_crop(im, length):
w, h = im.size
left = w//2 - length//2
right = w//2 + length//2
top = h//2 - length//2
bottom = h//2 + length//2
return im.crop((left, top, right, bottom)), (left, top)
def remove_boundary(img):
"""
Remove boundary artifacts that FAL causes.
"""
w, h = img.size
left = w//80
top = h//50
right = w*79//80
bottom = h*24//25
return img.crop((left, top, right, bottom))
def resize_shorter_side(img, min_length):
"""
Resize the shorter side of img to min_length while
preserving the aspect ratio.
"""
ow, oh = img.size
mult = 8
if ow < oh:
if ow == min_length and oh % mult == 0:
return img, (ow, oh)
w = min_length
h = int(min_length * oh / ow)
else:
if oh == min_length and ow % mult == 0:
return img, (ow, oh)
h = min_length
w = int(min_length * ow / oh)
return img.resize((w, h), Image.BICUBIC), (w, h)
def flow_resize(flow, sz):
oh, ow, _ = flow.shape
w, h = sz
u_ = cv2.resize(flow[:,:,0], (w, h))
v_ = cv2.resize(flow[:,:,1], (w, h))
u_ *= w / float(ow)
v_ *= h / float(oh)
return np.dstack((u_,v_))
def warp(im, flow, alpha=1, interp=cv2.INTER_CUBIC):
height, width, _ = flow.shape
cart = np.dstack(np.meshgrid(np.arange(width), np.arange(height)))
pixel_map = (cart + alpha * flow).astype(np.float32)
warped = cv2.remap(
im,
pixel_map[:, :, 0],
pixel_map[:, :, 1],
interp,
borderMode=cv2.BORDER_REPLICATE)
return warped
cnn_face_detector = None
def face_detection(
img,
verbose=False,
model_file='utils/dlib_face_detector/mmod_human_face_detector.dat'):
"""
Detects faces using dlib cnn face detection, and extend the bounding box
to include the entire face.
"""
def shrink(img, max_length=2048):
ow, oh = img.size
if max_length >= max(ow, oh):
return img, 1.0
if ow > oh:
mult = max_length / ow
else:
mult = max_length / oh
w = int(ow * mult)
h = int(oh * mult)
return img.resize((w, h), Image.BILINEAR), mult
global cnn_face_detector
if cnn_face_detector is None:
cnn_face_detector = face_detect_model(model_file)
w, h = img.size
img_shrinked, mult = shrink(img)
im = np.asarray(img_shrinked)
if len(im.shape) != 3 or im.shape[2] != 3:
return []
crop_ims = []
dets = cnn_face_detector(im, 0)
for k, d in enumerate(dets):
top = d.rect.top() / mult
bottom = d.rect.bottom() / mult
left = d.rect.left() / mult
right = d.rect.right() / mult
wid = right - left
left = max(0, left - wid // 2.5)
top = max(0, top - wid // 1.5)
right = min(w - 1, right + wid // 2.5)
bottom = min(h - 1, bottom + wid // 2.5)
if d.confidence > 1:
if verbose:
print("%d-th face detected: (%d, %d, %d, %d)" %
(k, left, top, right, bottom))
crop_im = img.crop((left, top, right, bottom))
crop_ims.append((crop_im, (left, top, right, bottom)))
return crop_ims
def mkdirs(paths):
if isinstance(paths, list) and not isinstance(paths, str):
for path in paths:
mkdir(path)
else:
mkdir(paths)
def mkdir(path):
if not os.path.exists(path):
os.makedirs(path)