Spaces:
Running
Running
File size: 3,245 Bytes
0a7d313 b098d52 9f28bcd ad62ac1 6fa4ded f3a76a1 b098d52 babc775 b45ec36 b0da32b 0a7d313 d5144c2 0a7d313 b0da32b 495a7a7 b0da32b ad62ac1 495a7a7 f00c22f b45ec36 f00c22f b45ec36 f00c22f b45ec36 495a7a7 f00c22f b45ec36 495a7a7 9f28bcd 495a7a7 f00c22f 495a7a7 f00c22f 6fa4ded f00c22f b45ec36 f00c22f 495a7a7 6fa4ded f00c22f 495a7a7 f00c22f 6fa4ded f00c22f 6fa4ded f00c22f f3a76a1 0a4e356 f3a76a1 495a7a7 f00c22f 9f28bcd babc775 ae78b79 9f28bcd b45ec36 b0da32b 495a7a7 b0da32b 495a7a7 b0da32b b0cfea0 495a7a7 b098d52 b45ec36 b098d52 5638557 |
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 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
import os
import gradio as gr
import cv2
import numpy as np
from insightface.app import FaceAnalysis
import tempfile
from moviepy.editor import VideoFileClip
# ===== Configuration précoce pour éviter les erreurs =====
os.environ["NO_ALBUMENTATIONS_UPDATE"] = "1"
# Rediriger les chemins problématiques
os.environ['MPLCONFIGDIR'] = '/tmp/matplotlib'
os.environ['FONTCONFIG_PATH'] = '/tmp/fontconfig'
os.makedirs('/tmp/matplotlib', exist_ok=True)
os.makedirs('/tmp/fontconfig', exist_ok=True)
# Forcer InsightFace à utiliser un répertoire accessible
os.environ['INSIGHTFACE_ROOT'] = '/tmp/.insightface'
os.environ["ORT_DISABLE_CUDA"] = "1" # Désactiver CUDA si GPU indisponible
def swap_face(source_face, target_face, frame):
src_emb = source_face.normed_embedding
tgt_bbox = target_face.bbox.astype(int)
resized_face = cv2.resize(source_face.img, (tgt_bbox[2]-tgt_bbox[0], tgt_bbox[3]-tgt_bbox[1]))
mask = np.zeros_like(resized_face)
center = (mask.shape[1]//2, mask.shape[0]//2)
radius = int(min(mask.shape) * 0.45)
cv2.circle(mask, center, radius, (255,255,255), -1)
mask = cv2.GaussianBlur(mask, (15,15), 5)
center = ((tgt_bbox[0]+tgt_bbox[2])//2, (tgt_bbox[1]+tgt_bbox[3])//2)
result = cv2.seamlessClone(resized_face, frame, mask, center, cv2.NORMAL_CLONE)
return result
def process_video(source_img, target_video):
try:
face_app = FaceAnalysis(name="buffalo_l", root="/tmp/.insightface")
face_app.prepare(ctx_id=0, det_size=(640, 640))
source_faces = face_app.get(source_img)
if not source_faces:
raise ValueError("Aucun visage trouvé dans l'image source.")
source_face = source_faces[0]
temp_output = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
cap = cv2.VideoCapture(target_video)
fps = cap.get(cv2.CAP_PROP_FPS)
frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'avc1')
out = cv2.VideoWriter(temp_output.name, fourcc, fps, (frame_width, frame_height))
while True:
ret, frame = cap.read()
if not ret:
break
target_faces = face_app.get(frame)
for face in target_faces:
frame = swap_face(source_face, face, frame)
out.write(frame)
cap.release()
out.release()
# Réencodage final pour compatibilité Gradio
clip = VideoFileClip(temp_output.name)
final_path = tempfile.mktemp(suffix=".mp4")
clip.write_videofile(final_path, codec="libx264", audio_codec="aac", verbose=False, logger=None)
return final_path
except Exception as e:
print(f"Erreur : {str(e)}")
return None
# Interface Gradio
demo = gr.Interface(
fn=process_video,
inputs=[
gr.Image(label="Visage Source", type="numpy"),
gr.Video(label="Vidéo Cible"),
],
outputs=gr.Video(label="Vidéo Résultat"),
title="🎬 FaceSwap Pro",
description="Échangez des visages dans une vidéo.",
allow_flagging="never"
)
if __name__ == "__main__":
demo.launch(share=True) |