Mmyyyzsj commited on
Commit
6cff877
·
verified ·
1 Parent(s): 22c800c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +134 -0
app.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import gradio as gr
4
+ import numpy as np
5
+ from PIL import Image
6
+ from insightface.app import FaceAnalysis
7
+ from insightface.model_zoo import get_model
8
+ from huggingface_hub import hf_hub_download
9
+ import tempfile
10
+
11
+ # --- 1. تجهيز الموديلات (طريقة hf_hub الرسمية) ---
12
+ print("--- جاري التحقق من الموديلات ---")
13
+
14
+ try:
15
+ # تحميل موديل التبديل (inswapper_128)
16
+ model_path = hf_hub_download(
17
+ repo_id="ezioruan/inswapper_128.onnx",
18
+ filename="inswapper_128.onnx",
19
+ local_dir=os.path.expanduser("~/.insightface/models"),
20
+ local_dir_use_symlinks=False
21
+ )
22
+ except Exception as e:
23
+ print(f"❌ خطأ في تحميل الموديل: {e}")
24
+ model_path = None
25
+
26
+ # تهيئة محرك تحليل الوجوه - تم تقليل det_size لتسريع الـ CPU
27
+ print("--- تهيئة FaceAnalysis (Optimization: 320x320) ---")
28
+ face_app = FaceAnalysis(name='buffalo_l', providers=['CPUExecutionProvider'])
29
+ face_app.prepare(ctx_id=0, det_size=(320, 320))
30
+
31
+ # تحميل المبدل مع التحقق من المسار
32
+ swapper = None
33
+ if model_path and os.path.exists(model_path):
34
+ try:
35
+ swapper = get_model(model_path, download=False)
36
+ print("✅ تم تحميل Swapper بنجاح")
37
+ except Exception as e:
38
+ print(f"❌ فشل تحميل Swapper: {e}")
39
+
40
+ # --- 2. منطق المعالجة الأساسي ---
41
+
42
+ def process_video(source_img, target_video, progress=gr.Progress()):
43
+ if swapper is None:
44
+ return None, "❌ عذراً، موديل التبديل غير جاهز حالياً."
45
+
46
+ if source_img is None or target_video is None:
47
+ return None, "⚠️ يرجى رفع الصورة والفيديو أولاً."
48
+
49
+ # تحويل الصورة المصدر واستخراج الوجه الأول
50
+ face_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
51
+ source_faces = face_app.get(face_img)
52
+
53
+ if len(source_faces) == 0:
54
+ return None, "❌ لم يتم العثور على وجه واضح في صورتك."
55
+
56
+ # نأخذ أول وجه تم العثور عليه
57
+ source_face = source_faces[0]
58
+
59
+ # إعداد الفيديو
60
+ cap = cv2.VideoCapture(target_video)
61
+ fps = cap.get(cv2.CAP_PROP_FPS)
62
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
63
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
64
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
65
+
66
+ # ملف مؤقت للنتيجة
67
+ output_path = tempfile.mktemp(suffix='.mp4')
68
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
69
+ out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
70
+
71
+ frame_count = 0
72
+ try:
73
+ while cap.isOpened():
74
+ ret, frame = cap.read()
75
+ if not ret:
76
+ break
77
+
78
+ # تحليل الوجوه في الفريم (تبديل أول وجه يظهر فقط لتسريع العملية)
79
+ target_faces = face_app.get(frame)
80
+ if target_faces:
81
+ # نبدل أول وجه فقط المكتشف في الفيديو لتقليل زمن المعالجة على CPU
82
+ frame = swapper.get(frame, target_faces[0], source_face, paste_back=True)
83
+
84
+ out.write(frame)
85
+ frame_count += 1
86
+
87
+ if frame_count % 5 == 0:
88
+ percent = int((frame_count / total_frames) * 100)
89
+ progress(frame_count / total_frames, desc=f"🎬 جاري المعالجة: {percent}%")
90
+
91
+ except Exception as e:
92
+ return None, f"🔥 خطأ تقني: {str(e)}"
93
+ finally:
94
+ cap.release()
95
+ out.release()
96
+
97
+ return output_path, "✅ اكتملت المعالجة! لاحظ أن الجودة مرتبطة بدقة الكشف (320px)."
98
+
99
+ # --- 3. واجهة المستخدم الرسومية ---
100
+ css = """
101
+ .upload-box { border: 2px dashed #4f46e5; border-radius: 15px; padding: 15px; background: #f9fafb; }
102
+ #mix-btn { background: linear-gradient(90deg, #4f46e5, #7c3aed); color: white; border-radius: 10px; font-weight: bold; }
103
+ .warning-text { color: #ef4444; font-weight: bold; text-align: center; }
104
+ """
105
+
106
+ with gr.Blocks(css=css, theme=gr.themes.Soft(primary_hue="indigo")) as demo:
107
+ gr.HTML("""
108
+ <div style="text-align: center; padding: 10px;">
109
+ <h1 style="color: #4f46e5; margin-bottom: 5px;">🎭 AI Face Mix Pro</h1>
110
+ <p style="color: #666;">أداة تبديل الوجوه المتقدمة (نسخة CPU المحسنة)</p>
111
+ </div>
112
+ """)
113
+
114
+ with gr.Row():
115
+ with gr.Column():
116
+ with gr.Group(elem_classes="upload-box"):
117
+ source_image = gr.Image(label="📸 ارفع صورتك الشخصية", type="pil")
118
+ target_vid = gr.Video(label="🎬 ارفع فيديو المشهد")
119
+
120
+ gr.Markdown("⚠️ **تنبيه:** بما أنك تستخدم النسخة المجانية، المعالجة قد تستغرق وقتاً طويلاً حسب طول الفيديو.", elem_classes="warning-text")
121
+ mix_btn = gr.Button("🚀 ابدأ الخلط الآن", elem_id="mix-btn")
122
+
123
+ with gr.Column():
124
+ output_vid = gr.Video(label="✨ النتيجة النهائية")
125
+ status = gr.Textbox(label="📡 حالة النظام", interactive=False)
126
+
127
+ mix_btn.click(
128
+ fn=process_video,
129
+ inputs=[source_image, target_vid],
130
+ outputs=[output_vid, status]
131
+ )
132
+
133
+ if __name__ == "__main__":
134
+ demo.launch()