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" | |
| } | |