Mr-HASSAN commited on
Commit
ed83cdc
·
verified ·
1 Parent(s): ed4b382

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -43
app.py CHANGED
@@ -10,17 +10,27 @@ import arabic_reshaper
10
  from bidi.algorithm import get_display
11
 
12
  import google.generativeai as genai
13
- import torch # 👈 مهم للـ GPU
14
 
15
  # ==========================
16
  # ⚠️ هنا تحط مفتاحك مباشرة
17
  # ==========================
18
 
19
- GEMINI_API_KEY = "AIzaSyAvm28ZnTMaZ1Jtg9sYM-EO4qlAN2W4BIQ" # 👈 استبدله بمفتاحك
20
 
21
- # اضبط الـ API
22
  genai.configure(api_key=GEMINI_API_KEY)
23
 
 
 
 
 
 
 
 
 
 
 
 
24
  # ==========================
25
  # إعدادات YOLO + الثوابت
26
  # ==========================
@@ -29,17 +39,10 @@ WEIGHTS_PATH = "best.pt"
29
  IMG_SIZE = 256
30
  CONF_THRESHOLD = 0.5
31
 
32
- # عدد الإطارات المطلوبة عشان نثبت الحرف
33
  MIN_STABLE_FRAMES = 3
34
- # بعد كم ثانية نحذر المستخدم إن الكلمة بتنتهي
35
  WARN_BEFORE_RESET = 1.5
36
- # بعد كم ثانية نعتبر الكلمة انتهت ونرسلها لـ Gemini
37
  RESET_DELAY = 2.5
38
 
39
- # اختيار الجهاز: GPU لو موجود، غيره CPU
40
- DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
41
- print("🔥 Using device:", DEVICE)
42
-
43
  arabic_map = {
44
  "aleff": "ا", "bb": "ب", "ta": "ت", "thaa": "ث", "jeem": "ج",
45
  "haa": "ح", "khaa": "خ", "dal": "د", "thal": "ذ", "ra": "ر",
@@ -61,39 +64,42 @@ SYSTEM_PROMPT = (
61
  )
62
 
63
  # ==========================
64
- # دوال رسم العربي
65
  # ==========================
66
 
67
- def draw_arabic_text(
68
- img,
69
- text,
70
- x,
71
- y,
72
- font_path="NotoNaskhArabic-VariableFont_wght.ttf",
73
- font_size=24,
74
- ):
75
- reshaped = arabic_reshaper.reshape(text)
76
- bidi_text = get_display(reshaped)
77
 
78
- img_pil = Image.fromarray(img)
79
- draw = ImageDraw.Draw(img_pil)
 
 
80
 
81
- try:
82
- font = ImageFont.truetype(font_path, font_size)
83
- except Exception:
84
- font = ImageFont.load_default()
85
 
86
- draw.text((x, y), bidi_text, font=font, fill=(0, 0, 0))
87
- return np.array(img_pil)
 
 
 
 
88
 
 
 
 
89
 
90
  def draw_detections(result, frame, names):
 
 
 
 
91
  boxes = result.boxes
92
  detected_labels = []
93
 
94
  if boxes is None or len(boxes) == 0:
95
  return frame, detected_labels
96
 
 
 
97
  for box in boxes:
98
  x1, y1, x2, y2 = map(int, box.xyxy[0])
99
  cls_id = int(box.cls[0])
@@ -106,6 +112,7 @@ def draw_detections(result, frame, names):
106
  ar_label = arabic_map.get(eng_label, eng_label)
107
  detected_labels.append(ar_label)
108
 
 
109
  cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
110
 
111
  label_bg_y1 = max(0, y1 - 35)
@@ -118,18 +125,40 @@ def draw_detections(result, frame, names):
118
  -1,
119
  )
120
 
121
- frame = draw_arabic_text(frame, ar_label, x1 + 5, label_bg_y1 + 5)
 
 
 
 
 
 
122
 
123
- return frame, detected_labels
 
 
 
 
 
 
 
124
 
125
 
126
  # ==========================
127
- # تحميل YOLO
128
  # ==========================
129
 
130
  print("🔹 Loading YOLO model...")
131
  model = YOLO(WEIGHTS_PATH)
132
- model.to(DEVICE) # 👈 نحمل الموديل على الـ GPU لو موجود
 
 
 
 
 
 
 
 
 
