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')