akarsh999 commited on
Commit
2279e94
·
verified ·
1 Parent(s): 73bd548

Upload 9 files

Browse files
Files changed (1) hide show
  1. athletic_performance.py +31 -116
athletic_performance.py CHANGED
@@ -182,124 +182,42 @@ def draw_pose_landmarks(frame, landmarks, knee_analysis=None):
182
  return frame
183
 
184
 
185
- def draw_jump_reference_arrows(frame, references, person_landmarks, is_jumping, user_height_cm):
186
- """
187
- Draw reference arrows for average and professional jump heights near the person.
188
- Only shows when the person is actively jumping.
189
 
190
- Args:
191
- frame: Video frame to draw on
192
- references (dict): Jump height references {'average': float, 'professional': float}
193
- person_landmarks: MediaPipe pose landmarks
194
- is_jumping (bool): Whether the person is currently jumping
195
- user_height_cm (float): User's height for scaling
196
 
197
- Returns:
198
- frame: Frame with reference arrows drawn
199
- """
200
- if not is_jumping or not person_landmarks:
201
- return frame
202
 
203
- h, w, _ = frame.shape
 
 
204
 
205
- # Get person's hip position (center point)
206
- left_hip = person_landmarks.landmark[mp.solutions.pose.PoseLandmark.LEFT_HIP]
207
- right_hip = person_landmarks.landmark[mp.solutions.pose.PoseLandmark.RIGHT_HIP]
208
-
209
- # Calculate person center
210
- person_x = int((left_hip.x + right_hip.x) / 2 * w)
211
- person_y = int((left_hip.y + right_hip.y) / 2 * h)
212
-
213
- # Calculate scaling factor (pixels per cm based on person height in frame)
214
- head = person_landmarks.landmark[mp.solutions.pose.PoseLandmark.NOSE]
215
- left_ankle = person_landmarks.landmark[mp.solutions.pose.PoseLandmark.LEFT_ANKLE]
216
- right_ankle = person_landmarks.landmark[mp.solutions.pose.PoseLandmark.RIGHT_ANKLE]
217
-
218
- # Person height in frame (head to ankle)
219
- ankle_y = (left_ankle.y + right_ankle.y) / 2
220
- person_height_pixels = abs(ankle_y - head.y) * h
221
- pixels_per_cm = person_height_pixels / user_height_cm if user_height_cm > 0 else 1
222
-
223
- # Ground reference (ankle level)
224
- ground_y = int(ankle_y * h)
225
-
226
- # Calculate reference positions
227
- avg_height = references.get('average', 0)
228
- pro_height = references.get('professional', 0)
229
-
230
- # Position arrows to the right side of the person
231
- arrow_x_start = person_x + 60
232
- arrow_x_end = person_x + 120
233
-
234
- # Draw average performance arrow
235
- if avg_height > 0:
236
- avg_y = int(ground_y - (avg_height * pixels_per_cm))
237
- if 20 < avg_y < h - 20: # Only draw if within frame
238
- # Draw arrow pointing to average height
239
- cv2.arrowedLine(frame, (arrow_x_start, avg_y), (arrow_x_end, avg_y),
240
- (255, 255, 0), 4, tipLength=0.3) # Yellow arrow
241
- cv2.putText(frame, f"Avg: {avg_height:.0f}cm", (arrow_x_end + 10, avg_y + 5),
242
- cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
243
-
244
- # Draw professional performance arrow
245
- if pro_height > 0:
246
- pro_y = int(ground_y - (pro_height * pixels_per_cm))
247
- if 20 < pro_y < h - 20: # Only draw if within frame
248
- # Draw arrow pointing to professional height
249
- cv2.arrowedLine(frame, (arrow_x_start, pro_y), (arrow_x_end, pro_y),
250
- (0, 255, 0), 4, tipLength=0.3) # Green arrow
251
- cv2.putText(frame, f"Pro: {pro_height:.0f}cm", (arrow_x_end + 10, pro_y + 5),
252
- cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
253
 
254
- return frame
255
-
256
-
257
- def detect_jumping_phase(landmarks, frame_height):
258
- """
259
- Detect if the person is currently in a jumping phase based on pose.
260
 
261
- Args:
262
- landmarks: MediaPipe pose landmarks
263
- frame_height (int): Height of the video frame
 
 
264
 
265
- Returns:
266
- bool: True if person appears to be jumping
267
- """
268
- if not landmarks:
269
- return False
270
 
271
- try:
272
- # Get key landmarks
273
- left_ankle = landmarks.landmark[mp.solutions.pose.PoseLandmark.LEFT_ANKLE]
274
- right_ankle = landmarks.landmark[mp.solutions.pose.PoseLandmark.RIGHT_ANKLE]
275
- left_knee = landmarks.landmark[mp.solutions.pose.PoseLandmark.LEFT_KNEE]
276
- right_knee = landmarks.landmark[mp.solutions.pose.PoseLandmark.RIGHT_KNEE]
277
- left_hip = landmarks.landmark[mp.solutions.pose.PoseLandmark.LEFT_HIP]
278
- right_hip = landmarks.landmark[mp.solutions.pose.PoseLandmark.RIGHT_HIP]
279
-
280
- # Calculate average positions
281
- ankle_y = (left_ankle.y + right_ankle.y) / 2
282
- knee_y = (left_knee.y + right_knee.y) / 2
283
- hip_y = (left_hip.y + right_hip.y) / 2
284
-
285
- # Check if person is in jumping posture
286
- # Jumping indicators:
287
- # 1. Knees are significantly bent (knee-hip distance is small)
288
- # 2. Person is in takeoff/landing phase (dynamic posture)
289
-
290
- knee_hip_distance = abs(knee_y - hip_y) * frame_height
291
- ankle_knee_distance = abs(ankle_y - knee_y) * frame_height
292
-
293
- # If knees are bent (shorter distances) or in dynamic position, likely jumping
294
- is_crouched = knee_hip_distance < 40 or ankle_knee_distance < 40
295
-
296
- # Additional check: if ankles are not at the bottom of frame, person might be airborne
297
- is_airborne = ankle_y < 0.85 # If ankles are not in bottom 15% of frame
298
-
299
- return is_crouched or is_airborne
300
-
301
- except (AttributeError, IndexError):
302
- return False
303
 
304
 
305
  def calculate_peak_power_output(jump_height_m, body_mass_kg, flight_time_s):
@@ -555,12 +473,9 @@ def generate_annotated_video(video_path, user_height_cm, user_weight_kg, gender,
555
  # Draw pose landmarks with strain indicators
556
  annotated_frame = draw_pose_landmarks(frame, results.pose_landmarks, knee_analysis)
557
 
558
- # Detect if person is currently jumping
559
- is_jumping = detect_jumping_phase(results.pose_landmarks, h)
560
-
561
- # Draw jump reference arrows (only when jumping)
562
- annotated_frame = draw_jump_reference_arrows(
563
- annotated_frame, jump_references, results.pose_landmarks, is_jumping, user_height_cm
564
  )
565
 
566
  # Add performance info overlay
 
182
  return frame
183
 
184
 
185
+ def draw_jump_reference_lines(frame, references, current_jump_height, user_height_cm):
186
+ """Draw average and professional jump height reference lines."""
187
+ h, w, _ = frame.shape
 
188
 
189
+ # Calculate line positions (relative to frame height)
190
+ # Assume the person's height spans about 70% of frame height
191
+ person_height_pixels = int(h * 0.7)
192
+ pixels_per_cm = person_height_pixels / user_height_cm
 
 
193
 
194
+ # Base line (ground level) - bottom 10% of frame
195
+ ground_y = int(h * 0.9)
 
 
 
196
 
197
+ # Reference lines
198
+ avg_jump_pixels = int(references["average"] * pixels_per_cm)
199
+ pro_jump_pixels = int(references["professional"] * pixels_per_cm)
200
 
201
+ avg_line_y = ground_y - avg_jump_pixels
202
+ pro_line_y = ground_y - pro_jump_pixels
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
+ # Draw ground line
205
+ cv2.line(frame, (0, ground_y), (w, ground_y), (100, 100, 100), 2)
206
+ cv2.putText(frame, "Ground", (10, ground_y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (100, 100, 100), 2)
 
 
 
207
 
208
+ # Draw average line
209
+ if avg_line_y > 0:
210
+ cv2.line(frame, (0, avg_line_y), (w, avg_line_y), (255, 255, 0), 2)
211
+ cv2.putText(frame, f"Avg: {references['average']:.0f}cm",
212
+ (10, avg_line_y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2)
213
 
214
+ # Draw professional line
215
+ if pro_line_y > 0:
216
+ cv2.line(frame, (0, pro_line_y), (w, pro_line_y), (0, 255, 0), 2)
217
+ cv2.putText(frame, f"Pro: {references['professional']:.0f}cm",
218
+ (10, pro_line_y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
219
 
220
+ return frame
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
 
222
 
223
  def calculate_peak_power_output(jump_height_m, body_mass_kg, flight_time_s):
 
473
  # Draw pose landmarks with strain indicators
474
  annotated_frame = draw_pose_landmarks(frame, results.pose_landmarks, knee_analysis)
475
 
476
+ # Draw jump reference lines
477
+ annotated_frame = draw_jump_reference_lines(
478
+ annotated_frame, jump_references, current_jump_height, user_height_cm
 
 
 
479
  )
480
 
481
  # Add performance info overlay