gibil commited on
Commit
bca95c6
·
verified ·
1 Parent(s): 010ddfd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +23 -8
app.py CHANGED
@@ -23,6 +23,10 @@ TARGET_FPS = 6.0
23
  # Minimum rep duration in seconds (keeps behavior stable when stride changes)
24
  MIN_REP_SECONDS = 0.33
25
 
 
 
 
 
26
  # Downscale only (no crop) for YOLO inference
27
  # 640 is a safe default across varying camera angles.
28
  MAX_INFER_SIDE = 640
@@ -132,15 +136,18 @@ def analyze_pushup_video_yolo(video_path: str, out_dir: str):
132
  frame_stride = max(1, int(round(float(fps) / float(TARGET_FPS))))
133
  effective_fps = float(fps) / float(frame_stride)
134
 
135
- # Convert time-based minimum rep duration to sampled frames
136
  min_rep_frames = int(math.ceil(MIN_REP_SECONDS * effective_fps))
137
- # Clamp so we don't reject real reps at low fps
138
  min_rep_frames = max(2, min_rep_frames)
139
 
 
 
 
140
  print(
141
  f"[speed] video_fps={fps:.2f} target_fps={TARGET_FPS:.2f} "
142
  f"stride={frame_stride} effective_fps={effective_fps:.2f} "
143
- f"min_rep_frames={min_rep_frames} infer_max_side={MAX_INFER_SIDE}"
 
144
  )
145
 
146
  # 1) First pass: compute angles + confs per sampled frame
@@ -204,12 +211,15 @@ def analyze_pushup_video_yolo(video_path: str, out_dir: str):
204
  elif not np.any(mask):
205
  raise RuntimeError("No valid pose angles detected.")
206
 
207
- # Smooth
208
- win = min(31, (len(angles) // 2) * 2 + 1)
209
- win = max(win, 5)
 
 
 
210
  angles_smooth = savgol_filter(angles, win, 2)
211
 
212
- # 2) Rep detection on smoothed angles
213
  reps = []
214
  state = "WAIT_DOWN"
215
  rep_min = rep_max = rep_conf_sum = rep_len = rep_start = None
@@ -230,6 +240,11 @@ def analyze_pushup_video_yolo(video_path: str, out_dir: str):
230
  rep_conf_sum += cf
231
  rep_len += 1
232
 
 
 
 
 
 
233
  if ang >= UP_ANGLE:
234
  if rep_len >= min_rep_frames:
235
  mean_cf = float(rep_conf_sum / rep_len)
@@ -369,4 +384,4 @@ with gr.Blocks(title="Pushup API (YOLO)") as demo:
369
  )
370
 
371
  if __name__ == "__main__":
372
- demo.launch()
 
23
  # Minimum rep duration in seconds (keeps behavior stable when stride changes)
24
  MIN_REP_SECONDS = 0.33
25
 
26
+ # NEW (from our efficient logic): Maximum rep duration in seconds
27
+ # Prevents very long false reps when tracking fails.
28
+ MAX_REP_SECONDS = 8.0
29
+
30
  # Downscale only (no crop) for YOLO inference
31
  # 640 is a safe default across varying camera angles.
32
  MAX_INFER_SIDE = 640
 
136
  frame_stride = max(1, int(round(float(fps) / float(TARGET_FPS))))
137
  effective_fps = float(fps) / float(frame_stride)
138
 
139
+ # Convert time-based rep duration limits to sampled frames (matches our efficient logic)
140
  min_rep_frames = int(math.ceil(MIN_REP_SECONDS * effective_fps))
 
141
  min_rep_frames = max(2, min_rep_frames)
142
 
143
+ max_rep_frames = int(math.ceil(MAX_REP_SECONDS * effective_fps))
144
+ max_rep_frames = max(min_rep_frames + 2, max_rep_frames)
145
+
146
  print(
147
  f"[speed] video_fps={fps:.2f} target_fps={TARGET_FPS:.2f} "
148
  f"stride={frame_stride} effective_fps={effective_fps:.2f} "
149
+ f"min_rep_frames={min_rep_frames} max_rep_frames={max_rep_frames} "
150
+ f"infer_max_side={MAX_INFER_SIDE}"
151
  )
152
 
153
  # 1) First pass: compute angles + confs per sampled frame
 
211
  elif not np.any(mask):
212
  raise RuntimeError("No valid pose angles detected.")
213
 
214
+ # Smooth (updated to match our efficient logic: ~1 second window scaled by effective_fps)
215
+ win = int(round(effective_fps * 1.0))
216
+ win = max(5, win)
217
+ if win % 2 == 0:
218
+ win += 1
219
+ win = min(win, (len(angles) // 2) * 2 + 1)
220
  angles_smooth = savgol_filter(angles, win, 2)
221
 
222
+ # 2) Rep detection on smoothed angles (updated to match our efficient logic)
223
  reps = []
224
  state = "WAIT_DOWN"
225
  rep_min = rep_max = rep_conf_sum = rep_len = rep_start = None
 
240
  rep_conf_sum += cf
241
  rep_len += 1
242
 
243
+ # Abort absurdly long reps (tracking failure / stall)
244
+ if rep_len > max_rep_frames:
245
+ state = "WAIT_DOWN"
246
+ continue
247
+
248
  if ang >= UP_ANGLE:
249
  if rep_len >= min_rep_frames:
250
  mean_cf = float(rep_conf_sum / rep_len)
 
384
  )
385
 
386
  if __name__ == "__main__":
387
+ demo.launch()