EngReem85 commited on
Commit
6c159a9
·
verified ·
1 Parent(s): a93c69b

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +203 -192
app.py CHANGED
@@ -1,208 +1,219 @@
1
- import gradio as gr
2
- import cv2
3
  import numpy as np
4
- import tempfile
 
 
 
5
  import os
6
  import math
7
- import sys
8
 
9
- try:
10
- import mediapipe as mp
11
- mp_pose = mp.solutions.pose
12
- pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5)
13
- MEDIAPIPE_AVAILABLE = True
14
- except ImportError:
15
- MEDIAPIPE_AVAILABLE = False
16
- print("MediaPipe not available - using fallback mode")
17
 
18
- def calculate_distance(point1, point2):
19
- """حساب المسافة بين نقطتين"""
20
- return math.sqrt((point1[0]-point2[0])**2 + (point1[1]-point2[1])**2)
 
21
 
22
- def analyze_gait_with_risk_score(video_file):
23
- """
24
- تحليل المشية مع تقييم مفصل لمستوى الخطورة
25
- """
26
- if not MEDIAPIPE_AVAILABLE:
27
- return " المكتبات المطلوبة غير مثبتة. يرجى التحقق من تثبيت المتطلبات."
28
-
29
- # حفظ الفيديو المؤقت
30
- temp_video = tempfile.NamedTemporaryFile(delete=False, suffix=".mp4")
31
-
32
- try:
33
- temp_video.write(video_file.read())
34
- temp_video.close()
35
-
36
- cap = cv2.VideoCapture(temp_video.name)
37
- if not cap.isOpened():
38
- return " لا يمكن فتح ملف الفيديو"
39
-
40
- frame_count = 0
41
- gait_metrics = {
42
- 'shoulder_movement': [], 'hip_movement': [], 'posture_stability': [],
43
- 'stride_consistency': [], 'knee_alignment': [], 'arm_swing': [],
44
- 'head_stability': [], 'gait_symmetry': []
45
- }
46
-
47
- previous_left_ankle = None
48
- previous_right_ankle = None
49
-
50
- while cap.isOpened():
51
- ret, frame = cap.read()
52
- if not ret:
53
- break
54
-
55
- try:
56
- frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
57
- results = pose.process(frame_rgb)
58
-
59
- if results.pose_landmarks:
60
- landmarks = results.pose_landmarks.landmark
61
-
62
- # استخراج النقاط الرئيسية
63
- left_shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
64
- landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
65
- right_shoulder = [landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].x,
66
- landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value].y]
67
- left_hip = [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,
68
- landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
69
- right_hip = [landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].x,
70
- landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value].y]
71
- left_knee = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x,
72
- landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].y]
73
- right_knee = [landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value].x,
74
- landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value].y]
75
- left_ankle = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].x,
76
- landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].y]
77
- right_ankle = [landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value].x,
78
- landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value].y]
79
- left_elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].x,
80
- landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value].y]
81
- right_elbow = [landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].x,
82
- landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value].y]
83
-
84
- # تحليل المقاييس
85
- shoulder_movement = abs(left_shoulder[1] - right_shoulder[1])
86
- hip_movement = abs(left_hip[1] - right_hip[1])
87
- center_of_gravity = (left_hip[1] + right_hip[1]) / 2
88
- arm_swing = abs(left_elbow[0] - right_elbow[0])
89
- knee_alignment = abs(left_knee[1] - right_knee[1])
90
-
91
- gait_metrics['shoulder_movement'].append(shoulder_movement)
92
- gait_metrics['hip_movement'].append(hip_movement)
93
- gait_metrics['posture_stability'].append(center_of_gravity)
94
- gait_metrics['arm_swing'].append(arm_swing)
95
- gait_metrics['knee_alignment'].append(knee_alignment)
96
-
97
- # تحليل تناسق الخطوات
98
- if previous_left_ankle and previous_right_ankle:
99
- left_stride = calculate_distance(left_ankle, previous_left_ankle)
100
- right_stride = calculate_distance(right_ankle, previous_right_ankle)
101
- stride_symmetry = abs(left_stride - right_stride)
102
- gait_metrics['gait_symmetry'].append(stride_symmetry)
103
-
104
- previous_left_ankle = left_ankle
105
- previous_right_ankle = right_ankle
106
-
107
- frame_count += 1
108
-
109
- except Exception as e:
110
- continue # تخطي الإطار في حالة خطأ
111
-
112
- cap.release()
113
-
114
- if frame_count == 0:
115
- return " لم يتم اكتشاف أي شخص في الفيديو. يرجى التأكد من ظهور الشخص بوضوح."
116
-
117
- # حساب النتائج
118
- risk_scores = {}
119
- for metric, values in gait_metrics.items():
120
- if values:
121
- avg_value = np.mean(values)
122
- # تحويل إلى درجة (0-100)
123
- if metric == 'shoulder_movement':
124
- risk_scores[metric] = max(0, 100 - (avg_value * 2000))
125
- elif metric == 'hip_movement':
126
- risk_scores[metric] = 90 if 0.02 < avg_value < 0.08 else max(0, 100 - (abs(avg_value - 0.05) * 3000))
127
- elif metric == 'posture_stability':
128
- stability_std = np.std(values) if len(values) > 1 else 0
129
- risk_scores[metric] = max(0, 100 - (stability_std * 5000))
130
- elif metric == 'arm_swing':
131
- risk_scores[metric] = 85 if 0.1 < avg_value < 0.3 else max(0, 100 - (abs(avg_value - 0.2) * 400))
132
- elif metric == 'knee_alignment':
133
- risk_scores[metric] = max(0, 100 - (avg_value * 4000))
134
- elif metric == 'gait_symmetry':
135
- risk_scores[metric] = max(0, 100 - (avg_value * 10000))
136
-
137
- # حساب النتيجة الإجمالية
138
- if risk_scores:
139
- total_risk_score = np.mean(list(risk_scores.values()))
140
- else:
141
- total_risk_score = 0
142
 
