|
|
import subprocess |
|
|
import sys |
|
|
|
|
|
|
|
|
def install_requirements(): |
|
|
try: |
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "opencv-python", "numpy", "scipy", "matplotlib", "gradio", "Pillow"]) |
|
|
try: |
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "facemorpher"]) |
|
|
except subprocess.CalledProcessError: |
|
|
subprocess.check_call([sys.executable, "-m", "pip", "install", "stasm", "docopt"]) |
|
|
print("facemorpher not available; fallback dependencies installed.") |
|
|
except Exception as e: |
|
|
print(f"Installation failed: {e}") |
|
|
|
|
|
install_requirements() |
|
|
|
|
|
|
|
|
import gradio as gr |
|
|
import cv2 |
|
|
import numpy as np |
|
|
from PIL import Image |
|
|
import facemorpher |
|
|
|
|
|
|
|
|
def load_image(file): |
|
|
img = cv2.imread(file.name) |
|
|
if img is None: |
|
|
raise ValueError(f"Failed to load image: {file.name}") |
|
|
return img |
|
|
|
|
|
|
|
|
def generate_lipsync_frame(img1, img2, morph_strength): |
|
|
img1_rgb = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) |
|
|
img2_rgb = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB) |
|
|
|
|
|
frames = facemorpher.morpher.morph_images([img1_rgb, img2_rgb], num_frames=20) |
|
|
index = int(morph_strength * (len(frames) - 1)) |
|
|
return Image.fromarray(frames[index]) |
|
|
|
|
|
|
|
|
def lipsync_interface(mm, aa, ee, oo, ww, na, s_aa, s_oo, s_ee, s_ww, s_na): |
|
|
mm_img = load_image(mm) |
|
|
result = mm_img.copy() |
|
|
|
|
|
if s_aa > 0.0: |
|
|
aa_img = load_image(aa) |
|
|
result = generate_lipsync_frame(result, aa_img, s_aa) |
|
|
if s_oo > 0.0: |
|
|
oo_img = load_image(oo) |
|
|
result = generate_lipsync_frame(result, oo_img, s_oo) |
|
|
if s_ee > 0.0: |
|
|
ee_img = load_image(ee) |
|
|
result = generate_lipsync_frame(result, ee_img, s_ee) |
|
|
if s_ww > 0.0: |
|
|
ww_img = load_image(ww) |
|
|
result = generate_lipsync_frame(result, ww_img, s_ww) |
|
|
if s_na > 0.0: |
|
|
na_img = load_image(na) |
|
|
result = generate_lipsync_frame(result, na_img, s_na) |
|
|
|
|
|
return result |
|
|
|
|
|
|
|
|
iface = gr.Interface( |
|
|
fn=lipsync_interface, |
|
|
inputs=[ |
|
|
gr.Image(label="MM Image (Neutral)", type="file"), |
|
|
gr.Image(label="AA Image", type="file"), |
|
|
gr.Image(label="EE Image", type="file"), |
|
|
gr.Image(label="OO Image", type="file"), |
|
|
gr.Image(label="WW Image", type="file"), |
|
|
gr.Image(label="NA Image", type="file"), |
|
|
|
|
|
gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label="Morph Strength AA"), |
|
|
gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label="Morph Strength OO"), |
|
|
gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label="Morph Strength EE"), |
|
|
gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label="Morph Strength WW"), |
|
|
gr.Slider(minimum=0.0, maximum=1.0, step=0.05, label="Morph Strength NA"), |
|
|
], |
|
|
outputs=gr.Image(label="Interpolated Lip-sync Frame"), |
|
|
live=True |
|
|
) |
|
|
|
|
|
iface.launch() |