Spaces:
Running
Running
import numpy as np | |
import cv2 | |
from PIL import Image | |
# from TDDFA_V2.FaceBoxes import FaceBoxes | |
# from TDDFA_V2.TDDFA import TDDFA | |
def get_5_from_98(lmk): | |
lefteye = (lmk[60] + lmk[64] + lmk[96]) / 3 # lmk[96] | |
righteye = (lmk[68] + lmk[72] + lmk[97]) / 3 # lmk[97] | |
nose = lmk[54] | |
leftmouth = lmk[76] | |
rightmouth = lmk[82] | |
return np.array([lefteye, righteye, nose, leftmouth, rightmouth]) | |
def get_center(points): | |
x = [p[0] for p in points] | |
y = [p[1] for p in points] | |
centroid = (sum(x) / len(points), sum(y) / len(points)) | |
return np.array([centroid]) | |
def get_lmk(img, tddfa, face_boxes): | |
# 仅接受一个人的图像 | |
boxes = face_boxes(img) | |
n = len(boxes) | |
if n < 1: | |
return None | |
param_lst, roi_box_lst = tddfa(img, boxes) | |
ver_lst = tddfa.recon_vers(param_lst, roi_box_lst, dense_flag=False) | |
x = ver_lst[0].transpose(1, 0)[..., :2] | |
left_eye = get_center(x[36:42]) | |
right_eye = get_center(x[42:48]) | |
nose = x[30:31] | |
left_mouth = x[48:49] | |
right_mouth = x[54:55] | |
x = np.concatenate([left_eye, right_eye, nose, left_mouth, right_mouth], axis=0) | |
return x | |
def get_landmark_once(img, gpu_mode=False): | |
tddfa = TDDFA( | |
gpu_mode=gpu_mode, | |
arch="resnet", | |
checkpoint_fp="./TDDFA_V2/weights/resnet22.pth", | |
bfm_fp="TDDFA_V2/configs/bfm_noneck_v3.pkl", | |
size=120, | |
num_params=62, | |
) | |
face_boxes = FaceBoxes() | |
boxes = face_boxes(img) | |
n = len(boxes) | |
if n < 1: | |
return None | |
param_lst, roi_box_lst = tddfa(img, boxes) | |
ver_lst = tddfa.recon_vers(param_lst, roi_box_lst, dense_flag=False) | |
x = ver_lst[0].transpose(1, 0)[..., :2] | |
left_eye = get_center(x[36:42]) | |
right_eye = get_center(x[42:48]) | |
nose = x[30:31] | |
left_mouth = x[48:49] | |
right_mouth = x[54:55] | |
x = np.concatenate([left_eye, right_eye, nose, left_mouth, right_mouth], axis=0) | |
return x | |
def get_detector(gpu_mode=False): | |
tddfa = TDDFA( | |
gpu_mode=gpu_mode, | |
arch="resnet", | |
checkpoint_fp="./TDDFA_V2/weights/resnet22.pth", | |
bfm_fp="TDDFA_V2/configs/bfm_noneck_v3.pkl", | |
size=120, | |
num_params=62, | |
) | |
face_boxes = FaceBoxes() | |
return tddfa, face_boxes | |
def save(x, trick=None, use_gpen=False): | |
""" Paste img to ori_img """ | |
img, mat, ori_img, save_path, img_mask = x | |
if mat is None: | |
print('[Warning] mat is None.') | |
ori_img = ori_img.astype(np.uint8) | |
Image.fromarray(ori_img).save(save_path) | |
return | |
H, W = img.shape[0], img.shape[1] # (256,256) or (512,512) | |
mat_rev = np.zeros([2, 3]) | |
div1 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0] | |
mat_rev[0][0] = mat[1][1] / div1 | |
mat_rev[0][1] = -mat[0][1] / div1 | |
mat_rev[0][2] = -(mat[0][2] * mat[1][1] - mat[0][1] * mat[1][2]) / div1 | |
div2 = mat[0][1] * mat[1][0] - mat[0][0] * mat[1][1] | |
mat_rev[1][0] = mat[1][0] / div2 | |
mat_rev[1][1] = -mat[0][0] / div2 | |
mat_rev[1][2] = -(mat[0][2] * mat[1][0] - mat[0][0] * mat[1][2]) / div2 | |
img_shape = (ori_img.shape[1], ori_img.shape[0]) # (h,w) | |
img = cv2.warpAffine(img, mat_rev, img_shape) | |
if img_mask is None: | |
''' hanbang version of paste masks ''' | |
img_white = np.full((H, W), 255, dtype=float) | |
img_white = cv2.warpAffine(img_white, mat_rev, img_shape) | |
img_white[img_white > 20] = 255 | |
img_mask = img_white | |
kernel = np.ones((40, 40), np.uint8) | |
img_mask = cv2.erode(img_mask, kernel, iterations=2) | |
kernel_size = (20, 20) | |
blur_size = tuple(2 * j + 1 for j in kernel_size) | |
img_mask = cv2.GaussianBlur(img_mask, blur_size, 0) | |
img_mask /= 255 | |
img_mask = np.reshape(img_mask, [img_mask.shape[0], img_mask.shape[1], 1]) | |
else: | |
''' yuange version of paste masks ''' | |
img_mask = cv2.warpAffine(img_mask, mat_rev, img_shape) | |
img_mask = np.expand_dims(img_mask, axis=-1) | |
ori_img = img_mask * img + (1 - img_mask) * ori_img | |
ori_img = ori_img.astype(np.uint8) | |
if trick is not None: | |
ori_img = trick.gpen(ori_img, use_gpen) | |
Image.fromarray(ori_img).save(save_path) | |
# img_mask = np.array((img_mask * 255), dtype=np.uint8).squeeze() | |
# Image.fromarray(img_mask).save('img_mask.jpg') | |