Spaces:
Sleeping
Sleeping
File size: 3,380 Bytes
0a7d313 b098d52 9f28bcd ad62ac1 6fa4ded f3a76a1 b098d52 d5144c2 0a14ee3 0a7d313 d5144c2 0a7d313 0a4e356 495a7a7 f3a76a1 ad62ac1 495a7a7 f00c22f 0a14ee3 f00c22f 0a14ee3 f00c22f 0a14ee3 495a7a7 f00c22f 495a7a7 9f28bcd 495a7a7 f00c22f 495a7a7 f00c22f 6fa4ded f00c22f 0a14ee3 f00c22f 495a7a7 6fa4ded f00c22f 495a7a7 f00c22f 6fa4ded f00c22f 6fa4ded f00c22f f3a76a1 0a4e356 f3a76a1 495a7a7 f00c22f 9f28bcd 495a7a7 ae78b79 9f28bcd d5144c2 495a7a7 b0cfea0 495a7a7 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 |
import os
import gradio as gr
import cv2
import numpy as np
from insightface.app import FaceAnalysis
import tempfile
from moviepy.editor import VideoFileClip
# Désactiver les avertissements d'Albumentations
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') # Codec compatible H.264
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()
print(f"Taille de la vidéo temporaire : {os.path.getsize(temp_output.name)} octets")
# 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 lors du traitement : {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) |