133
  print("📚 Classes:", model.names)
134
 
135
 
@@ -142,7 +171,7 @@ def call_gemini_on_word(word: str) -> str:
142
  return ""
143
 
144
  try:
145
- # نفس الموديل اللي كنت تستخدمه
146
  model_g = genai.GenerativeModel("gemini-1.5-flash")
147
 
148
  prompt = (
@@ -172,18 +201,19 @@ def process_frame(
172
  if chat_history is None:
173
  chat_history = []
174
 
175
- # نحول من RGB (gradio) إلى BGR (opencv)
176
  frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
177
- # نعكس الصورة أفقياً (كأنها مراية)
178
  frame_bgr = cv2.flip(frame_bgr, 1)
179
 
180
- # نستخدم YOLO مع نفس الجهاز (GPU/CPU)
181
  results = model.predict(
182
  frame_bgr,
183
  conf=CONF_THRESHOLD,
184
  imgsz=IMG_SIZE,
185
  verbose=False,
186
- device=DEVICE, # 👈 هنا
 
187
  )[0]
188
 
189
  annotated, labels = draw_detections(results, frame_bgr, model.names)
@@ -207,19 +237,15 @@ def process_frame(
207
  elapsed = time.time() - last_letter_time
208
 
209
  if elapsed > RESET_DELAY:
210
- # نعتبر الكلمة انتهت
211
  final_text = current_word
212
 
213
- # نضيفها للشات كرسالة من المريض
214
  chat_history.append(["🖐️ من الإشارات", final_text])
215
 
216
- # نرسلها لـ Gemini
217
  gpt_reply = call_gemini_on_word(final_text)
218
 
219
  if gpt_reply:
220
  chat_history.append(["🤖 المساعد", gpt_reply])
221
 
222
- # نرجع نفضّي الحالة
223
  current_word = ""
224
  last_label = None
225
  stable_count = 0
@@ -293,4 +319,6 @@ with gr.Blocks() as demo:
293
 
294
 
295
  if __name__ == "__main__":
296
- demo.launch()
 
 
 
10
  from bidi.algorithm import get_display
11
 
12
  import google.generativeai as genai
13
+ import torch
14
 
15
  # ==========================
16
  # ⚠️ هنا تحط مفتاحك مباشرة
17
  # ==========================
18
 
19
+ GEMINI_API_KEY = "YOUR_GEMINI_API_KEY_HERE" # 👈 استبدله بمفتاحك
20
 
 
21
  genai.configure(api_key=GEMINI_API_KEY)
22
 
23
+ # ==========================
24
+ # إعدادات أداء PyTorch / GPU
25
+ # ==========================
26
+
27
+ # تفعيل تسريع CUDNN
28
+ torch.backends.cudnn.benchmark = True
29
+
30
+ DEVICE = "cuda:0" if torch.cuda.is_available() else "cpu"
31
+ USE_HALF = DEVICE.startswith("cuda")
32
+ print("🔥 Using device:", DEVICE)
33
+
34
  # ==========================
35
  # إعدادات YOLO + الثوابت
36
  # ==========================
 
39
  IMG_SIZE = 256
40
  CONF_THRESHOLD = 0.5
41
 
 
42
  MIN_STABLE_FRAMES = 3
 
43
  WARN_BEFORE_RESET = 1.5
 
44
  RESET_DELAY = 2.5
45
 
 
 
 
 
46
  arabic_map = {
47
  "aleff": "ا", "bb": "ب", "ta": "ت", "thaa": "ث", "jeem": "ج",
48
  "haa": "ح", "khaa": "خ", "dal": "د", "thal": "ذ", "ra": "ر",
 
64
  )
65
 
66
  # ==========================
67
+ # إعداد خط عربي مرة وحدة (بدون تكرار)
68
  # ==========================
69
 
70
+ DEFAULT_FONT_SIZE = 24
71
+ DEFAULT_FONT_PATH = "NotoNaskhArabic-VariableFont_wght.ttf"
 
 
 
 
 
 
 
 
72
 
73
+ try:
74
+ FONT_AR = ImageFont.truetype(DEFAULT_FONT_PATH, DEFAULT_FONT_SIZE)
75
+ except Exception:
76
+ FONT_AR = ImageFont.load_default()
77
 
 
 
 
 
78
 
79
+ def prepare_arabic(text: str) -> str:
80
+ """تجهيز النص العربي (reshaper + bidi) بدون رسم."""
81
+ reshaped = arabic_reshaper.reshape(text)
82
+ bidi_text = get_display(reshaped)
83
+ return bidi_text
84
+
85
 
86
+ # ==========================
87
+ # رسم الديتكشن بشكل أسرع
88
+ # ==========================
89
 
90
  def draw_detections(result, frame, names):
91
+ """
92
+ نرسم البوكسات بـ OpenCV،
93
+ وبعدين نحول الصورة إلى PIL مرة واحدة ونرسم كل النصوص.
94
+ """
95
  boxes = result.boxes
96
  detected_labels = []
97
 
98
  if boxes is None or len(boxes) == 0:
99
  return frame, detected_labels
100
 
101
+ label_infos = []
102
+
103
  for box in boxes:
104
  x1, y1, x2, y2 = map(int, box.xyxy[0])
105
  cls_id = int(box.cls[0])
 
112
  ar_label = arabic_map.get(eng_label, eng_label)
113
  detected_labels.append(ar_label)
114
 
115
+ # رسم البوكس
116
  cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
117
 
118
  label_bg_y1 = max(0, y1 - 35)
 
125
  -1,
126
  )
127
 
128
+ label_infos.append(
129
+ (
130
+ prepare_arabic(ar_label), # نص عربي جاهز للرسم
131
+ x1 + 5,
132
+ label_bg_y1 + 5,
133
+ )
134
+ )
135
 
136
+ # نحول لمرة وحدة إلى PIL ونرسم كل النصوص
137
+ img_pil = Image.fromarray(frame)
138
+ draw = ImageDraw.Draw(img_pil)
139
+
140
+ for bidi_text, tx, ty in label_infos:
141
+ draw.text((tx, ty), bidi_text, font=FONT_AR, fill=(0, 0, 0))
142
+
143
+ return np.array(img_pil), detected_labels
144
 
145
 
146
  # ==========================
147
+ # تحميل YOLO على GPU + half
148
  # ==========================
149
 
150
  print("🔹 Loading YOLO model...")
151
  model = YOLO(WEIGHTS_PATH)
152
+ model.to(DEVICE)
153
+
154
+ # تفعيل half precision لو معنا GPU
155
+ if USE_HALF:
156
+ try:
157
+ model.model.half()
158
+ print("⚡ Using half precision for YOLO on GPU")
159
+ except Exception as e:
160
+ print("⚠️ Could not enable half precision:", e)
161
+
162
  print("📚 Classes:", model.names)
163
 
164
 
 
171
  return ""
172
 
173
  try:
174
+ # flash سريع أصلا، نخليه كما هو
175
  model_g = genai.GenerativeModel("gemini-1.5-flash")
176
 
177
  prompt = (
 
201
  if chat_history is None:
202
  chat_history = []
203
 
204
+ # Gradio يعطينا RGB، نحوله BGR لـ OpenCV
205
  frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
206
+ # نعكس الصورة أفقياً
207
  frame_bgr = cv2.flip(frame_bgr, 1)
208
 
209
+ # YOLO على GPU + نصف دقة لو متوفر
210
  results = model.predict(
211
  frame_bgr,
212
  conf=CONF_THRESHOLD,
213
  imgsz=IMG_SIZE,
214
  verbose=False,
215
+ device=DEVICE,
216
+ half=USE_HALF,
217
  )[0]
218
 
219
  annotated, labels = draw_detections(results, frame_bgr, model.names)
 
237
  elapsed = time.time() - last_letter_time
238
 
239
  if elapsed > RESET_DELAY:
 
240
  final_text = current_word
241
 
 
242
  chat_history.append(["🖐️ من الإشارات", final_text])
243
 
 
244
  gpt_reply = call_gemini_on_word(final_text)
245
 
246
  if gpt_reply:
247
  chat_history.append(["🤖 المساعد", gpt_reply])
248
 
 
249
  current_word = ""
250
  last_label = None
251
  stable_count = 0
 
319
 
320
 
321
  if __name__ == "__main__":
322
+ # لو أنت على Hugging Face Spaces وطلع لك موضوع الـ hot-reload،
323
+ # نقدر نضيف باتش بسيط هنا، بس حالياً نخليها عادية:
324
+ demo.launch(server_name="0.0.0.0", server_port=7860)