lipsync-docker / shared /blending /__init__.py
naicoi's picture
update
0d4381f
Raw
History Blame Contribute Delete
2.41 kB
"""Face blending module for MuseTalk"""
import numpy as np
import cv2
import copy
from PIL import Image
def get_image(image, face, face_box, mode="jaw", fp=None):
"""Blend generated face back to original image
Args:
image: Original full image (BGR numpy array)
face: Generated face (BGR numpy array)
face_box: Bounding box [x1, y1, x2, y2]
mode: Blending mode ("jaw" or default)
fp: Face parser (optional)
"""
body = Image.fromarray(image[:, :, ::-1])
face = Image.fromarray(face[:, :, ::-1])
x1, y1, x2, y2 = face_box
crop_box, s = _get_crop_box(face_box, expand=1.5)
x_s, y_s, x_e, y_e = crop_box
face_large = body.crop(crop_box)
ori_shape = face_large.size
if fp is not None:
mask_image = fp(face_large, mode=mode)
mask_small = mask_image.crop((x1 - x_s, y1 - y_s, x2 - x_s, y2 - y_s))
mask_image = Image.new("L", ori_shape, 0)
mask_image.paste(mask_small, (x1 - x_s, y1 - y_s, x2 - x_s, y2 - y_s))
width, height = mask_image.size
top_boundary = int(height * 0.5)
modified_mask_image = Image.new("L", ori_shape, 0)
modified_mask_image.paste(
mask_image.crop((0, top_boundary, width, height)), (0, top_boundary)
)
blur_kernel_size = int(0.1 * ori_shape[0] // 2 * 2) + 1
mask_array = cv2.GaussianBlur(
np.array(modified_mask_image), (blur_kernel_size, blur_kernel_size), 0
)
mask_image = Image.fromarray(mask_array)
else:
mask_image = Image.new("L", ori_shape, 255)
face_large.paste(face, (x1 - x_s, y1 - y_s, x2 - x_s, y2 - y_s))
body.paste(face_large, crop_box[:2], mask_image)
body = np.array(body)[:, :, ::-1]
return body
def _get_crop_box(box, expand=1.5):
x, y, x1, y1 = box
x_c, y_c = (x + x1) // 2, (y + y1) // 2
w, h = x1 - x, y1 - y
s = int(max(w, h) // 2 * expand)
crop_box = [x_c - s, y_c - s, x_c + s, y_c + s]
return crop_box, s
if __name__ == "__main__":
test_img = np.zeros((512, 512, 3), dtype=np.uint8)
test_img[:, :, 1] = 100
test_img[:, :, 2] = 200
test_face = np.zeros((256, 256, 3), dtype=np.uint8)
test_face[:, :, 0] = 255
result = get_image(test_img, test_face, [128, 128, 384, 384], mode="jaw")
cv2.imwrite("test_blending.png", result)
print("Face blending test complete")