Spaces:
Runtime error
Runtime error
File size: 3,864 Bytes
c61b6f3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
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_path,
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)
img = Image.open(img_path).convert('RGB')
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)
|