BSuruchi commited on
Commit
f0c8a90
·
verified ·
1 Parent(s): d163beb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +375 -0
app.py ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Install mediapipe
2
+ !pip install mediapipe
3
+
4
+ # *******Import necessary libraries***************
5
+ import math
6
+ import cv2
7
+ import numpy as np
8
+ from time import time
9
+ import mediapipe as mp
10
+ import matplotlib.pyplot as plt
11
+
12
+
13
+ #*******************Initialize the Pose Detection Model*****************
14
+
15
+ # Initializing mediapipe pose class.
16
+ mp_pose = mp.solutions.pose
17
+
18
+ # Setting up the Pose function.
19
+ pose = mp_pose.Pose(static_image_mode=True, min_detection_confidence=0.3, model_complexity=2)
20
+
21
+ # Initializing mediapipe drawing class, useful for annotation.
22
+ mp_drawing = mp.solutions.drawing_utils
23
+
24
+ #*********Read an Image************************
25
+
26
+ # !pip install requests
27
+ # import requests
28
+ # # Function to read an image from a URL
29
+ #def read_image_from_url(url1):
30
+ # response = requests.get(url1)
31
+ # image_array = np.asarray(bytearray(response.content), dtype=np.uint8)
32
+ # image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
33
+ # return image
34
+
35
+ # # GitHub URL of the image
36
+ # url1 = 'https://github.com/toanmolsharma/newprojecty/raw/main/media/sample.jpg'
37
+
38
+ # # Read the image from the URL
39
+ # sample_img = read_image_from_url(url1)
40
+
41
+ # # Read an image from the specified path.
42
+ # #sample_img = cv2.imread('media/sample.jpg')
43
+
44
+ # # Specify a size of the figure.
45
+ # plt.figure(figsize = [10, 10])
46
+
47
+ # # Display the sample image, also convert BGR to RGB for display.
48
+ #plt.title("Sample Image");plt.axis('off');plt.imshow(sample_img[:,:,::-1]);plt.show()
49
+
50
+
51
+
52
+ #*********************Pose Detection On Real-Time Webcam Feed/Video******
53
+
54
+ ## Setup Pose function for video.
55
+ #pose_video = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, model_complexity=1)
56
+
57
+ ## Initialize the VideoCapture object to read from the webcam.
58
+ #video = cv2.VideoCapture(1)
59
+
60
+ ## Create named window for resizing purposes
61
+ #cv2.namedWindow('Pose Detection', cv2.WINDOW_NORMAL)
62
+
63
+
64
+ ## Initialize the VideoCapture object to read from a video stored in the disk.
65
+ ##video = cv2.VideoCapture('media/running.mp4')
66
+
67
+ ## Set video camera size
68
+ #video.set(3,1280)
69
+ #video.set(4,960)
70
+
71
+ ## Initialize a variable to store the time of the previous frame.
72
+ #time1 = 0
73
+
74
+ ## Iterate until the video is accessed successfully.
75
+ #while video.isOpened():
76
+
77
+ # # Read a frame.
78
+ # ok, frame = video.read()
79
+
80
+ # # Check if frame is not read properly.
81
+ # if not ok:
82
+
83
+ # # Break the loop.
84
+ # break
85
+
86
+ # # Flip the frame horizontally for natural (selfie-view) visualization.
87
+ # frame = cv2.flip(frame, 1)
88
+
89
+ # # Get the width and height of the frame
90
+ # frame_height, frame_width, _ = frame.shape
91
+
92
+ # # Resize the frame while keeping the aspect ratio.
93
+ # frame = cv2.resize(frame, (int(frame_width * (640 / frame_height)), 640))
94
+
95
+ # # Perform Pose landmark detection.
96
+ #frame, _ = detectPose(frame, pose_video, display=False)
97
+
98
+ ## Set the time for this frame to the current time.
99
+ ##time2 = time()
100
+
101
+ # #Check if the difference between the previous and this frame time > 0 to avoid division by zero.
102
+ #if (time2 - time1) > 0:
103
+
104
+ # # Calculate the number of frames per second.
105
+ # frames_per_second = 1.0 / (time2 - time1)
106
+
107
+ # # Write the calculated number of frames per second on the frame.
108
+ #cv2.putText(frame, 'FPS: {}'.format(int(frames_per_second)), (10, 30),cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 3)
109
+
110
+ ## Update the previous frame time to this frame time.
111
+ ## As this frame will become previous frame in next iteration.
112
+ #time1 = time2
113
+
114
+ ## Display the frame.
115
+ #cv2.imshow('Pose Detection', frame)
116
+
117
+ # # Wait until a key is pressed.
118
+ # # Retreive the ASCII code of the key pressed
119
+ # k = cv2.waitKey(1) & 0xFF
120
+
121
+ # # Check if 'ESC' is pressed.
122
+ #if(k == 27):
123
+
124
+ # # Break the loop.
125
+ # break
126
+
127
+ ## Release the VideoCapture object.
128
+ #video.release()
129
+
130
+ ## Close the windows.
131
+ #cv2.destroyAllWindows()
132
+
133
+
134
+ # ********************Pose Classification with Angle Heuristics*****************
135
+
136
+ def calculateAngle(landmark1, landmark2, landmark3):
137
+ '''
138
+ This function calculates angle between three different landmarks.
139
+ Args:
140
+ landmark1: The first landmark containing the x,y and z coordinates.
141
+ landmark2: The second landmark containing the x,y and z coordinates.
142
+ landmark3: The third landmark containing the x,y and z coordinates.
143
+ Returns:
144
+ angle: The calculated angle between the three landmarks.
145
+
146
+ '''
147
+
148
+ # Get the required landmarks coordinates.
149
+ x1, y1, _ = landmark1
150
+ x2, y2, _ = landmark2
151
+ x3, y3, _ = landmark3
152
+
153
+ # Calculate the angle between the three points
154
+ angle = math.degrees(math.atan2(y3 - y2, x3 - x2) - math.atan2(y1 - y2, x1 - x2))
155
+
156
+ # Check if the angle is less than zero.
157
+ if angle < 0:
158
+
159
+ # Add 360 to the found angle.
160
+ angle += 360
161
+
162
+ # Return the calculated angle.
163
+ return angle
164
+
165
+
166
+
167
+ #***************************Create a Function to Perform Pose Classification***************
168
+
169
+ def classifyPose(landmarks, output_image, display=False):
170
+ '''
171
+ This function classifies yoga poses depending upon the angles of various body joints.
172
+ Args:
173
+ landmarks: A list of detected landmarks of the person whose pose needs to be classified.
174
+ output_image: A image of the person with the detected pose landmarks drawn.
175
+ display: A boolean value that is if set to true the function displays the resultant image with the pose label
176
+ written on it and returns nothing.
177
+ Returns:
178
+ output_image: The image with the detected pose landmarks drawn and pose label written.
179
+ label: The classified pose label of the person in the output_image.
180
+
181
+ '''
182
+
183
+ # Initialize the label of the pose. It is not known at this stage.
184
+ label = 'Unknown Pose'
185
+
186
+ # Specify the color (Red) with which the label will be written on the image.
187
+ color = (0, 0, 255)
188
+
189
+ # Calculate the required angles.
190
+ #----------------------------------------------------------------------------------------------------------------
191
+
192
+ # Get the angle between the left shoulder, elbow and wrist points.
193
+ left_elbow_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value],
194
+ landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value],
195
+ landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value])
196
+
197
+ # Get the angle between the right shoulder, elbow and wrist points.
198
+ right_elbow_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value],
199
+ landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value],
200
+ landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value])
201
+
202
+ # Get the angle between the left elbow, shoulder and hip points.
203
+ left_shoulder_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_ELBOW.value],
204
+ landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value],
205
+ landmarks[mp_pose.PoseLandmark.LEFT_HIP.value])
206
+
207
+ # Get the angle between the right hip, shoulder and elbow points.
208
+ right_shoulder_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value],
209
+ landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value],
210
+ landmarks[mp_pose.PoseLandmark.RIGHT_ELBOW.value])
211
+
212
+ # Get the angle between the left hip, knee and ankle points.
213
+ left_knee_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.LEFT_HIP.value],
214
+ landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value],
215
+ landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value])
216
+
217
+ # Get the angle between the right hip, knee and ankle points
218
+ right_knee_angle = calculateAngle(landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value],
219
+ landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value],
220
+ landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value])
221
+
222
+ #----------------------------------------------------------------------------------------------------------------
223
+ # Check for Five-Pointed Star Pose
224
+ if abs(landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][1] - landmarks[mp_pose.PoseLandmark.LEFT_HIP.value][1]) < 100 and \
225
+ abs(landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][1] - landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value][1]) < 100 and \
226
+ abs(landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value][0] - landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value][0]) > 200 and \
227
+ abs(landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][0] - landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][0]) > 200:
228
+ label = "Five-Pointed Star Pose"
229
+
230
+ # Check if it is the warrior II pose or the T pose.
231
+ # As for both of them, both arms should be straight and shoulders should be at the specific angle.
232
+ #----------------------------------------------------------------------------------------------------------------
233
+
234
+ # Check if the both arms are straight.
235
+ if left_elbow_angle > 165 and left_elbow_angle < 195 and right_elbow_angle > 165 and right_elbow_angle < 195:
236
+
237
+ # Check if shoulders are at the required angle.
238
+ if left_shoulder_angle > 80 and left_shoulder_angle < 110 and right_shoulder_angle > 80 and right_shoulder_angle < 110:
239
+
240
+ # Check if it is the warrior II pose.
241
+ #----------------------------------------------------------------------------------------------------------------
242
+
243
+ # Check if one leg is straight.
244
+ if left_knee_angle > 165 and left_knee_angle < 195 or right_knee_angle > 165 and right_knee_angle < 195:
245
+
246
+ # Check if the other leg is bended at the required angle.
247
+ if left_knee_angle > 90 and left_knee_angle < 120 or right_knee_angle > 90 and right_knee_angle < 120:
248
+
249
+ # Specify the label of the pose that is Warrior II pose.
250
+ label = 'Warrior II Pose'
251
+
252
+ #----------------------------------------------------------------------------------------------------------------
253
+
254
+ # Check if it is the T pose.
255
+ #----------------------------------------------------------------------------------------------------------------
256
+
257
+ # Check if both legs are straight
258
+ if left_knee_angle > 160 and left_knee_angle < 195 and right_knee_angle > 160 and right_knee_angle < 195:
259
+
260
+ # Specify the label of the pose that is tree pose.
261
+ label = 'T Pose'
262
+
263
+ #----------------------------------------------------------------------------------------------------------------
264
+
265
+ # Check if it is the tree pose.
266
+ #----------------------------------------------------------------------------------------------------------------
267
+
268
+ # Check if one leg is straight
269
+ if left_knee_angle > 165 and left_knee_angle < 195 or right_knee_angle > 165 and right_knee_angle < 195:
270
+
271
+ # Check if the other leg is bended at the required angle.
272
+ if left_knee_angle > 315 and left_knee_angle < 335 or right_knee_angle > 25 and right_knee_angle < 45:
273
+
274
+ # Specify the label of the pose that is tree pose.
275
+ label = 'Tree Pose'
276
+
277
+ # Check for Upward Salute Pose
278
+ if abs(landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][0] - landmarks[mp_pose.PoseLandmark.LEFT_HIP.value][0]) < 100 and \
279
+ abs(landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][0] - landmarks[mp_pose.PoseLandmark.RIGHT_HIP.value][0]) < 100 and \
280
+ landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][1] < landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value][1] and \
281
+ landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][1] < landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value][1] and \
282
+ abs(landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value][1] - landmarks[mp_pose.PoseLandmark.RIGHT_SHOULDER.value][1]) < 50:
283
+ label = "Upward Salute Pose"
284
+
285
+ # Check for Hands Under Feet Pose
286
+ if landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][1] > landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value][1] and \
287
+ landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][1] > landmarks[mp_pose.PoseLandmark.RIGHT_KNEE.value][1] and \
288
+ abs(landmarks[mp_pose.PoseLandmark.LEFT_WRIST.value][0] - landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value][0]) < 50 and \
289
+ abs(landmarks[mp_pose.PoseLandmark.RIGHT_WRIST.value][0] - landmarks[mp_pose.PoseLandmark.RIGHT_ANKLE.value][0]) < 50:
290
+ label = "Hands Under Feet Pose"
291
+
292
+
293
+ #----------------------------------------------------------------------------------------------------------------
294
+
295
+ # Check if the pose is classified successfully
296
+ if label != 'Unknown Pose':
297
+
298
+ # Update the color (to green) with which the label will be written on the image.
299
+ color = (0, 255, 0)
300
+
301
+ # Write the label on the output image.
302
+ cv2.putText(output_image, label, (10, 30),cv2.FONT_HERSHEY_PLAIN, 2, color, 2)
303
+
304
+ # Check if the resultant image is specified to be displayed.
305
+ if display:
306
+
307
+ # Display the resultant image.
308
+ plt.figure(figsize=[10,10])
309
+ plt.imshow(output_image[:,:,::-1]);plt.title("Output Image");plt.axis('off');
310
+
311
+ else:
312
+
313
+ # Return the output image and the classified label.
314
+ return output_image, label
315
+
316
+ #******************************Pose Classification On Real-Time Webcam Feed*****************
317
+
318
+ # Setup Pose function for video.
319
+ pose_video = mp_pose.Pose(static_image_mode=False, min_detection_confidence=0.5, model_complexity=1)
320
+
321
+ # Initialize the VideoCapture object to read from the webcam.
322
+ camera_video = cv2.VideoCapture(0)
323
+ camera_video.set(3,1280)
324
+ camera_video.set(4,960)
325
+
326
+ # Initialize a resizable window.
327
+ cv2.namedWindow('Pose Classification', cv2.WINDOW_NORMAL)
328
+
329
+ # Iterate until the webcam is accessed successfully.
330
+ while camera_video.isOpened():
331
+
332
+ # Read a frame.
333
+ ok, frame = camera_video.read()
334
+
335
+ # Check if frame is not read properly.
336
+ if not ok:
337
+
338
+ # Continue to the next iteration to read the next frame and ignore the empty camera frame.
339
+ continue
340
+
341
+ # Flip the frame horizontally for natural (selfie-view) visualization.
342
+ frame = cv2.flip(frame, 1)
343
+
344
+ # Get the width and height of the frame
345
+ frame_height, frame_width, _ = frame.shape
346
+
347
+ # Resize the frame while keeping the aspect ratio.
348
+ frame = cv2.resize(frame, (int(frame_width * (640 / frame_height)), 640))
349
+
350
+ # Perform Pose landmark detection.
351
+ frame, landmarks = detectPose(frame, pose_video, display=False)
352
+
353
+ # Check if the landmarks are detected.
354
+ if landmarks:
355
+
356
+ # Perform the Pose Classification.
357
+ frame, _ = classifyPose(landmarks, frame, display=False)
358
+
359
+ # Display the frame.
360
+ cv2.imshow('Pose Classification', frame)
361
+
362
+ # Wait until a key is pressed.
363
+ # Retreive the ASCII code of the key pressed
364
+ k = cv2.waitKey(1) & 0xFF
365
+
366
+ # Check if 'ESC' is pressed.
367
+ if(k == 27):
368
+
369
+ # Break the loop.
370
+ break
371
+
372
+ # Release the VideoCapture object and close the windows.
373
+ camera_video.release()
374
+ cv2.destroyAllWindows()
375
+