assile commited on
Commit
6fa4ded
·
verified ·
1 Parent(s): 95802e7

Update run.py

Browse files
Files changed (1) hide show
  1. run.py +66 -64
run.py CHANGED
@@ -2,87 +2,89 @@ import gradio as gr
2
  import cv2
3
  import numpy as np
4
  from insightface.app import FaceAnalysis
 
 
5
 
6
- # Initialisation sécurisée
7
- try:
8
- face_app = FaceAnalysis(name="buffalo_l")
9
- face_app.prepare(ctx_id=0, det_size=(640, 640))
10
- except Exception as e:
11
- print(f"ERREUR initialisation : {str(e)}")
12
- face_app = None
13
 
14
- def safe_face_swap(source_img, target_img):
15
  try:
16
- if face_app is None:
17
- raise ValueError("Le modèle de détection n'est pas chargé")
18
 
19
- # Conversion robuste
20
- source = np.array(source_img, dtype=np.uint8)
21
- target = np.array(target_img, dtype=np.uint8)
22
 
23
- # Vérification des dimensions
24
- if source.ndim != 3 or target.ndim != 3:
25
- raise ValueError("Format d'image invalide")
26
-
27
- # Détection sécurisée
28
- source_faces = face_app.get(cv2.cvtColor(source, cv2.COLOR_RGB2BGR))
29
- target_faces = face_app.get(cv2.cvtColor(target, cv2.COLOR_RGB2BGR))
 
 
30
 
31
- if not source_faces:
32
- raise ValueError("Aucun visage détecté dans l'image source")
33
- if not target_faces:
34
- raise ValueError("Aucun visage détecté dans l'image cible")
 
 
 
 
35
 
36
- # Swap simplifié mais stable
37
- src_face = source_faces[0].bbox.astype(int)
38
- tgt_face = target_faces[0].bbox.astype(int)
 
39
 
40
- result = target.copy()
41
- result[tgt_face[1]:tgt_face[3], tgt_face[0]:tgt_face[2]] = \
42
- cv2.resize(source[src_face[1]:src_face[3], src_face[0]:src_face[2]],
43
- (tgt_face[2]-tgt_face[0], tgt_face[3]-tgt_face[1]))
44
 
45
- return result
46
  except Exception as e:
47
- print(f"ERREUR traitement : {str(e)}")
48
- # Retourne l'image cible avec message d'erreur
49
- if target_img is not None:
50
- return target_img
51
  return None
52
 
53
- # Interface renforcée
54
- with gr.Blocks(title="FaceSwap Pro") as app:
55
- gr.Markdown("""
56
- ## 🔄 FaceSwap Professionnel
57
- *Échange de visages stable et sécurisé*
58
- """)
59
 
60
- with gr.Row():
61
- with gr.Column():
62
- src = gr.Image(label="Source", type="numpy")
63
- tgt = gr.Image(label="Cible", type="numpy")
64
- btn = gr.Button("Exécuter", variant="primary")
65
- result = gr.Image(label="Résultat", interactive=False)
 
 
 
 
66
 
67
- # Gestion des erreurs dans l'UI
68
- error_box = gr.Textbox(visible=False, label="Erreur")
 
69
 
70
- def wrapped_face_swap(src_img, tgt_img):
71
- try:
72
- return safe_face_swap(src_img, tgt_img), ""
73
- except Exception as e:
74
- return None, f"Erreur : {str(e)}"
 
 
 
 
 
 
 
75
 
76
  btn.click(
77
- fn=wrapped_face_swap,
78
- inputs=[src, tgt],
79
- outputs=[result, error_box]
80
  )
81
 
82
  if __name__ == "__main__":
83
- app.launch(
84
- server_name="0.0.0.0",
85
- server_port=7860,
86
- show_error=True,
87
- debug=True
88
- )
 
2
  import cv2
3
  import numpy as np
4
  from insightface.app import FaceAnalysis
5
+ import tempfile
6
+ from moviepy.editor import VideoFileClip
7
 
8
+ # Initialisation du modèle
9
+ face_swapper = FaceAnalysis(name="buffalo_l")
10
+ face_swapper.prepare(ctx_id=0, det_size=(640, 640))
 
 
 
 
11
 
12
+ def process_video(source_img, target_video):
13
  try:
14
+ # Fichiers temporaires
15
+ temp_output = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
16
 
17
+ # Traitement de la vidéo
18
+ source_face = face_swapper.get(np.array(source_img))[0]
 
19
 
20
+ cap = cv2.VideoCapture(target_video)
21
+ fps = cap.get(cv2.CAP_PROP_FPS)
22
+ frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
23
+ frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
24
+
25
+ out = cv2.VideoWriter(temp_output.name,
26
+ cv2.VideoWriter_fourcc(*'mp4v'),
27
+ fps,
28
+ (frame_width, frame_height))
29
 
30
+ while cap.isOpened():
31
+ ret, frame = cap.read()
32
+ if not ret:
33
+ break
34
+
35
+ target_faces = face_swapper.get(frame)
36
+ if target_faces:
37
+ frame = swap_face(source_face, target_faces[0], frame)
38
 
39
+ out.write(frame)
40
+
41
+ cap.release()
42
+ out.release()
43
 
44
+ return temp_output.name
 
 
 
45
 
 
46
  except Exception as e:
47
+ print(f"ERREUR: {str(e)}")
 
 
 
48
  return None
49
 
50
+ def swap_face(source_face, target_face, frame):
51
+ # Algorithme professionnel d'échange
52
+ src_bbox = source_face.bbox.astype(int)
53
+ tgt_bbox = target_face.bbox.astype(int)
 
 
54
 
55
+ # Extraction et ajustement du visage source
56
+ src_face = cv2.resize(source_face.img[tgt_bbox[1]:tgt_bbox[3], tgt_bbox[0]:tgt_bbox[2]],
57
+ (tgt_bbox[2]-tgt_bbox[0], tgt_bbox[3]-tgt_bbox[1]))
58
+
59
+ # Fusion réaliste
60
+ mask = np.zeros_like(src_face)
61
+ cv2.circle(mask,
62
+ (mask.shape[1]//2, mask.shape[0]//2),
63
+ min(mask.shape)//2,
64
+ (255,255,255), -1)
65
 
66
+ center = ((tgt_bbox[0]+tgt_bbox[2])//2, (tgt_bbox[1]+tgt_bbox[3])//2)
67
+ output = cv2.seamlessClone(
68
+ src_face, frame, mask, center, cv2.NORMAL_CLONE)
69
 
70
+ return output
71
+
72
+ # Interface optimisée pour vidéo
73
+ with gr.Blocks() as app:
74
+ gr.Markdown("## 🎬 VideoFaceSwap Pro")
75
+
76
+ with gr.Row():
77
+ src_img = gr.Image(label="Visage source", type="numpy")
78
+ tgt_video = gr.Video(label="Vidéo cible")
79
+
80
+ btn = gr.Button("Traiter la vidéo", variant="primary")
81
+ output_video = gr.Video(label="Résultat")
82
 
83
  btn.click(
84
+ fn=process_video,
85
+ inputs=[src_img, tgt_video],
86
+ outputs=output_video
87
  )
88
 
89
  if __name__ == "__main__":
90
+ app.launch(server_name="0.0.0.0", server_port=7860)