143
- # تحديد مستوى الخطر
144
- if total_risk_score >= 80:
145
- risk_level = "🟢 منخفض"
146
- recommendation = "المشية طبيعية ولا توجد مؤشرات خطيرة"
147
- elif total_risk_score >= 60:
148
- risk_level = "🟡 متوسط"
149
- recommendation = "هناك بعض الملاحظات البسيطة التي تحتاج للمراقبة"
150
- elif total_risk_score >= 40:
151
- risk_level = "🟠 مرتفع"
152
- recommendation = "يوجد خلل واضح في المشية - يوصى بالمتابعة مع أخصائي"
153
- else:
154
- risk_level = "🔴 عالي جداً"
155
- recommendation = "خلل شديد في المشية - ضرورة مراجعة أخصائي علاج طبيعي فوراً"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
- return f"""
158
- # تقرير تحليل المشية
 
 
 
 
 
 
159
 
160
- ## النتيجة الإجمالية: {total_risk_score:.1f}/100
161
- ## مستوى الخطورة: {risk_level}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
 
163
- ## التوصية:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  {recommendation}
165
 
166
- ## الإحصائيات:
167
- - عدد الإطارات المحللة: {frame_count}
168
- - عدد المقاييس المستخدمة: {len(risk_scores)}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
170
- ---
171
- **ملاحظة:** هذا تحليل أولي ولا يغني عن التشخيص الطبي المتخصص.
172
  """
173
-
174
- except Exception as e:
175
- return f" حدث خطأ أثناء معالجة الفيديو: {str(e)}"
176
-
177
- finally:
178
- # تنظيف الملف المؤقت
179
- if os.path.exists(temp_video.name):
180
- try:
181
- os.unlink(temp_video.name)
182
- except:
183
- pass
184
 
