|
|
|
import cv2 |
|
import numpy as np |
|
|
|
emap = np.load("emap.npy") |
|
input_std = 255.0 |
|
input_mean = 0.0 |
|
|
|
def postprocess_face(face_tensor): |
|
face_tensor = face_tensor.squeeze().cpu().detach() |
|
face_np = (face_tensor.permute(1, 2, 0).numpy() * 255).astype(np.uint8) |
|
face_np = cv2.cvtColor(face_np, cv2.COLOR_RGB2BGR) |
|
|
|
return face_np |
|
|
|
def getBlob(aimg, input_size = (128, 128)): |
|
blob = cv2.dnn.blobFromImage(aimg, 1.0 / input_std, input_size, |
|
(input_mean, input_mean, input_mean), swapRB=True) |
|
return blob |
|
|
|
def getLatent(source_face): |
|
latent = source_face.normed_embedding.reshape((1,-1)) |
|
latent = np.dot(latent, emap) |
|
latent /= np.linalg.norm(latent) |
|
|
|
return latent |
|
|
|
def blend_swapped_image(swapped_face, target_image, M): |
|
|
|
h, w = target_image.shape[:2] |
|
|
|
|
|
M_inv = cv2.invertAffineTransform(M) |
|
|
|
|
|
warped_face = cv2.warpAffine( |
|
swapped_face, |
|
M_inv, |
|
(w, h), |
|
borderValue=0.0 |
|
) |
|
|
|
|
|
img_white = np.full( |
|
(swapped_face.shape[0], swapped_face.shape[1]), |
|
255, |
|
dtype=np.float32 |
|
) |
|
|
|
|
|
img_mask = cv2.warpAffine( |
|
img_white, |
|
M_inv, |
|
(w, h), |
|
borderValue=0.0 |
|
) |
|
|
|
|
|
img_mask[img_mask > 20] = 255 |
|
|
|
|
|
mask_h_inds, mask_w_inds = np.where(img_mask == 255) |
|
if len(mask_h_inds) > 0 and len(mask_w_inds) > 0: |
|
mask_h = np.max(mask_h_inds) - np.min(mask_h_inds) |
|
mask_w = np.max(mask_w_inds) - np.min(mask_w_inds) |
|
mask_size = int(np.sqrt(mask_h * mask_w)) |
|
|
|
|
|
k = max(mask_size // 10, 10) |
|
kernel = np.ones((k, k), np.uint8) |
|
img_mask = cv2.erode(img_mask, kernel, iterations=1) |
|
|
|
|
|
k = max(mask_size // 20, 5) |
|
kernel_size = (k, k) |
|
blur_size = tuple(2 * i + 1 for i in kernel_size) |
|
img_mask = cv2.GaussianBlur(img_mask, blur_size, 0) |
|
|
|
|
|
img_mask = img_mask / 255.0 |
|
img_mask = np.reshape(img_mask, [img_mask.shape[0], img_mask.shape[1], 1]) |
|
|
|
|
|
result = img_mask * warped_face + (1 - img_mask) * target_image.astype(np.float32) |
|
result = result.astype(np.uint8) |
|
|
|
return result |
|
|
|
def drawKeypoints(image, keypoints, colorBGR, keypointsRadius=2): |
|
for kp in keypoints: |
|
x, y = int(kp[0]), int(kp[1]) |
|
cv2.circle(image, (x, y), radius=keypointsRadius, color=colorBGR, thickness=-1) |