EngReem85 commited on
Commit
9d35a29
·
verified ·
1 Parent(s): 649f6b1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +60 -378
app.py CHANGED
@@ -3,387 +3,69 @@ import cv2
3
  import numpy as np
4
  import mediapipe as mp
5
  import tempfile
6
- import os
7
  import math
8
- import traceback
9
- from scipy.stats import variation
10
 
11
- # تهيئة MediaPipe Pose (يوصى باستخدام context manager إذا أردت تشغيل متكرر)
12
  mp_pose = mp.solutions.pose
13
- mp_drawing = mp.solutions.drawing_utils
14
- pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.7, model_complexity=1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
 
16
- def calculate_distance(point1, point2):
17
- return math.hypot(point1[0]-point2[0], point1[1]-point2[1])
18
-
19
- def calculate_angle(a, b, c):
20
- try:
21
- a = np.array(a); b = np.array(b); c = np.array(c)
22
- radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
23
- angle = abs(radians * 180.0 / math.pi)
24
- if angle > 180.0:
25
- angle = 360 - angle
26
- return angle
27
- except Exception:
28
- return 0.0
29
-
30
- def calculate_asymmetry_index(left_values, right_values):
31
- if not left_values or not right_values:
32
- return 0.0
33
- left_mean = float(np.mean(left_values))
34
- right_mean = float(np.mean(right_values))
35
- denom = (left_mean + right_mean) / 2.0
36
- if denom == 0:
37
- return 0.0
38
- return abs(left_mean - right_mean) / denom * 100.0
39
-
40
- def analyze_neurological_gait(video_file, progress=gr.Progress()):
41
- if video_file is None:
42
- return "❌ يرجى رفع فيديو أولاً"
43
- temp_path = None
44
- try:
45
- # حفظ الفيديو مؤقتًا إذا تم رفعه كـ bytes
46
- if hasattr(video_file, "name"):
47
- video_path = video_file.name
48
- else:
49
- tmp = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
50
- tmp.write(video_file)
51
- tmp.flush()
52
- tmp.close()
53
- video_path = tmp.name
54
- temp_path = tmp.name
55
-
56
- progress(0.05, desc="🔍 جاري فتح الفيديو...")
57
- cap = cv2.VideoCapture(video_path)
58
- if not cap.isOpened():
59
- return "❌ لا يمكن فتح الفيديو"
60
-
61
- total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) or 0
62
- fps = cap.get(cv2.CAP_PROP_FPS) or 0
63
- if fps <= 0 or fps > 1000:
64
- fps = 30.0 # fallback
65
- frame_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) or 640
66
- frame_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) or 480
67
-
68
- # محاولة تحسين تقدير pixel->meter:
69
- # إذا أمكن الحصول على landmark رأس-كعب أو ارتفاع تقريبي من الميدان استخدمها،
70
- # وإلا استخدم افتراض 1.70 m كنقطة بداية (تقريبي).
71
- estimated_person_height_pixels = frame_height * 0.8 if frame_height > 0 else 384
72
- pixel_to_meter_ratio = 1.7 / estimated_person_height_pixels if estimated_person_height_pixels > 0 else 1.7/384
73
-
74
- analysis_data = {
75
- 'gait_speed': [], 'cadence': [],
76
- 'step_length_left': [], 'step_length_right': [],
77
- 'stride_length_left': [], 'stride_length_right': [],
78
- 'base_width': [], 'gait_cycle_time': [],
79
- 'step_time_left': [], 'step_time_right': [],
80
- 'stride_time_left': [], 'stride_time_right': [],
81
- 'double_support_time': [], 'single_support_time_left': [], 'single_support_time_right': [],
82
- 'ankle_angle_heel_strike_left': [], 'ankle_angle_heel_strike_right': [],
83
- 'ankle_angle_toe_off_left': [], 'ankle_angle_toe_off_right': [],
84
- 'foot_clearance_left': [], 'foot_clearance_right': [],
85
- 'foot_progression_angle_left': [], 'foot_progression_angle_right': [],
86
- 'left_foot_contact': [], 'right_foot_contact': []
87
- }
88
-
89
- prev_left_ankle = None
90
- prev_right_ankle = None
91
- prev_left_heel = None
92
- prev_right_heel = None
93
-
94
- left_step_start = None
95
- right_step_start = None
96
- last_double_support_start = None
97
- in_double_support = False
98
-
99
- left_foot_ground_contact = False
100
- right_foot_ground_contact = False
101
-
102
- frames_processed = 0
103
- person_detected = False
104
-
105
- progress(0.1, desc="🔬 جاري تحليل إطارات الفيديو...")
106
- max_frames = min(500, total_frames) if total_frames > 0 else 500
107
-
108
- while cap.isOpened() and frames_processed < max_frames:
109
- ret, frame = cap.read()
110
- if not ret:
111
- break
112
- current_time = frames_processed / fps
113
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
114
- results = pose.process(frame_rgb)
115
-
116
- if results.pose_landmarks:
117
- person_detected = True
118
- landmarks = results.pose_landmarks.landmark
119
-
120
- # استخراج نقاط مهمة وتحويلها لبكسل
121
- def lm(idx):
122
- return [landmarks[idx].x * frame_width, landmarks[idx].y * frame_height]
123
-
124
- left_ankle = lm(mp_pose.PoseLandmark.LEFT_ANKLE.value)
125
- right_ankle = lm(mp_pose.PoseLandmark.RIGHT_ANKLE.value)
126
- left_knee = lm(mp_pose.PoseLandmark.LEFT_KNEE.value)
127
- right_knee = lm(mp_pose.PoseLandmark.RIGHT_KNEE.value)
128
- left_heel = lm(mp_pose.PoseLandmark.LEFT_HEEL.value)
129
- right_heel = lm(mp_pose.PoseLandmark.RIGHT_HEEL.value)
130
- left_foot_index = lm(mp_pose.PoseLandmark.LEFT_FOOT_INDEX.value)
131
- right_foot_index = lm(mp_pose.PoseLandmark.RIGHT_FOOT_INDEX.value)
132
-
133
- # تلامس الأرض (عتبة تقريبية)
134
- ground_threshold = frame_height * 0.92
135
- current_left_contact = left_ankle[1] >= ground_threshold
136
- current_right_contact = right_ankle[1] >= ground_threshold
137
-
138
- # عرض القاعدة
139
- base_width = abs(left_ankle[0] - right_ankle[0]) * pixel_to_meter_ratio
140
- analysis_data['base_width'].append(base_width)
141
-
142
- # زوايا الكاحل
143
- left_ankle_angle_hs = calculate_angle(left_knee, left_ankle, left_foot_index)
144
- right_ankle_angle_hs = calculate_angle(right_knee, right_ankle, right_foot_index)
145
- left_ankle_angle_to = calculate_angle(left_heel, left_ankle, left_knee)
146
- right_ankle_angle_to = calculate_angle(right_heel, right_ankle, right_knee)
147
-
148
- analysis_data['ankle_angle_heel_strike_left'].append(left_ankle_angle_hs)
149
- analysis_data['ankle_angle_heel_strike_right'].append(right_ankle_angle_hs)
150
- analysis_data['ankle_angle_toe_off_left'].append(left_ankle_angle_to)
151
- analysis_data['ankle_angle_toe_off_right'].append(right_ankle_angle_to)
152
-
153
- # ارتفاع القدم (سم)
154
- left_foot_clearance = max(0.0, (ground_threshold - min(left_ankle[1], left_foot_index[1])) * pixel_to_meter_ratio * 100.0)
155
- right_foot_clearance = max(0.0, (ground_threshold - min(right_ankle[1], right_foot_index[1])) * pixel_to_meter_ratio * 100.0)
156
- analysis_data['foot_clearance_left'].append(left_foot_clearance)
157
- analysis_data['foot_clearance_right'].append(right_foot_clearance)
158
-
159
- # زاوية تقدم القدم
160
- left_foot_vector = [left_foot_index[0] - left_heel[0], left_foot_index[1] - left_heel[1]]
161
- right_foot_vector = [right_foot_index[0] - right_heel[0], right_foot_index[1] - right_heel[1]]
162
- left_foot_angle = math.degrees(math.atan2(left_foot_vector[1], left_foot_vector[0]))
163
- right_foot_angle = math.degrees(math.atan2(right_foot_vector[1], right_foot_vector[0]))
164
- analysis_data['foot_progression_angle_left'].append(left_foot_angle)
165
- analysis_data['foot_progression_angle_right'].append(right_foot_angle)
166
-
167
- # توقيت بداية الخطوة
168
- if current_left_contact and not left_foot_ground_contact:
169
- if left_step_start is not None:
170
- step_time = current_time - left_step_start
171
- analysis_data['step_time_left'].append(step_time)
172
- left_step_start = current_time
173
-
174
- if current_right_contact and not right_foot_ground_contact:
175
- if right_step_start is not None:
176
- step_time = current_time - right_step_start
177
- analysis_data['step_time_right'].append(step_time)
178
- right_step_start = current_time
179
-
180
- # طولي الخطوة (باستخدام الكاحل السابق للقدم المقابلة)
181
- if prev_left_ankle is not None and prev_right_ankle is not None:
182
- if current_left_contact and not left_foot_ground_contact:
183
- step_length = calculate_distance(left_ankle, prev_right_ankle) * pixel_to_meter_ratio
184
- analysis_data['step_length_left'].append(step_length)
185
- if current_right_contact and not right_foot_ground_contact:
186
- step_length = calculate_distance(right_ankle, prev_left_ankle) * pixel_to_meter_ratio
187
- analysis_data['step_length_right'].append(step_length)
188
-
189
- # حساب الدعم المزدوج بشكل صحيح (تسجيل مدة كل حدث)
190
- if current_left_contact and current_right_contact:
191
- if not in_double_support:
192
- # بداية مرحلة دعم مزدوج
193
- in_double_support = True
194
- last_double_support_start = current_time
195
- else:
196
- if in_double_support and last_double_support_start is not None:
197
- # انتهاء مرحلة دعم مزدوج: سجل المدة
198
- duration = current_time - last_double_support_start
199
- analysis_data['double_support_time'].append(duration)
200
- in_double_support = False
201
- last_double_support_start = None
202
-
203
- # تحديث الحالات والقيم السابقة
204
- left_foot_ground_contact = current_left_contact
205
- right_foot_ground_contact = current_right_contact
206
- analysis_data['left_foot_contact'].append(1 if current_left_contact else 0)
207
- analysis_data['right_foot_contact'].append(1 if current_right_contact else 0)
208
-
209
- prev_left_ankle = left_ankle
210
- prev_right_ankle = right_ankle
211
- prev_left_heel = left_heel
212
- prev_right_heel = right_heel
213
-
214
- frames_processed += 1
215
-
216
- # تحديث التقدّم
217
- if frames_processed % 50 == 0:
218
- progress(0.1 + (frames_processed / max_frames) * 0.7,
219
- desc=f"🔬 جاري تحليل الإطارات... ({frames_processed}/{max_frames})")
220
-
221
- cap.release()
222
-
223
- if not person_detected:
224
- return "❌ لم يتم اكتشاف شخص في الفيديو"
225
-
226
- progress(0.85, desc="📊 حساب المؤشرات الإحصائية...")
227
-
228
- def safe_mean(data):
229
- return float(np.mean(data)) if data else 0.0
230
- def safe_std(data):
231
- return float(np.std(data)) if data else 0.0
232
- def safe_cv(data):
233
- if not data or len(data) < 2 or np.mean(data) == 0:
234
- return 0.0
235
- return (np.std(data) / np.mean(data)) * 100.0
236
-
237
- total_time = frames_processed / fps if fps > 0 else frames_processed / 30.0
238
- total_steps = (len(analysis_data['step_time_left']) + len(analysis_data['step_time_right'])) / 2.0
239
- cadence = (total_steps / total_time) * 60.0 if total_time > 0 else 0.0
240
-
241
- avg_step_length = safe_mean(analysis_data['step_length_left'] + analysis_data['step_length_right'])
242
- gait_speed = (cadence * avg_step_length) / 60.0 # m/s
243
-
244
- avg_step_time = safe_mean(analysis_data['step_time_left'] + analysis_data['step_time_right'])
245
- gait_cycle_time = avg_step_time * 2.0 if avg_step_time > 0 else 0.0
246
-
247
- total_double_support = safe_mean(analysis_data['double_support_time']) if analysis_data['double_support_time'] else 0.0
248
- double_support_percentage = (total_double_support / gait_cycle_time) * 100.0 if gait_cycle_time > 0 else 0.0
249
-
250
- step_length_cv = safe_cv(analysis_data['step_length_left'] + analysis_data['step_length_right'])
251
-
252
- asymmetry_indicators = {
253
- 'طول الخطوة': calculate_asymmetry_index(analysis_data['step_length_left'], analysis_data['step_length_right']),
254
- 'زمن الخطوة': calculate_asymmetry_index(analysis_data['step_time_left'], analysis_data['step_time_right']),
255
- 'زاوية الهبوط': calculate_asymmetry_index(analysis_data['ankle_angle_heel_strike_left'], analysis_data['ankle_angle_heel_strike_right']),
256
- 'زاوية الدفع': calculate_asymmetry_index(analysis_data['ankle_angle_toe_off_left'], analysis_data['ankle_angle_toe_off_right']),
257
- 'ارتفاع القدم': calculate_asymmetry_index(analysis_data['foot_clearance_left'], analysis_data['foot_clearance_right'])
258
- }
259
-
260
- avg_ankle_hs_left = safe_mean(analysis_data['ankle_angle_heel_strike_left'])
261
- avg_ankle_hs_right = safe_mean(analysis_data['ankle_angle_heel_strike_right'])
262
- avg_ankle_to_left = safe_mean(analysis_data['ankle_angle_toe_off_left'])
263
- avg_ankle_to_right = safe_mean(analysis_data['ankle_angle_toe_off_right'])
264
- avg_foot_clearance_left = safe_mean(analysis_data['foot_clearance_left'])
265
- avg_foot_clearance_right = safe_mean(analysis_data['foot_clearance_right'])
266
- avg_base_width = safe_mean(analysis_data['base_width'])
267
- avg_foot_angle_left = safe_mean(analysis_data['foot_progression_angle_left'])
268
- avg_foot_angle_right = safe_mean(analysis_data['foot_progression_angle_right'])
269
-
270
- affected_side = "اليمين" if (avg_ankle_hs_right < avg_ankle_hs_left or avg_foot_clearance_right < avg_foot_clearance_left) else "اليسار"
271
-
272
- # قواعد تشخيص تجريبية (يمكن تعديلها طبياً)
273
- risk_factors = 0
274
- if gait_speed < 0.8: risk_factors += 1
275
- if cadence < 90: risk_factors += 1
276
- if asymmetry_indicators['طول الخطوة'] > 15: risk_factors += 1
277
- if asymmetry_indicators['زاوية الهبوط'] > 20: risk_factors += 1
278
- if double_support_percentage > 25: risk_factors += 1
279
- if step_length_cv > 15: risk_factors += 1
280
- if (affected_side == "اليمين" and avg_ankle_hs_right < 80) or (affected_side == "اليسار" and avg_ankle_hs_left < 80):
281
- risk_factors += 2
282
-
283
- risk_percentage = min(95, risk_factors * 15)
284
-
285
- if risk_factors >= 5:
286
- diagnosis = "🩺 احتمال قوي لإصابة عصبية"
287
- risk_level = "عالية جداً"
288
- elif risk_factors >= 3:
289
- diagnosis = "🩺 احتمال إصابة عصبية"
290
- risk_level = "عالية"
291
- elif risk_factors >= 2:
292
- diagnosis = "⚠️ مؤشرات تستدعي الانتباه"
293
- risk_level = "متوسطة"
294
- else:
295
- diagnosis = "✅ المشية ضمن الطبيعي"
296
- risk_level = "منخفضة"
297
-
298
- progress(1.0, desc="✅ اكتمل التحليل!")
299
-
300
- report = f"""
301
- # 📊 التقرير الشامل لتحليل المشية
302
- ## 🩺 التشخيص:
303
- **{diagnosis}**
304
- ## 📊 نسبة الخطورة:
305
- **{risk_percentage}%** - مستوى خطورة **{risk_level}**
306
- ## 📍 الجانب المتأثر:
307
- **{affected_side}**
308
- ## 📈 المؤشرات الكمية:
309
- ### 1. السرعة والتواتر:
310
- - **سرعة المشي**: {gait_speed:.2f} م/ث
311
- - **تواتر الخطوات**: {cadence:.1f} خطوة/دقيقة
312
- ### 2. أطوال الخطوات:
313
- - **طول الخطوة اليمنى**: {safe_mean(analysis_data['step_length_right']):.3f} م
314
- - **طول الخطوة اليسرى**: {safe_mean(analysis_data['step_length_left']):.3f} م
315
- - **تذبذب طول الخطوة**: {step_length_cv:.1f}%
316
- ### 3. الأبعاد والزوايا:
317
- - **عرض القاعدة**: {avg_base_width:.3f} م
318
- - **زمن الدورة الكاملة**: {gait_cycle_time:.2f} ثانية
319
- - **نسبة الدعم المزدوج**: {double_support_percentage:.1f}%
320
- ### 4. زوايا الكاحل:
321
- - **زاوية الهبوط - اليمنى**: {avg_ankle_hs_right:.1f}°
322
- - **زاوية الهبوط - اليسرى**: {avg_ankle_hs_left:.1f}°
323
- - **زاوية الدفع - اليمنى**: {avg_ankle_to_right:.1f}°
324
- - **زاوية الدفع - اليسرى**: {avg_ankle_to_left:.1f}°
325
- ### 5. ارتفاع القدم:
326
- - **الارتفاع - اليمنى**: {avg_foot_clearance_right:.1f} سم
327
- - **الارتفاع - اليسرى**: {avg_foot_clearance_left:.1f} سم
328
- ### 6. عدم التناسق بين الجانبين:
329
- {chr(10).join([f"- {key}: {value:.1f}%" for key, value in asymmetry_indicators.items()])}
330
- ## 💡 ط��يقة التصوير المثالية:
331
- - 📹 فيديو **جانبي** واضح للمشي
332
- - 👣 إظهار **القدمين والساقين** بالكامل
333
- - 🚶 المشي **الطبيعي** لمسافة كافية
334
- - ⏱️ مدة **15-30 ثانية**
335
- - 💡 إضاءة **جيدة** وخلفية بسيطة
336
- ## 🎯 الإجراء المقترح:
337
- {("🔄 مراجعة طبيب أعصاب متخصص" if risk_percentage >= 60 else
338
- "👁️ مراجعة طبية للتقييم الدقيق" if risk_percentage >= 40 else
339
- "👁️ المتابعة الدورية")}
340
- ---
341
- *تم تحليل {frames_processed} إطار بسرعة {fps:.1f} إطار/ثانية*
342
- """
343
- return report
344
-
345
- except Exception as e:
346
- tb = traceback.format_exc()
347
- return f"❌ خطأ في التحليل: {str(e)}\n\nتفاصيل:\n{tb}"
348
- finally:
349
- try:
350
- if temp_path and os.path.exists(temp_path):
351
- os.unlink(temp_path)
352
- except Exception:
353
- pass
354
- try:
355
- pose.close()
356
- except Exception:
357
- pass
358
-
359
- # واجهة التطبيق (لم أتغيّر كثيراً عن ما لديك)
360
- with gr.Blocks(title="التحليل الشامل للمشية العصبية", theme=gr.themes.Soft()) as demo:
361
- gr.Markdown("# 🩺 النظام الشامل لتحليل المشية العصبية")
362
- gr.Markdown("## تحليل كمي دقيق لجميع مؤشرات المشية العصبية")
363
- with gr.Row():
364
- with gr.Column(scale=1):
365
- gr.Markdown("### 📹 رفع فيديو المشي")
366
- gr.Markdown("""
367
- **لتحليل دقيق يرجى:**
368
- - فيديو جانبي واضح
369
- - ظهور القدمين كاملين
370
- - المشي الطبيعي
371
- - إضاءة جيدة
372
- - مدة 15-30 ثانية
373
- """)
374
- video_input = gr.File(
375
- label="اختر ملف الفيديو",
376
- file_types=[".mp4", ".avi", ".mov"],
377
- type="binary"
378
- )
379
- analyze_btn = gr.Button("بدء التحليل الشامل", variant="primary")
380
- with gr.Column(scale=2):
381
- gr.Markdown("### 📋 التقرير الشامل")
382
- output_report = gr.Markdown(value="**سيظهر هنا التقرير الكامل مع جميع المؤشرات**")
383
-
384
- analyze_btn.click(fn=analyze_neurological_gait, inputs=[video_input], outputs=[output_report])
385
-
386
- if __name__ == "__main__":
387
- demo.launch(server_name="0.0.0.0", server_port=7860)
388
 
