FaceDetection / app.py
MohammedAli93's picture
Upload 4 files
c2fed66 verified
raw
history blame
3.16 kB
"""
Hugging Face Space — Face Swap with InsightFace inswapper_128.
Gradio app: webcam or upload a source face, swap it onto a target image.
"""
import os
import cv2
import numpy as np
import gradio as gr
import insightface
from insightface.app import FaceAnalysis
from huggingface_hub import hf_hub_download
HERE = os.path.dirname(os.path.abspath(__file__))
DEFAULT_TARGET = os.path.join(HERE, "reference.png")
print("[boot] loading FaceAnalysis (buffalo_l)…", flush=True)
face_app = FaceAnalysis(name="buffalo_l", providers=["CPUExecutionProvider"])
face_app.prepare(ctx_id=0, det_size=(640, 640))
print("[boot] downloading inswapper_128…", flush=True)
MODEL_PATH = hf_hub_download(
repo_id="ezioruan/inswapper_128.onnx",
filename="inswapper_128.onnx",
)
print("[boot] loading inswapper_128…", flush=True)
swapper = insightface.model_zoo.get_model(
MODEL_PATH, providers=["CPUExecutionProvider"]
)
print("[boot] ready", flush=True)
def largest_face(faces):
return max(
faces,
key=lambda f: (f.bbox[2] - f.bbox[0]) * (f.bbox[3] - f.bbox[1]),
)
def swap(source_img, target_img):
if source_img is None:
return None, "Please provide a source face (webcam or upload)."
# Gradio gives RGB numpy — convert to BGR for OpenCV/InsightFace
source_bgr = cv2.cvtColor(source_img, cv2.COLOR_RGB2BGR)
if target_img is None:
target_bgr = cv2.imread(DEFAULT_TARGET)
if target_bgr is None:
return None, "Default target image is missing."
else:
target_bgr = cv2.cvtColor(target_img, cv2.COLOR_RGB2BGR)
source_faces = face_app.get(source_bgr)
if not source_faces:
return None, "No face detected in source image."
src_face = largest_face(source_faces)
target_faces = face_app.get(target_bgr)
if not target_faces:
return None, "No face detected in target image."
tgt_face = largest_face(target_faces)
result = swapper.get(target_bgr, tgt_face, src_face, paste_back=True)
return cv2.cvtColor(result, cv2.COLOR_BGR2RGB), "Done."
with gr.Blocks(title="Face Swap — InsightFace") as demo:
gr.Markdown(
"# Face Swap — InsightFace `inswapper_128`\n"
"Take a webcam photo (or upload), click **Swap**. "
"Leave the target empty to use the default Denmark fan, "
"or upload your own target image."
)
with gr.Row():
with gr.Column():
src_in = gr.Image(
sources=["webcam", "upload"],
type="numpy",
label="Your face (webcam or upload)",
)
tgt_in = gr.Image(
sources=["upload"],
type="numpy",
label="Target image (optional — defaults to reference.png)",
value=DEFAULT_TARGET,
)
btn = gr.Button("Swap", variant="primary")
with gr.Column():
out_img = gr.Image(label="Result", type="numpy")
status = gr.Textbox(label="Status", interactive=False)
btn.click(swap, inputs=[src_in, tgt_in], outputs=[out_img, status])
if __name__ == "__main__":
demo.launch()