Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -24,7 +24,7 @@ PITCH_LENGTH = 20.12 # meters (standard cricket pitch length)
|
|
24 |
STUMPS_HEIGHT = 0.71 # meters (stumps height)
|
25 |
CAMERA_HEIGHT = 2.0 # meters (assumed camera height)
|
26 |
CAMERA_DISTANCE = 10.0 # meters (assumed camera distance from pitch)
|
27 |
-
MAX_POSITION_JUMP =
|
28 |
|
29 |
def process_video(video_path):
|
30 |
if not os.path.exists(video_path):
|
@@ -82,16 +82,19 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
|
|
82 |
return None, None, None, None, None, None, None, None, None, "Error: Fewer than 2 ball detections for trajectory"
|
83 |
frame_height, frame_width = frames[0].shape[:2]
|
84 |
|
85 |
-
# Filter out
|
86 |
filtered_positions = [ball_positions[0]]
|
87 |
filtered_frames = [detection_frames[0]]
|
88 |
for i in range(1, len(ball_positions)):
|
89 |
-
prev_pos =
|
90 |
curr_pos = ball_positions[i]
|
91 |
distance = np.sqrt((curr_pos[0] - prev_pos[0])**2 + (curr_pos[1] - prev_pos[1])**2)
|
92 |
if distance <= MAX_POSITION_JUMP:
|
93 |
filtered_positions.append(curr_pos)
|
94 |
filtered_frames.append(detection_frames[i])
|
|
|
|
|
|
|
95 |
|
96 |
if len(filtered_positions) < 2:
|
97 |
return None, None, None, None, None, None, None, None, None, "Error: Fewer than 2 valid ball detections after filtering"
|
@@ -122,12 +125,13 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
|
|
122 |
impact_point = filtered_positions[impact_idx]
|
123 |
|
124 |
try:
|
125 |
-
|
126 |
-
|
|
|
127 |
except Exception as e:
|
128 |
return None, None, None, None, None, None, None, None, None, f"Error in trajectory interpolation: {str(e)}"
|
129 |
|
130 |
-
t_full = np.linspace(times[0], times[-1]
|
131 |
x_full = fx(t_full)
|
132 |
y_full = fy(t_full)
|
133 |
trajectory_2d = list(zip(x_full, y_full))
|
|
|
24 |
STUMPS_HEIGHT = 0.71 # meters (stumps height)
|
25 |
CAMERA_HEIGHT = 2.0 # meters (assumed camera height)
|
26 |
CAMERA_DISTANCE = 10.0 # meters (assumed camera distance from pitch)
|
27 |
+
MAX_POSITION_JUMP = 50 # Pixels, threshold for unexpected position changes
|
28 |
|
29 |
def process_video(video_path):
|
30 |
if not os.path.exists(video_path):
|
|
|
82 |
return None, None, None, None, None, None, None, None, None, "Error: Fewer than 2 ball detections for trajectory"
|
83 |
frame_height, frame_width = frames[0].shape[:2]
|
84 |
|
85 |
+
# Filter out sudden changes in position for continuous trajectory
|
86 |
filtered_positions = [ball_positions[0]]
|
87 |
filtered_frames = [detection_frames[0]]
|
88 |
for i in range(1, len(ball_positions)):
|
89 |
+
prev_pos = filtered_positions[-1]
|
90 |
curr_pos = ball_positions[i]
|
91 |
distance = np.sqrt((curr_pos[0] - prev_pos[0])**2 + (curr_pos[1] - prev_pos[1])**2)
|
92 |
if distance <= MAX_POSITION_JUMP:
|
93 |
filtered_positions.append(curr_pos)
|
94 |
filtered_frames.append(detection_frames[i])
|
95 |
+
else:
|
96 |
+
# Skip sudden jumps to maintain continuity
|
97 |
+
continue
|
98 |
|
99 |
if len(filtered_positions) < 2:
|
100 |
return None, None, None, None, None, None, None, None, None, "Error: Fewer than 2 valid ball detections after filtering"
|
|
|
125 |
impact_point = filtered_positions[impact_idx]
|
126 |
|
127 |
try:
|
128 |
+
# Use cubic interpolation for smoother trajectory
|
129 |
+
fx = interp1d(times[:impact_idx + 1], x_coords[:impact_idx + 1], kind='cubic', fill_value="extrapolate")
|
130 |
+
fy = interp1d(times[:impact_idx + 1], y_coords[:impact_idx + 1], kind='cubic', fill_value="extrapolate")
|
131 |
except Exception as e:
|
132 |
return None, None, None, None, None, None, None, None, None, f"Error in trajectory interpolation: {str(e)}"
|
133 |
|
134 |
+
t_full = np.linspace(times[0], times[-1], len(times) * 4) # Dense points for smooth trajectory
|
135 |
x_full = fx(t_full)
|
136 |
y_full = fy(t_full)
|
137 |
trajectory_2d = list(zip(x_full, y_full))
|