reab5555 commited on
Commit
295d1f0
·
verified ·
1 Parent(s): a8bbf69

Update pose_analysis.py

Browse files
Files changed (1) hide show
  1. pose_analysis.py +135 -134
pose_analysis.py CHANGED
@@ -1,135 +1,136 @@
1
- import math
2
- import cv2
3
- import mediapipe as mp
4
-
5
- mp_pose = mp.solutions.pose
6
- mp_drawing = mp.solutions.drawing_utils
7
- pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.7, min_tracking_confidence=0.7)
8
-
9
- def calculate_posture_score(frame):
10
- image_height, image_width, _ = frame.shape
11
- results = pose.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
12
-
13
- if not results.pose_landmarks:
14
- return None, None
15
-
16
- landmarks = results.pose_landmarks.landmark
17
-
18
- # Use only body landmarks
19
- left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
20
- right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
21
- left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
22
- right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
23
- left_knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]
24
- right_knee = landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]
25
-
26
- # Calculate angles
27
- shoulder_angle = abs(math.degrees(math.atan2(right_shoulder.y - left_shoulder.y, right_shoulder.x - left_shoulder.x)))
28
- hip_angle = abs(math.degrees(math.atan2(right_hip.y - left_hip.y, right_hip.x - left_hip.x)))
29
- knee_angle = abs(math.degrees(math.atan2(right_knee.y - left_knee.y, right_knee.x - left_knee.x)))
30
-
31
- # Calculate vertical alignment
32
- shoulder_hip_alignment = abs((left_shoulder.y + right_shoulder.y) / 2 - (left_hip.y + right_hip.y) / 2)
33
- hip_knee_alignment = abs((left_hip.y + right_hip.y) / 2 - (left_knee.y + right_knee.y) / 2)
34
- # Add head landmarks
35
- nose = landmarks[mp_pose.PoseLandmark.NOSE.value]
36
- left_ear = landmarks[mp_pose.PoseLandmark.LEFT_EAR.value]
37
- right_ear = landmarks[mp_pose.PoseLandmark.RIGHT_EAR.value]
38
- # Calculate head tilt
39
- head_tilt = abs(math.degrees(math.atan2(right_ear.y - left_ear.y, right_ear.x - left_ear.x)))
40
- # Calculate head position relative to shoulders
41
- head_position = abs((nose.y - (left_shoulder.y + right_shoulder.y) / 2) /
42
- ((left_shoulder.y + right_shoulder.y) / 2 - (left_hip.y + right_hip.y) / 2))
43
-
44
- # Combine metrics into a single posture score (you may need to adjust these weights)
45
- posture_score = (
46
- (1 - abs(shoulder_angle - hip_angle) / 90) * 0.3 +
47
- (1 - abs(hip_angle - knee_angle) / 90) * 0.2 +
48
- (1 - shoulder_hip_alignment) * 0.1 +
49
- (1 - hip_knee_alignment) * 0.1 +
50
- (1 - abs(head_tilt - 90) / 90) * 0.15 +
51
- (1 - head_position) * 0.15
52
- )
53
-
54
- return posture_score, results.pose_landmarks
55
-
56
- def draw_pose_landmarks(frame, landmarks):
57
- annotated_frame = frame.copy()
58
- # Include relevant landmarks for head position and body
59
- body_landmarks = [
60
- mp_pose.PoseLandmark.NOSE,
61
- mp_pose.PoseLandmark.LEFT_SHOULDER,
62
- mp_pose.PoseLandmark.RIGHT_SHOULDER,
63
- mp_pose.PoseLandmark.LEFT_EAR,
64
- mp_pose.PoseLandmark.RIGHT_EAR,
65
- mp_pose.PoseLandmark.LEFT_ELBOW,
66
- mp_pose.PoseLandmark.RIGHT_ELBOW,
67
- mp_pose.PoseLandmark.LEFT_WRIST,
68
- mp_pose.PoseLandmark.RIGHT_WRIST,
69
- mp_pose.PoseLandmark.LEFT_HIP,
70
- mp_pose.PoseLandmark.RIGHT_HIP,
71
- mp_pose.PoseLandmark.LEFT_KNEE,
72
- mp_pose.PoseLandmark.RIGHT_KNEE,
73
- mp_pose.PoseLandmark.LEFT_ANKLE,
74
- mp_pose.PoseLandmark.RIGHT_ANKLE
75
- ]
76
-
77
- # Connections for head position and body
78
- body_connections = [
79
- (mp_pose.PoseLandmark.LEFT_EAR, mp_pose.PoseLandmark.LEFT_SHOULDER),
80
- (mp_pose.PoseLandmark.RIGHT_EAR, mp_pose.PoseLandmark.RIGHT_SHOULDER),
81
- (mp_pose.PoseLandmark.NOSE, mp_pose.PoseLandmark.LEFT_SHOULDER),
82
- (mp_pose.PoseLandmark.NOSE, mp_pose.PoseLandmark.RIGHT_SHOULDER),
83
- (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.RIGHT_SHOULDER),
84
- (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.LEFT_ELBOW),
85
- (mp_pose.PoseLandmark.RIGHT_SHOULDER, mp_pose.PoseLandmark.RIGHT_ELBOW),
86
- (mp_pose.PoseLandmark.LEFT_ELBOW, mp_pose.PoseLandmark.LEFT_WRIST),
87
- (mp_pose.PoseLandmark.RIGHT_ELBOW, mp_pose.PoseLandmark.RIGHT_WRIST),
88
- (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.LEFT_HIP),
89
- (mp_pose.PoseLandmark.RIGHT_SHOULDER, mp_pose.PoseLandmark.RIGHT_HIP),
90
- (mp_pose.PoseLandmark.LEFT_HIP, mp_pose.PoseLandmark.RIGHT_HIP),
91
- (mp_pose.PoseLandmark.LEFT_HIP, mp_pose.PoseLandmark.LEFT_KNEE),
92
- (mp_pose.PoseLandmark.RIGHT_HIP, mp_pose.PoseLandmark.RIGHT_KNEE),
93
- (mp_pose.PoseLandmark.LEFT_KNEE, mp_pose.PoseLandmark.LEFT_ANKLE),
94
- (mp_pose.PoseLandmark.RIGHT_KNEE, mp_pose.PoseLandmark.RIGHT_ANKLE)
95
- ]
96
-
97
- # Draw landmarks
98
- for landmark in body_landmarks:
99
- if landmark in landmarks.landmark:
100
- lm = landmarks.landmark[landmark]
101
- h, w, _ = annotated_frame.shape
102
- cx, cy = int(lm.x * w), int(lm.y * h)
103
- cv2.circle(annotated_frame, (cx, cy), 5, (245, 117, 66), -1)
104
-
105
- # Draw connections
106
- for connection in body_connections:
107
- start_lm = landmarks.landmark[connection[0]]
108
- end_lm = landmarks.landmark[connection[1]]
109
- h, w, _ = annotated_frame.shape
110
- start_point = (int(start_lm.x * w), int(start_lm.y * h))
111
- end_point = (int(end_lm.x * w), int(end_lm.y * h))
112
- cv2.line(annotated_frame, start_point, end_point, (245, 66, 230), 2)
113
-
114
- # Highlight head tilt
115
- left_ear = landmarks.landmark[mp_pose.PoseLandmark.LEFT_EAR]
116
- right_ear = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_EAR]
117
- nose = landmarks.landmark[mp_pose.PoseLandmark.NOSE]
118
-
119
- h, w, _ = annotated_frame.shape
120
- left_ear_point = (int(left_ear.x * w), int(left_ear.y * h))
121
- right_ear_point = (int(right_ear.x * w), int(right_ear.y * h))
122
- nose_point = (int(nose.x * w), int(nose.y * h))
123
-
124
- # Draw a line between ears to show head tilt
125
- cv2.line(annotated_frame, left_ear_point, right_ear_point, (0, 255, 0), 2)
126
-
127
- # Draw a line from nose to the midpoint between shoulders to show head forward/backward tilt
128
- left_shoulder = landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
129
- right_shoulder = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
130
- shoulder_mid_x = (left_shoulder.x + right_shoulder.x) / 2
131
- shoulder_mid_y = (left_shoulder.y + right_shoulder.y) / 2
132
- shoulder_mid_point = (int(shoulder_mid_x * w), int(shoulder_mid_y * h))
133
- cv2.line(annotated_frame, nose_point, shoulder_mid_point, (0, 255, 0), 2)
134
-
 
