Spaces:
Sleeping
Sleeping
import numpy as np | |
def predict_trajectory(detection_data, pitch_height=720, stump_zone=(280, 360)): | |
""" | |
Uses polynomial regression to predict post-impact ball trajectory. | |
Args: | |
detection_data: output from `detect_lbw_event` | |
pitch_height: total frame height (in pixels) to simulate stumps | |
stump_zone: x-coordinate range for stumps (min_x, max_x) | |
Returns: | |
dict with: | |
- trajectory_points: [(x, y), ...] actual + predicted | |
- decision: "OUT" or "NOT OUT" | |
""" | |
ball_positions = detection_data["ball_positions"] | |
impact_frame = detection_data["impact_frame"] | |
if not ball_positions or impact_frame == -1: | |
return { | |
"trajectory_points": [], | |
"decision": "NOT ENOUGH DATA" | |
} | |
# Extract coordinates pre-impact | |
xs = [] | |
ys = [] | |
for idx, x, y in ball_positions: | |
if idx <= impact_frame: | |
xs.append(x) | |
ys.append(y) | |
if len(xs) < 5: | |
return { | |
"trajectory_points": [], | |
"decision": "NOT ENOUGH POINTS" | |
} | |
# Fit polynomial regression (degree 2 for parabolic path) | |
coeffs = np.polyfit(xs, ys, deg=2) | |
poly = np.poly1d(coeffs) | |
# Predict future trajectory | |
last_x = xs[-1] | |
future_xs = list(range(last_x, last_x + 60, 5)) # simulate 60px ahead | |
future_ys = [int(poly(x)) for x in future_xs] | |
trajectory_points = list(zip(xs, ys)) + list(zip(future_xs, future_ys)) | |
# OUT logic: predicted y crosses stump plane and x within stump zone | |
for x, y in zip(future_xs, future_ys): | |
if y >= pitch_height - 150: # near stump base | |
if stump_zone[0] <= x <= stump_zone[1]: | |
return { | |
"trajectory_points": trajectory_points, | |
"decision": "OUT" | |
} | |
return { | |
"trajectory_points": trajectory_points, | |
"decision": "NOT OUT" | |
} | |