185
- # إنشاء الواجهة
186
- with gr.Blocks(theme=gr.themes.Soft(), title="تحليل المشية") as demo:
187
- gr.Markdown("# نظام تحليل المشية")
188
-
189
- with gr.Row():
190
- with gr.Column():
191
- video_input = gr.File(
192
- label=" رفع فيديو المشي",
193
- file_types=[".mp4", ".avi", ".mov"],
194
- type="binary"
195
- )
196
- analyze_btn = gr.Button("🔍 بدء التحليل", variant="primary")
197
-
198
- with gr.Column():
199
- output_text = gr.Markdown(label=" التقرير")
200
-
201
- analyze_btn.click(
202
- fn=analyze_gait_with_risk_score,
203
- inputs=video_input,
204
- outputs=output_text
205
- )
206
 
207
- if __name__ == "__main__":
208
- demo.launch(share=True, show_error=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # التحقق من الإصدارات أولاً
 
2
  import numpy as np
3
+ import cv2
4
+ import matplotlib.pyplot as plt
5
+ import mediapipe as mp
6
+ from google.colab import files
7
  import os
8
  import math
 
9
 
 
 
 
 
 
 
 
 
10
 
11
+ def is_video_file(filename):
12
+ """التحقق مما إذا كان الملف فيديو"""
13
+ video_extensions = ['.mp4', '.avi', '.mov', '.mkv', '.wmv', '.flv']
14
+ return any(filename.lower().endswith(ext) for ext in video_extensions)
15
 
16
+ def is_image_file(filename):
17
+ """التحقق مما إذا كان الملف صورة"""
18
+ image_extensions = ['.png', '.jpg', '.jpeg', '.bmp', '.tiff']
19
+ return any(filename.lower().endswith(ext) for ext in image_extensions)
20
+
21
+ def analyze_video_gait(video_path):
22
+ cap = cv2.VideoCapture(video_path)
23
+
24
+ if not cap.isOpened():
25
+ return None, 0
26
+
27
+ gait_metrics = {
28
+ 'shoulder_movement': [], 'hip_movement': [], 'posture_stability': [],
29
+ 'knee_alignment': [], 'arm_swing': [], 'gait_symmetry': []
30
+ }
31
+
32
+ frame_count = 0
33
+ previous_left_ankle = None
34
+ previous_right_ankle = None
35
+
36
+ print("🎬 بدء تحليل الفيديو...")
37
+
38
+ mp_pose = mp.solutions.pose
39
+ pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5)
40
+
41
+ while cap.isOpened():
42
+ ret, frame = cap.read()
43
+ if not ret:
44
+ break
45
+
46
+ frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
47
+ results = pose.process(frame_rgb)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
 