389
 
 
3
  import numpy as np
4
  import mediapipe as mp
5
  import tempfile
 
6
  import math
 
 
7
 
 
8
  mp_pose = mp.solutions.pose
9
+ pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5)
10
+
11
+ def analyze_gait(video):
12
+ cap = cv2.VideoCapture(video)
13
+ step_count = 0
14
+ right_ankle_y, left_ankle_y = [], []
15
+
16
+ while cap.isOpened():
17
+ ret, frame = cap.read()
18
+ if not ret:
19
+ break
20
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
21
+ result = pose.process(frame_rgb)
22
+
23
+ if result.pose_landmarks:
24
+ landmarks = result.pose_landmarks.landmark
25
+ right_ankle = landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE]
26
+ left_ankle = landmarks[mp_pose.PoseLandmark.LEFT_ANKLE]
27
+ right_ankle_y.append(right_ankle.y)
28
+ left_ankle_y.append(left_ankle.y)
29
+
30
+ cap.release()
31
+
32
+ if len(right_ankle_y) < 10 or len(left_ankle_y) < 10:
33
+ return "لم يتم اكتشاف مشية واضحة في الفيديو.", None
34
+
35
+ # تحليل الاختلاف بين القدمين
36
+ diff = np.std(np.array(right_ankle_y) - np.array(left_ankle_y))
37
+ avg_right = np.mean(right_ankle_y)
38
+ avg_left = np.mean(left_ankle_y)
39
+
40
+ # مؤشرات تشخيصية بسيطة
41
+ if diff > 0.05 and abs(avg_right - avg_left) > 0.03:
42
+ diagnosis = "يبدو وجود عدم توازن واضح بين القدمين وقد يشير ذلك إلى اعتلال الأعصاب المحيطية أو قدم شاركوت.\nينصح بمراجعة الطبيب المختص."
43
+ elif np.mean(right_ankle_y) > 0.55 or np.mean(left_ankle_y) > 0.55:
44
+ diagnosis = "ارتفاع القدم أثناء المشي يدل على احتمال وجود Foot Drop (ضعف العضلة الظنبوبية الأمامية).\nينصح بمراجعة الطبيب."
45
+ else:
46
+ diagnosis = "المشية تبدو شبه طبيعية، مع ملاحظة خفيفة في الاتزان.\nيمكن المتابعة مع الطبيب إذا استمرت الأعراض."
47
+
48
+ # زر الحجز
49
+ button_html = """
50
+ <a href="https://www.mayoclinic.org/ar/patient-care-and-health-information"
51
+ target="_blank"
52
+ style="background-color:#4CAF50;color:white;padding:10px 20px;
53
+ text-decoration:none;border-radius:10px;display:inline-block;margin-top:10px;">
54
+ احجز موعد مع الطبيب
55
+ </a>
56
+ """
57
+
58
+ return f"<div style='font-size:18px'>{diagnosis}</div>{button_html}"
59
+
60
+ demo = gr.Interface(
61
+ fn=analyze_gait,
62
+ inputs=gr.Video(label="ارفع مقطع فيديو لمشيك"),
63
+ outputs=gr.HTML(label="نتيجة التحليل"),
64
+ title="تحليل المشية الذكي – الكشف عن الحالات العصبية والعضلية",
65
+ description="يرجى رفع فيديو قصير أثناء المشي، سيقوم النظام بتحليل نمط المشي لتقدير وجود مؤشرات مثل Foot Drop أو قدم شاركوت أو اعتلال الأعصاب."
66
+ )
67
+
68
+ demo.launch()
69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71