File size: 2,965 Bytes
239e6b3
 
 
3036471
f0f3036
239e6b3
3036471
f0f3036
 
3036471
 
 
 
 
f0f3036
3036471
239e6b3
3036471
 
f0f3036
 
3036471
 
239e6b3
3036471
 
 
 
 
 
239e6b3
3036471
 
 
 
239e6b3
3036471
 
 
239e6b3
3036471
 
 
 
92b238b
3036471
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92b238b
3036471
92b238b
3036471
 
 
 
 
 
 
 
 
 
92b238b
3036471
 
 
 
 
 
 
 
 
92b238b
3036471
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import subprocess
import sys

# --- Installation Block ---
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()

# --- Imports ---
import gradio as gr
import cv2
import numpy as np
from PIL import Image
import facemorpher

# --- Image Loader ---
def load_image(file):
    img = cv2.imread(file.name)
    if img is None:
        raise ValueError(f"Failed to load image: {file.name}")
    return img

# --- Morphing Function ---
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])

# --- Lipsync Processing ---
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

# --- Gradio Interface ---
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()