49
+ if results.pose_landmarks:
50
+ landmarks = results.pose_landmarks.landmark
51
+
52
+ # استخراج النقاط الرئيسية
53
+ left_shoulder = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER].y]
54
+ right_shoulder = [landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].x, landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER].y]
55
+ left_hip = [landmarks[mp_pose.PoseLandmark.LEFT_HIP].x, landmarks[mp_pose.PoseLandmark.LEFT_HIP].y]
56
+ right_hip = [landmarks[mp_pose.PoseLandmark.RIGHT_HIP].x, landmarks[mp_pose.PoseLandmark.RIGHT_HIP].y]
57
+ left_knee = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE].x, landmarks[mp_pose.PoseLandmark.LEFT_KNEE].y]
58
+ right_knee = [landmarks[mp_pose.PoseLandmark.RIGHT_KNEE].x, landmarks[mp_pose.PoseLandmark.RIGHT_KNEE].y]
59
+ left_ankle = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE].x, landmarks[mp_pose.PoseLandmark.LEFT_ANKLE].y]
60
+ right_ankle = [landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE].x, landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE].y]
61
+ left_elbow = [landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].x, landmarks[mp_pose.PoseLandmark.LEFT_ELBOW].y]
62
+ right_elbow = [landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].x, landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW].y]
63
+
64
+ # حساب المقاييس
65
+ shoulder_movement = abs(left_shoulder[1] - right_shoulder[1])
66
+ hip_movement = abs(left_hip[1] - right_hip[1])
67
+ center_of_gravity = (left_hip[1] + right_hip[1]) / 2
68
+ arm_swing = abs(left_elbow[0] - right_elbow[0])
69
+ knee_alignment = abs(left_knee[1] - right_knee[1])
70
+
71
+ gait_metrics['shoulder_movement'].append(shoulder_movement)
72
+ gait_metrics['hip_movement'].append(hip_movement)
73
+ gait_metrics['posture_stability'].append(center_of_gravity)
74
+ gait_metrics['arm_swing'].append(arm_swing)
75
+ gait_metrics['knee_alignment'].append(knee_alignment)
76
+
77
+ if previous_left_ankle and previous_right_ankle:
78
+ left_stride = math.sqrt((left_ankle[0]-previous_left_ankle[0])**2 + (left_ankle[1]-previous_left_ankle[1])**2)
79
+ right_stride = math.sqrt((right_ankle[0]-previous_right_ankle[0])**2 + (right_ankle[1]-previous_right_ankle[1])**2)
80
+ stride_symmetry = abs(left_stride - right_stride)
81
+ gait_metrics['gait_symmetry'].append(stride_symmetry)
82
+
83
+ previous_left_ankle = left_ankle
84
+ previous_right_ankle = right_ankle
85
+
86
+ frame_count += 1
87
 
88
+ if frame_count % 50 == 0:
89
+ print(f"📊 تم تحليل {frame_count} إطار...")
90
+
91
+ cap.release()
92
+ pose.close()
93
+ print(f"✅ اكتمل تحليل {frame_count} إطار")
94
+
95
+ return gait_metrics, frame_count
96
 
97
+ def calculate_risk_scores(gait_metrics, frame_count):
98
+ if frame_count == 0:
99
+ return None
100
+
101
+ risk_scores = {}
102
+
103
+ for metric, values in gait_metrics.items():
104
+ if values:
105
+ avg_value = np.mean(values)
106
+
107
+ if metric == 'shoulder_movement':
108
+ risk_scores[metric] = max(0, 100 - (avg_value * 2000))
109
+ elif metric == 'hip_movement':
110
+ if 0.02 < avg_value < 0.08:
111
+ risk_scores[metric] = 90
112
+ else:
113
+ risk_scores[metric] = max(0, 100 - (abs(avg_value - 0.05) * 3000))
114
+ elif metric == 'posture_stability':
115
+ stability_std = np.std(values) if len(values) > 1 else 0
116
+ risk_scores[metric] = max(0, 100 - (stability_std * 5000))
117
+ elif metric == 'arm_swing':
118
+ if 0.1 < avg_value < 0.3:
119
+ risk_scores[metric] = 85
120
+ else:
121
+ risk_scores[metric] = max(0, 100 - (abs(avg_value - 0.2) * 400))
122
+ elif metric == 'knee_alignment':
123
+ risk_scores[metric] = max(0, 100 - (avg_value * 4000))
124
+ elif metric == 'gait_symmetry':
125
+ risk_scores[metric] = max(0, 100 - (avg_value * 10000))
126
+
127
+ return risk_scores
128
 
