File size: 2,508 Bytes
a421271
a545eac
 
 
0212eae
a421271
a545eac
e4c6291
 
 
 
 
 
 
db40070
a545eac
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a421271
 
 
 
 
 
a545eac
a421271
a545eac
a421271
a545eac
 
 
a421271
 
 
 
 
 
a545eac
a421271
 
 
 
 
 
 
a545eac
 
a421271
 
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
import gradio as gr
import cv2
import dlib
import numpy as np
import subprocess
import os

subprocess.check_call([sys.executable, "-m", "pip", "install", "--upgrade", "pip"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "gradio==2.3.0"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "modelscope==1.9.4"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "moviepy==1.0.3"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "natsort==8.4.0"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "opencv-python==4.8.1.78"])
subprocess.check_call([sys.executable, "-m", "pip", "install", "torch==1.10.0"])

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'mp4', 'avi'}

detector = dlib.get_frontal_face_detector()

def detect_faces(image_path):
    img = cv2.imread(image_path)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = detector(gray)
    return faces, img

def extract_face(img, face):
    x, y, w, h = face.left(), face.top(), face.width(), face.height()
    return img[y:y+h, x:x+w]

def swap_faces(img, face1, face2):
    face1_img = extract_face(img, face1)
    face2_img = extract_face(img, face2)

    face1_resized = cv2.resize(face1_img, (face2.width(), face2.height()))
    face2_resized = cv2.resize(face2_img, (face1.width(), face1.height()))

    img[face1.top():face1.top()+face1.height(), face1.left():face1.left()+face1.width()] = face2_resized
    img[face2.top():face2.top()+face2.height(), face2.left():face2.left()+face2.width()] = face1_resized

    return img

def process_file(image):
    if image is None:
        return "Please upload an image."
    
    filename = os.path.join(UPLOAD_FOLDER, 'uploaded_image.jpg')
    cv2.imwrite(filename, image)

    faces, img = detect_faces(filename)
    if len(faces) < 2:
        return "Need at least two faces to swap"

    swapped_img = swap_faces(img, faces[0], faces[1])
    
    result_filename = os.path.join(UPLOAD_FOLDER, 'result_image.jpg')
    cv2.imwrite(result_filename, swapped_img)
    return swapped_img

if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

iface = gr.Interface(
    fn=process_file,
    inputs=gr.Image(type="numpy", label="Upload an Image"),
    outputs=gr.Image(type="numpy", label="Swapped Faces"),
    title="Face Swap",
    description="Upload an image with at least two faces, and this tool will swap the faces."
)

if __name__ == "__main__":
    iface.launch()