Mirko Trasciatti
commited on
Commit
·
62b40d2
1
Parent(s):
778b9c7
Use adaptive speed threshold and area fallback for kick detection
Browse files
app.py
CHANGED
|
@@ -575,11 +575,14 @@ def _detect_kick_frame(state: AppState, target_obj_id: int) -> int | None:
|
|
| 575 |
frames = sorted(smoothed.keys())
|
| 576 |
speed_series = [speeds.get(f, 0.0) for f in frames]
|
| 577 |
|
| 578 |
-
baseline_window = min(
|
| 579 |
baseline_speeds = speed_series[:baseline_window]
|
| 580 |
baseline_speed = statistics.median(baseline_speeds) if baseline_speeds else 0.0
|
| 581 |
-
|
| 582 |
-
|
|
|
|
|
|
|
|
|
|
| 583 |
sustain_frames = 3
|
| 584 |
holdout_frames = 8
|
| 585 |
return_distance = 12.0
|
|
@@ -598,14 +601,14 @@ def _detect_kick_frame(state: AppState, target_obj_id: int) -> int | None:
|
|
| 598 |
for j in range(1, sustain_frames + 1):
|
| 599 |
if idx + j >= len(frames):
|
| 600 |
break
|
| 601 |
-
if speed_series[idx + j] < speed_threshold * 0.
|
| 602 |
sustain_ok = False
|
| 603 |
break
|
| 604 |
if not sustain_ok:
|
| 605 |
continue
|
| 606 |
|
| 607 |
-
area_pass = True
|
| 608 |
current_area = areas_dict.get(frame)
|
|
|
|
| 609 |
if current_area:
|
| 610 |
prev_areas = [
|
| 611 |
areas_dict.get(f)
|
|
@@ -614,9 +617,11 @@ def _detect_kick_frame(state: AppState, target_obj_id: int) -> int | None:
|
|
| 614 |
]
|
| 615 |
if prev_areas:
|
| 616 |
median_prev = statistics.median(prev_areas)
|
| 617 |
-
if median_prev > 0
|
| 618 |
-
|
| 619 |
-
|
|
|
|
|
|
|
| 620 |
continue
|
| 621 |
|
| 622 |
moved_far = True
|
|
|
|
| 575 |
frames = sorted(smoothed.keys())
|
| 576 |
speed_series = [speeds.get(f, 0.0) for f in frames]
|
| 577 |
|
| 578 |
+
baseline_window = min(10, len(frames) // 3 or 1)
|
| 579 |
baseline_speeds = speed_series[:baseline_window]
|
| 580 |
baseline_speed = statistics.median(baseline_speeds) if baseline_speeds else 0.0
|
| 581 |
+
speed_std = statistics.pstdev(baseline_speeds) if len(baseline_speeds) > 1 else 0.0
|
| 582 |
+
base_threshold = baseline_speed + 4.0 * speed_std
|
| 583 |
+
if base_threshold < baseline_speed * 3.0:
|
| 584 |
+
base_threshold = baseline_speed * 3.0
|
| 585 |
+
speed_threshold = max(base_threshold, 15.0)
|
| 586 |
sustain_frames = 3
|
| 587 |
holdout_frames = 8
|
| 588 |
return_distance = 12.0
|
|
|
|
| 601 |
for j in range(1, sustain_frames + 1):
|
| 602 |
if idx + j >= len(frames):
|
| 603 |
break
|
| 604 |
+
if speed_series[idx + j] < speed_threshold * 0.7:
|
| 605 |
sustain_ok = False
|
| 606 |
break
|
| 607 |
if not sustain_ok:
|
| 608 |
continue
|
| 609 |
|
|
|
|
| 610 |
current_area = areas_dict.get(frame)
|
| 611 |
+
area_pass = True
|
| 612 |
if current_area:
|
| 613 |
prev_areas = [
|
| 614 |
areas_dict.get(f)
|
|
|
|
| 617 |
]
|
| 618 |
if prev_areas:
|
| 619 |
median_prev = statistics.median(prev_areas)
|
| 620 |
+
if median_prev > 0:
|
| 621 |
+
ratio = current_area / median_prev
|
| 622 |
+
if ratio > area_drop_ratio:
|
| 623 |
+
area_pass = False
|
| 624 |
+
if not area_pass and speed < speed_threshold * 1.2:
|
| 625 |
continue
|
| 626 |
|
| 627 |
moved_far = True
|