129
+ def generate_report(risk_scores, frame_count):
130
+ if not risk_scores:
131
+ return "❌ لا توجد بيانات كافية لتحليل المشية"
132
+
133
+ total_risk_score = np.mean(list(risk_scores.values()))
134
+
135
+ if total_risk_score >= 80:
136
+ risk_level = "🟢 منخفض"
137
+ recommendation = "المشية طبيعية ولا توجد مؤشرات خطيرة"
138
+ elif total_risk_score >= 60:
139
+ risk_level = "🟡 متوسط"
140
+ recommendation = "هناك بعض الملاحظات البسيطة التي تحتاج للمراقبة"
141
+ elif total_risk_score >= 40:
142
+ risk_level = "🟠 مرتفع"
143
+ recommendation = "يوجد خلل واضح في المشية - يوصى بالمتابعة مع أخصائي"
144
+ else:
145
+ risk_level = "🔴 عالي جداً"
146
+ recommendation = "خلل شديد في المشية - ضرورة مراجعة أخصائي علاج طبيعي فوراً"
147
+
148
+ report = f"""
149
+ 📊 تقرير تحليل المشية مع تقييم الخطر
150
+ {'='*50}
151
+
152
+ 🎯 النتيجة الإجمالية: {total_risk_score:.1f}/100
153
+ 📈 مستوى الخطورة: {risk_level}
154
+
155
+ 💡 التوصية:
156
  {recommendation}
157
 
158
+ 🔍 تحليل مفصل للنقاط:
159
+ {'─'*30}
160
+ """
161
+
162
+ metric_names = {
163
+ 'shoulder_movement': 'حركة الكتفين',
164
+ 'hip_movement': 'حركة الورك',
165
+ 'posture_stability': 'استقرار القامة',
166
+ 'arm_swing': 'تأرجح الذراعين',
167
+ 'knee_alignment': 'اتزان الركبتين',
168
+ 'gait_symmetry': 'تناسق المشية'
169
+ }
170
+
171
+ for metric, score in risk_scores.items():
172
+ metric_name = metric_names.get(metric, metric)
173
+ status = "✅ طبيعي" if score >= 70 else "⚠️ يحتاج مراقبة" if score >= 50 else "❌ غير طبيعي"
174
+ report += f"{metric_name}: {score:.1f}/100 - {status}\n"
175
+
176
+ report += f"""
177
+ {'─'*30}
178
+ 📋 الإحصائيات:
179
+ • عدد الإطارات المحللة: {frame_count}
180
+ • عدد المقاييس المستخدمة: {len(risk_scores)}
181
 
182
+ {'='*50}
183
+ ملاحظة: هذا التحليل مبني على معايير عامة ويجب عدم الاعتماد عليه كتشخيص طبي نهائي.
184
  """
185
+
186
+ return report
 
 
 
 
 
 
 
 
 
187
 
188
+ # التشغيل الرئيسي مع تحسين اكتشاف نوع الملف
189
+ print("📁 رفع فيديو للمشي لتحليل المشية")
190
+ print("⚠️ تأكد من رفع ملف فيديو (mp4, avi, mov) وليس صورة")
191
+ uploaded = files.upload()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
192
 
193
+ if uploaded:
194
+ file_name = list(uploaded.keys())[0]
195
+
196
+ if is_image_file(file_name):
197
+ print(f"❌ خطأ: الملف '{file_name}' هو صورة وليس فيديو!")
198
+ print("📹 يرجى رفع ملف فيديو حقيقي للمشي")
199
+ elif is_video_file(file_name):
200
+ print(f"✅ تم رفع الفيديو: {file_name}")
201
+
202
+ gait_metrics, frame_count = analyze_video_gait(file_name)
203
+
204
+ if gait_metrics and frame_count > 0:
205
+ risk_scores = calculate_risk_scores(gait_metrics, frame_count)
206
+ report = generate_report(risk_scores, frame_count)
207
+ print(report)
208
+ else:
209
+ print("❌ فشل في تحليل الفيديو أو لم يتم اكتشاف أي شخص")
210
+
211
+ try:
212
+ os.remove(file_name)
213
+ except:
214
+ pass
215
+ else:
216
+ print(f"❌ نوع الملف غير مدعوم: {file_name}")
217
+ print("📹 يرجى رفع ملف فيديو (mp4, avi, mov)")
218
+ else:
219
+ print("📂 لم يتم رفع أي ملف")