135
  return annotated_frame
 
1
+ import math
2
+ import cv2
3
+ import mediapipe as mp
4
+
5
+ @spaces.GPU(duration=300)
6
+ mp_pose = mp.solutions.pose
7
+ mp_drawing = mp.solutions.drawing_utils
8
+ pose = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.7, min_tracking_confidence=0.7)
9
+
10
+ def calculate_posture_score(frame):
11
+ image_height, image_width, _ = frame.shape
12
+ results = pose.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
13
+
14
+ if not results.pose_landmarks:
15
+ return None, None
16
+
17
+ landmarks = results.pose_landmarks.landmark
18
+
19
+ # Use only body landmarks
20
+ left_shoulder = landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value]
21
+ right_shoulder = landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value]
22
+ left_hip = landmarks[mp_pose.PoseLandmark.LEFT_HIP.value]
23
+ right_hip = landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value]
24
+ left_knee = landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value]
25
+ right_knee = landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value]
26
+
27
+ # Calculate angles
28
+ shoulder_angle = abs(math.degrees(math.atan2(right_shoulder.y - left_shoulder.y, right_shoulder.x - left_shoulder.x)))
29
+ hip_angle = abs(math.degrees(math.atan2(right_hip.y - left_hip.y, right_hip.x - left_hip.x)))
30
+ knee_angle = abs(math.degrees(math.atan2(right_knee.y - left_knee.y, right_knee.x - left_knee.x)))
31
+
32
+ # Calculate vertical alignment
33
+ shoulder_hip_alignment = abs((left_shoulder.y + right_shoulder.y) / 2 - (left_hip.y + right_hip.y) / 2)
34
+ hip_knee_alignment = abs((left_hip.y + right_hip.y) / 2 - (left_knee.y + right_knee.y) / 2)
35
+ # Add head landmarks
36
+ nose = landmarks[mp_pose.PoseLandmark.NOSE.value]
37
+ left_ear = landmarks[mp_pose.PoseLandmark.LEFT_EAR.value]
38
+ right_ear = landmarks[mp_pose.PoseLandmark.RIGHT_EAR.value]
39
+ # Calculate head tilt
40
+ head_tilt = abs(math.degrees(math.atan2(right_ear.y - left_ear.y, right_ear.x - left_ear.x)))
41
+ # Calculate head position relative to shoulders
42
+ head_position = abs((nose.y - (left_shoulder.y + right_shoulder.y) / 2) /
43
+ ((left_shoulder.y + right_shoulder.y) / 2 - (left_hip.y + right_hip.y) / 2))
44
+
45
+ # Combine metrics into a single posture score (you may need to adjust these weights)
46
+ posture_score = (
47
+ (1 - abs(shoulder_angle - hip_angle) / 90) * 0.3 +
48
+ (1 - abs(hip_angle - knee_angle) / 90) * 0.2 +
49
+ (1 - shoulder_hip_alignment) * 0.1 +
50
+ (1 - hip_knee_alignment) * 0.1 +
51
+ (1 - abs(head_tilt - 90) / 90) * 0.15 +
52
+ (1 - head_position) * 0.15
53
+ )
54
+
55
+ return posture_score, results.pose_landmarks
56
+
57
+ def draw_pose_landmarks(frame, landmarks):
58
+ annotated_frame = frame.copy()
59
+ # Include relevant landmarks for head position and body
60
+ body_landmarks = [
61
+ mp_pose.PoseLandmark.NOSE,
62
+ mp_pose.PoseLandmark.LEFT_SHOULDER,
63
+ mp_pose.PoseLandmark.RIGHT_SHOULDER,
64
+ mp_pose.PoseLandmark.LEFT_EAR,
65
+ mp_pose.PoseLandmark.RIGHT_EAR,
66
+ mp_pose.PoseLandmark.LEFT_ELBOW,
67
+ mp_pose.PoseLandmark.RIGHT_ELBOW,
68
+ mp_pose.PoseLandmark.LEFT_WRIST,
69
+ mp_pose.PoseLandmark.RIGHT_WRIST,
70
+ mp_pose.PoseLandmark.LEFT_HIP,
71
+ mp_pose.PoseLandmark.RIGHT_HIP,
72
+ mp_pose.PoseLandmark.LEFT_KNEE,
73
+ mp_pose.PoseLandmark.RIGHT_KNEE,
74
+ mp_pose.PoseLandmark.LEFT_ANKLE,
75
+ mp_pose.PoseLandmark.RIGHT_ANKLE
76
+ ]
77
+
78
+ # Connections for head position and body
79
+ body_connections = [
80
+ (mp_pose.PoseLandmark.LEFT_EAR, mp_pose.PoseLandmark.LEFT_SHOULDER),
81
+ (mp_pose.PoseLandmark.RIGHT_EAR, mp_pose.PoseLandmark.RIGHT_SHOULDER),
82
+ (mp_pose.PoseLandmark.NOSE, mp_pose.PoseLandmark.LEFT_SHOULDER),
83
+ (mp_pose.PoseLandmark.NOSE, mp_pose.PoseLandmark.RIGHT_SHOULDER),
84
+ (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.RIGHT_SHOULDER),
85
+ (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.LEFT_ELBOW),
86
+ (mp_pose.PoseLandmark.RIGHT_SHOULDER, mp_pose.PoseLandmark.RIGHT_ELBOW),
87
+ (mp_pose.PoseLandmark.LEFT_ELBOW, mp_pose.PoseLandmark.LEFT_WRIST),
88
+ (mp_pose.PoseLandmark.RIGHT_ELBOW, mp_pose.PoseLandmark.RIGHT_WRIST),
89
+ (mp_pose.PoseLandmark.LEFT_SHOULDER, mp_pose.PoseLandmark.LEFT_HIP),
90
+ (mp_pose.PoseLandmark.RIGHT_SHOULDER, mp_pose.PoseLandmark.RIGHT_HIP),
91
+ (mp_pose.PoseLandmark.LEFT_HIP, mp_pose.PoseLandmark.RIGHT_HIP),
92
+ (mp_pose.PoseLandmark.LEFT_HIP, mp_pose.PoseLandmark.LEFT_KNEE),
93
+ (mp_pose.PoseLandmark.RIGHT_HIP, mp_pose.PoseLandmark.RIGHT_KNEE),
94
+ (mp_pose.PoseLandmark.LEFT_KNEE, mp_pose.PoseLandmark.LEFT_ANKLE),
95
+ (mp_pose.PoseLandmark.RIGHT_KNEE, mp_pose.PoseLandmark.RIGHT_ANKLE)
96
+ ]
97
+
98
+ # Draw landmarks
99
+ for landmark in body_landmarks:
100
+ if landmark in landmarks.landmark:
101
+ lm = landmarks.landmark[landmark]
102
+ h, w, _ = annotated_frame.shape
103
+ cx, cy = int(lm.x * w), int(lm.y * h)
104
+ cv2.circle(annotated_frame, (cx, cy), 5, (245, 117, 66), -1)
105
+
106
+ # Draw connections
107
+ for connection in body_connections:
108
+ start_lm = landmarks.landmark[connection[0]]
109
+ end_lm = landmarks.landmark[connection[1]]
110
+ h, w, _ = annotated_frame.shape
111
+ start_point = (int(start_lm.x * w), int(start_lm.y * h))
112
+ end_point = (int(end_lm.x * w), int(end_lm.y * h))
113
+ cv2.line(annotated_frame, start_point, end_point, (245, 66, 230), 2)
114
+
115
+ # Highlight head tilt
116
+ left_ear = landmarks.landmark[mp_pose.PoseLandmark.LEFT_EAR]
117
+ right_ear = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_EAR]
118
+ nose = landmarks.landmark[mp_pose.PoseLandmark.NOSE]
119
+
120
+ h, w, _ = annotated_frame.shape
121
+ left_ear_point = (int(left_ear.x * w), int(left_ear.y * h))
122
+ right_ear_point = (int(right_ear.x * w), int(right_ear.y * h))
123
+ nose_point = (int(nose.x * w), int(nose.y * h))
124
+
125
+ # Draw a line between ears to show head tilt
126
+ cv2.line(annotated_frame, left_ear_point, right_ear_point, (0, 255, 0), 2)
127
+
128
+ # Draw a line from nose to the midpoint between shoulders to show head forward/backward tilt
129
+ left_shoulder = landmarks.landmark[mp_pose.PoseLandmark.LEFT_SHOULDER]
130
+ right_shoulder = landmarks.landmark[mp_pose.PoseLandmark.RIGHT_SHOULDER]
131
+ shoulder_mid_x = (left_shoulder.x + right_shoulder.x) / 2
132
+ shoulder_mid_y = (left_shoulder.y + right_shoulder.y) / 2
133
+ shoulder_mid_point = (int(shoulder_mid_x * w), int(shoulder_mid_y * h))
134
+ cv2.line(annotated_frame, nose_point, shoulder_mid_point, (0, 255, 0), 2)
135
+
136
  return annotated_frame