Update app.py
Browse files
app.py
CHANGED
@@ -227,17 +227,16 @@ def calculate_angle(a, b, c):
|
|
227 |
a = np.array(a)
|
228 |
b = np.array(b)
|
229 |
c = np.array(c)
|
230 |
-
radians = np.arctan2(c[1]
|
231 |
angle = np.abs(radians * 180.0 / np.pi)
|
232 |
if angle > 180.0:
|
233 |
angle = 360 - angle
|
234 |
return angle
|
235 |
|
236 |
-
counterL
|
237 |
-
correct
|
238 |
-
incorrect
|
239 |
-
stage
|
240 |
-
|
241 |
|
242 |
# Detection Queue
|
243 |
result_queue: "queue.Queue[List[Detection]]" = queue.Queue()
|
@@ -249,12 +248,7 @@ def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
|
|
249 |
|
250 |
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
|
251 |
results = pose.process(image_rgb)
|
252 |
-
|
253 |
-
if results.pose_landmarks:
|
254 |
-
landmarks = results.pose_landmarks.landmark
|
255 |
-
else:
|
256 |
-
landmarks = []
|
257 |
-
cv2.putText(image, "No Pose Detected", (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv2.LINE_AA)
|
258 |
|
259 |
# Corrected detection logic
|
260 |
detections = [
|
@@ -270,84 +264,114 @@ def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
|
|
270 |
hipL = [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,
|
271 |
landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
|
272 |
kneeL = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x,
|
273 |
-
|
274 |
ankleL = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].x,
|
275 |
-
|
276 |
shoulderL = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
|
277 |
-
|
278 |
footIndexL = [landmarks[mp_pose.PoseLandmark.LEFT_FOOT_INDEX.value].x,
|
279 |
-
|
280 |
|
281 |
# Calculate angles
|
282 |
-
angleKneeL = calculate_angle(
|
283 |
-
angleHipL = calculate_angle(
|
284 |
-
angleAnkleL = calculate_angle(
|
285 |
|
286 |
-
#
|
287 |
-
cv2.putText(image, str(angleHipL),
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
343 |
|
344 |
-
|
345 |
-
|
346 |
-
cv2.putText(image, str(correct), (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2, cv2.LINE_AA)
|
347 |
|
348 |
-
|
349 |
-
|
350 |
-
|
|
|
|
|
|
|
|
|
|
|
351 |
|
352 |
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
|
353 |
mp_drawing.DrawingSpec(color=(255, 175, 0), thickness=2, circle_radius=2),
|
@@ -357,7 +381,9 @@ def video_frame_callback(frame: av.VideoFrame) -> av.VideoFrame:
|
|
357 |
return av.VideoFrame.from_ndarray(image, format="bgr24")
|
358 |
|
359 |
|
|
|
360 |
# WebRTC streamer configuration
|
|
|
361 |
webrtc_streamer(
|
362 |
key="squat-detection",
|
363 |
mode=WebRtcMode.SENDRECV,
|
|
|
227 |
a = np.array(a)
|
228 |
b = np.array(b)
|
229 |
c = np.array(c)
|
230 |
+
radians = np.arctan2(c[1]-b[1], c[0]-b[0]) - np.arctan2(a[1]-b[1], a[0]-b[0])
|
231 |
angle = np.abs(radians * 180.0 / np.pi)
|
232 |
if angle > 180.0:
|
233 |
angle = 360 - angle
|
234 |
return angle
|
235 |
|
236 |
+
counterL=0#Counter checks for number of curls
|
237 |
+
correct=0
|
238 |
+
incorrect=0
|
239 |
+
stage=None#it checks if we our hand is UP or DOWN
|
|
|
240 |
|
241 |
# Detection Queue
|
242 |
result_queue: "queue.Queue[List[Detection]]" = queue.Queue()
|
|
|
248 |
|
249 |
with mp_pose.Pose(min_detection_confidence=0.5, min_tracking_confidence=0.5) as pose:
|
250 |
results = pose.process(image_rgb)
|
251 |
+
landmarks = results.pose_landmarks.landmark if results.pose_landmarks else []
|
|
|
|
|
|
|
|
|
|
|
252 |
|
253 |
# Corrected detection logic
|
254 |
detections = [
|
|
|
264 |
hipL = [landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].x,
|
265 |
landmarks[mp_pose.PoseLandmark.LEFT_HIP.value].y]
|
266 |
kneeL = [landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].x,
|
267 |
+
landmarks[mp_pose.PoseLandmark.LEFT_KNEE.value].y]
|
268 |
ankleL = [landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].x,
|
269 |
+
landmarks[mp_pose.PoseLandmark.LEFT_ANKLE.value].y]
|
270 |
shoulderL = [landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].x,
|
271 |
+
landmarks[mp_pose.PoseLandmark.LEFT_SHOULDER.value].y]
|
272 |
footIndexL = [landmarks[mp_pose.PoseLandmark.LEFT_FOOT_INDEX.value].x,
|
273 |
+
landmarks[mp_pose.PoseLandmark.LEFT_FOOT_INDEX.value].y]
|
274 |
|
275 |
# Calculate angles
|
276 |
+
angleKneeL = calculate_angle(hip, knee, ankle)
|
277 |
+
angleHipL = calculate_angle(shoulder, hip, [hip[0], 0])
|
278 |
+
angleAnkleL = calculate_angle(foot, ankle, knee)
|
279 |
|
280 |
+
#Visualize of left leg
|
281 |
+
cv2.putText(image, str(angleHipL),tuple(np.multiply(angleHipL, [640, 480]).astype(int)),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 255), 2, cv2.LINE_AA)
|
282 |
+
|
283 |
+
# Squat logic
|
284 |
+
if 80 < knee_angle < 110 and 29 < hip_angle < 40:
|
285 |
+
cv2.putText(image, "Squat Detected!", (300, 100), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 3)
|
286 |
+
else:
|
287 |
+
if hip_angle < 29:
|
288 |
+
cv2.putText(image, "Lean Forward!", (300, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
|
289 |
+
elif hip_angle > 45:
|
290 |
+
cv2.putText(image, "Lean Backward!", (300, 200), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
|
291 |
+
if knee_angle < 80:
|
292 |
+
cv2.putText(image, "Squat Too Deep!", (300, 250), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
|
293 |
+
elif knee_angle > 110:
|
294 |
+
cv2.putText(image, "Lower Your Hips!", (300, 300), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 0, 255), 3)
|
295 |
|
296 |
+
# # 1. Bend Forward Warning
|
297 |
+
# if 10 < angleHipL < 18:
|
298 |
+
# print(f"AngleHipL when Bend forward warning:{angleHipL}")
|
299 |
+
# cv2.rectangle(image, (310, 180), (450, 220), (0, 0, 0), -1)
|
300 |
+
# cv2.putText(image,f"Bend Forward",
|
301 |
+
# (320,200),cv2.FONT_HERSHEY_SIMPLEX,1,(150,120,255),1,cv2.LINE_AA)
|
302 |
+
|
303 |
+
# 2. Lean Backward Warning
|
304 |
+
if angleHipL > 45:
|
305 |
+
print(f"AngleHipL when Bend backward warning:{angleHipL}")
|
306 |
+
cv2.rectangle(image, (310, 180), (450, 220), (0, 0, 0), -1)
|
307 |
+
cv2.putText(image,f"Bend Backward",
|
308 |
+
(320,200),cv2.FONT_HERSHEY_SIMPLEX,1,(80,120,255),1,cv2.LINE_AA)
|
309 |
+
|
310 |
+
# stage 2
|
311 |
+
|
312 |
+
# Incorrect movements
|
313 |
+
|
314 |
+
# # 3. Knees not low enough
|
315 |
+
# if 110 < angleKneeL < 130:
|
316 |
+
# print(f"AngleKneeL when Lower Your Hips warning:{angleKneeL}")
|
317 |
+
# cv2.rectangle(image, (220, 40), (450, 80), (0, 0, 0), -1)
|
318 |
+
# cv2.putText(image,f"Lower Your Hips",
|
319 |
+
# (230,60),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1,cv2.LINE_AA)
|
320 |
+
|
321 |
|
322 |
+
# # 3. Knees not low enough and not completed the squat
|
323 |
+
# if angleKneeL>130 and stage=='mid':
|
324 |
+
# print(f"AngleKneeL when Knees not low enough and not completed the squat :{angleKneeL}")
|
325 |
+
# cv2.rectangle(image, (220, 40), (450, 80), (0, 0, 0), -1)
|
326 |
+
# cv2.putText(image,f"Lower Your Hips",
|
327 |
+
# (230,60),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1,cv2.LINE_AA)
|
328 |
+
# print(f"Incorrect counter Knees not low enough and not completed the squat :{incorrect}")
|
329 |
+
# incorrect+=1
|
330 |
+
# stage='up'
|
331 |
+
|
332 |
+
# # 4. Squat too deep
|
333 |
+
# if angleKneeL < 80 and stage=='mid':
|
334 |
+
# print(f"AngleKneeL when Squat too deep warning:{angleKneeL}")
|
335 |
+
# cv2.rectangle(image, (220, 40), (450, 80), (0, 0, 0), -1)
|
336 |
+
# cv2.putText(image,f"Squat too deep",
|
337 |
+
# (230,60),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1,cv2.LINE_AA)
|
338 |
+
# print(f"Incorrect counter when Squat too deep warning:{incorrect}")
|
339 |
+
# incorrect +=1
|
340 |
+
# stage='up'
|
341 |
+
|
342 |
+
# # stage 4
|
343 |
+
# if (80 < angleKneeL < 110) and stage=='mid':
|
344 |
+
# if (18 < angleHipL < 40): # Valid "down" position
|
345 |
+
# print(f"AngleKneeL when valid down position:{angleKneeL}")
|
346 |
+
# print(f"AngleHipL when valid down position:{angleHipL}")
|
347 |
+
# print(f"Correct counter when valid down position:{correct}")
|
348 |
+
# correct+=1
|
349 |
+
# stage='up'
|
350 |
+
# cv2.putText(image,f"Correct:{correct}",
|
351 |
+
# (400,120),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,0),1,cv2.LINE_AA)
|
352 |
+
# cv2.putText(image,f"Incorrect:{incorrect}",
|
353 |
+
# (400,150),cv2.FONT_HERSHEY_SIMPLEX,1,(0,0,0),1,cv2.LINE_AA)
|
354 |
+
|
355 |
+
# #Render Counter to our camera screen
|
356 |
+
# #Setup Status box
|
357 |
+
# cv2.rectangle(image,(0,0),(500,80),(245,117,16),-1)
|
358 |
+
|
359 |
+
# #REP data
|
360 |
+
|
361 |
+
# cv2.putText(image,'Left',(10,12),
|
362 |
+
# cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,0),1,cv2.LINE_AA)
|
363 |
|
364 |
+
# cv2.putText(image,str(correct),
|
365 |
+
# (10,60),cv2.FONT_HERSHEY_SIMPLEX,2,(255,255,255),2,cv2.LINE_AA)
|
|
|
366 |
|
367 |
+
# #Stage data for left leg
|
368 |
+
|
369 |
+
# cv2.putText(image,'STAGE',(230,12),
|
370 |
+
# cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,0),1,cv2.LINE_AA)
|
371 |
+
|
372 |
+
# cv2.putText(image,stage,
|
373 |
+
# (230,60),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,255),1,cv2.LINE_AA)
|
374 |
+
|
375 |
|
376 |
mp_drawing.draw_landmarks(image, results.pose_landmarks, mp_pose.POSE_CONNECTIONS,
|
377 |
mp_drawing.DrawingSpec(color=(255, 175, 0), thickness=2, circle_radius=2),
|
|
|
381 |
return av.VideoFrame.from_ndarray(image, format="bgr24")
|
382 |
|
383 |
|
384 |
+
|
385 |
# WebRTC streamer configuration
|
386 |
+
|
387 |
webrtc_streamer(
|
388 |
key="squat-detection",
|
389 |
mode=WebRtcMode.SENDRECV,
|