Mmyyyzsj commited on
Commit
a6852ca
·
verified ·
1 Parent(s): 2695ae9

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +132 -0
app.py ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import cv2
3
+ import torch
4
+ import gradio as gr
5
+ import numpy as np
6
+ from PIL import Image
7
+ from insightface.app import FaceAnalysis
8
+ from insightface.model_zoo import get_model
9
+ from transformers import AutoModelForCausalLM, AutoTokenizer, AutoConfig
10
+ import tempfile
11
+
12
+ # 1. إعداد نماذج الرؤية (Moondream2) - النسخة المستقرة
13
+ print("--- جاري تحميل نموذج الرؤية (Moondream2) ---")
14
+ model_id = "vikhyatk/moondream2"
15
+ revision = "2024-05-20"
16
+ device = "cpu"
17
+
18
+ try:
19
+ # --- الجزء الجديد لحل مشكلة AttributeError و pad_token_id ---
20
+ config = AutoConfig.from_pretrained(model_id, trust_remote_code=True)
21
+ if not hasattr(config, 'pad_token_id'):
22
+ # تعيين pad_token_id ليكون نفس قيمة eos_token_id لمنع خطأ PhiConfig
23
+ config.pad_token_id = config.eos_token_id
24
+
25
+ tokenizer = AutoTokenizer.from_pretrained(
26
+ model_id,
27
+ trust_remote_code=True
28
+ )
29
+
30
+ vision_model = AutoModelForCausalLM.from_pretrained(
31
+ model_id,
32
+ config=config,
33
+ revision=revision,
34
+ trust_remote_code=True
35
+ ).to(device)
36
+ vision_model.eval()
37
+ # -------------------------------------------------------
38
+ except Exception as e:
39
+ print(f"⚠️ خطأ أثناء تحميل موديل الرؤية: {e}")
40
+
41
+ # 2. إعداد محرك الـ Mix (Face Swap)
42
+ print("--- جاري تحميل محرك تبديل الوجوه ---")
43
+ face_app = FaceAnalysis(name='bufflere', providers=['CPUExecutionProvider'])
44
+ face_app.prepare(ctx_id=0, det_size=(640, 640))
45
+
46
+ # تحميل موديل التبديل (inswapper_128)
47
+ swapper = get_model("inswapper_128.onnx", download=True, download_zip=True)
48
+
49
+ def process_video(source_img, target_video, progress=gr.Progress()):
50
+ if source_img is None or target_video is None:
51
+ return None, "⚠️ من فضلك ارفع صورة الوجه وفيديو المشهد أولاً."
52
+
53
+ progress(0, desc="🔍 جاري تحليل ملامح الوجه...")
54
+
55
+ # تحويل الصورة لنمط OpenCV
56
+ face_img = cv2.cvtColor(np.array(source_img), cv2.COLOR_RGB2BGR)
57
+ source_faces = face_app.get(face_img)
58
+
59
+ if not source_faces:
60
+ return None, "❌ لم نجد وجهاً واضحاً في الصورة المرفوعة!"
61
+
62
+ source_face = source_faces[0]
63
+
64
+ # قراءة الفيديو المصدر
65
+ cap = cv2.VideoCapture(target_video)
66
+ fps = cap.get(cv2.CAP_PROP_FPS)
67
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
68
+ width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
69
+ height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
70
+
71
+ # إنشاء ملف مؤقت للنتيجة
72
+ output_fd, output_path = tempfile.mkstemp(suffix='.mp4')
73
+ os.close(output_fd)
74
+
75
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
76
+ out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
77
+
78
+ frame_count = 0
79
+ try:
80
+ while cap.isOpened():
81
+ ret, frame = cap.read()
82
+ if not ret:
83
+ break
84
+
85
+ # البحث عن الوجوه في كل فريم لتبديلها
86
+ target_faces = face_app.get(frame)
87
+ if target_faces:
88
+ for target_face in target_faces:
89
+ # عملية التبديل السينمائي
90
+ frame = swapper.get(frame, target_face, source_face, paste_back=True)
91
+
92
+ out.write(frame)
93
+ frame_count += 1
94
+
95
+ if frame_count % 5 == 0:
96
+ progress(frame_count / total_frames, desc=f"🎬 جاري المعالجة: {int((frame_count/total_frames)*100)}%")
97
+
98
+ except Exception as e:
99
+ return None, f"🔥 حدث خطأ فني: {str(e)}"
100
+ finally:
101
+ cap.release()
102
+ out.release()
103
+
104
+ return output_path, "✅ تم الخلط بنجاح! شاهد النتيجة الآن."
105
+
106
+ # 3. واجهة المستخدم (Gradio UI)
107
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="indigo")) as demo:
108
+ gr.HTML("""
109
+ <div style="text-align: center; padding: 20px;">
110
+ <h1 style="font-size: 2.5rem; font-weight: 900;">🎭 AI Face Mix Pro</h1>
111
+ <p style="font-size: 1.1rem; opacity: 0.8;">اجمع بين صورتك وأي مشهد فيديو باحترافية</p>
112
+ </div>
113
+ """)
114
+
115
+ with gr.Row():
116
+ with gr.Column():
117
+ source_image = gr.Image(label="📸 صورتك الشخصية", type="pil")
118
+ target_video = gr.Video(label="🎬 فيديو المشهد")
119
+ mix_btn = gr.Button("🚀 ابدأ الخلط السحري", variant="primary")
120
+
121
+ with gr.Column():
122
+ output_video = gr.Video(label="✨ النتيجة النهائية")
123
+ status_text = gr.Textbox(label="📡 حالة المعالجة", interactive=False)
124
+
125
+ mix_btn.click(
126
+ fn=process_video,
127
+ inputs=[source_image, target_video],
128
+ outputs=[output_video, status_text]
129
+ )
130
+
131
+ if __name__ == "__main__":
132
+ demo.launch(server_name="0.0.0.0", server_port=7860)