AjaykumarPilla commited on
Commit
3159747
·
verified ·
1 Parent(s): 74942a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -17
app.py CHANGED
@@ -24,6 +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
 
28
  def process_video(video_path):
29
  if not os.path.exists(video_path):
@@ -50,10 +51,11 @@ def process_video(video_path):
50
  for detection in results[0].boxes:
51
  if detection.cls == 0: # Class 0 is the ball
52
  detections += 1
53
- x1, y1, x2, y2 = detection.xyxy[0].cpu().numpy()
54
- ball_positions.append([(x1 + x2) / 2, (y1 + y2) / 2])
55
- detection_frames.append(frame_count - 1)
56
- cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
 
57
  frames[-1] = frame
58
  debug_log.append(f"Frame {frame_count}: {detections} ball detections")
59
  cap.release()
@@ -80,12 +82,26 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
80
  return None, None, None, None, None, None, None, None, None, "Error: Fewer than 2 ball detections for trajectory"
81
  frame_height, frame_width = frames[0].shape[:2]
82
 
83
- x_coords = [pos[0] for pos in ball_positions]
84
- y_coords = [pos[1] for pos in ball_positions]
85
- times = np.array(detection_frames) / FRAME_RATE
 
 
 
 
 
 
 
86
 
87
- pitch_point = ball_positions[0]
88
- pitch_frame = detection_frames[0]
 
 
 
 
 
 
 
89
 
90
  # Prioritize sudden y-change for impact detection
91
  impact_idx = None
@@ -94,16 +110,16 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
94
  delta_y = abs(y_coords[i] - y_coords[i-1])
95
  if delta_y > IMPACT_DELTA_Y:
96
  impact_idx = i
97
- impact_frame = detection_frames[i]
98
  break
99
  elif y_coords[i] > frame_height * IMPACT_ZONE_Y:
100
  impact_idx = i
101
- impact_frame = detection_frames[i]
102
  break
103
  if impact_idx is None:
104
- impact_idx = len(ball_positions) - 1
105
- impact_frame = detection_frames[-1]
106
- impact_point = ball_positions[impact_idx]
107
 
108
  try:
109
  fx = interp1d(times[:impact_idx + 1], x_coords[:impact_idx + 1], kind='linear', fill_value="extrapolate")
@@ -111,13 +127,13 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
111
  except Exception as e:
112
  return None, None, None, None, None, None, None, None, None, f"Error in trajectory interpolation: {str(e)}"
113
 
114
- t_full = np.linspace(times[0], times[-1] + 0.5, len(times) + 10)
115
  x_full = fx(t_full)
116
  y_full = fy(t_full)
117
  trajectory_2d = list(zip(x_full, y_full))
118
 
119
  trajectory_3d = [pixel_to_3d(x, y, frame_height, frame_width) for x, y in trajectory_2d]
120
- detections_3d = [pixel_to_3d(x, y, frame_height, frame_width) for x, y in ball_positions]
121
  pitch_point_3d = pixel_to_3d(pitch_point[0], pitch_point[1], frame_height, frame_width)
122
  impact_point_3d = pixel_to_3d(impact_point[0], impact_point[1], frame_height, frame_width)
123
 
@@ -125,7 +141,7 @@ def estimate_trajectory(ball_positions, frames, detection_frames):
125
  f"Trajectory estimated successfully\n"
126
  f"Pitch point at frame {pitch_frame + 1}: ({pitch_point[0]:.1f}, {pitch_point[1]:.1f})\n"
127
  f"Impact point at frame {impact_frame + 1}: ({impact_point[0]:.1f}, {impact_point[1]:.1f})\n"
128
- f"Detections in frames: {detection_frames}"
129
  )
130
  return trajectory_2d, pitch_point, impact_point, pitch_frame, impact_frame, detections_3d, trajectory_3d, pitch_point_3d, impact_point_3d, debug_log
131
 
 
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 = 100 # Pixels, threshold for unexpected position changes
28
 
29
  def process_video(video_path):
30
  if not os.path.exists(video_path):
 
51
  for detection in results[0].boxes:
52
  if detection.cls == 0: # Class 0 is the ball
53
  detections += 1
54
+ if detections == 1: # Only consider frames with exactly one detection
55
+ x1, y1, x2, y2 = detection.xyxy[0].cpu().numpy()
56
+ ball_positions.append([(x1 + x2) / 2, (y1 + y2) / 2])
57
+ detection_frames.append(frame_count - 1)
58
+ cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2)
59
  frames[-1] = frame
60
  debug_log.append(f"Frame {frame_count}: {detections} ball detections")
61
  cap.release()
 
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 unexpected jumps in position
86
+ filtered_positions = [ball_positions[0]]
87
+ filtered_frames = [detection_frames[0]]
88
+ for i in range(1, len(ball_positions)):
89
+ prev_pos = ball_positions[i-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
 
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"
98
+
99
+ x_coords = [pos[0] for pos in filtered_positions]
100
+ y_coords = [pos[1] for pos in filtered_positions]
101
+ times = np.array(filtered_frames) / FRAME_RATE
102
+
103
+ pitch_point = filtered_positions[0]
104
+ pitch_frame = filtered_frames[0]
105
 
106
  # Prioritize sudden y-change for impact detection
107
  impact_idx = None
 
110
  delta_y = abs(y_coords[i] - y_coords[i-1])
111
  if delta_y > IMPACT_DELTA_Y:
112
  impact_idx = i
113
+ impact_frame = filtered_frames[i]
114
  break
115
  elif y_coords[i] > frame_height * IMPACT_ZONE_Y:
116
  impact_idx = i
117
+ impact_frame = filtered_frames[i]
118
  break
119
  if impact_idx is None:
120
+ impact_idx = len(filtered_positions) - 1
121
+ impact_frame = filtered_frames[-1]
122
+ impact_point = filtered_positions[impact_idx]
123
 
124
  try:
125
  fx = interp1d(times[:impact_idx + 1], x_coords[:impact_idx + 1], kind='linear', fill_value="extrapolate")
 
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] + 0.5, len(times) * 2) # Smoother trajectory
131
  x_full = fx(t_full)
132
  y_full = fy(t_full)
133
  trajectory_2d = list(zip(x_full, y_full))
134
 
135
  trajectory_3d = [pixel_to_3d(x, y, frame_height, frame_width) for x, y in trajectory_2d]
136
+ detections_3d = [pixel_to_3d(x, y, frame_height, frame_width) for x, y in filtered_positions]
137
  pitch_point_3d = pixel_to_3d(pitch_point[0], pitch_point[1], frame_height, frame_width)
138
  impact_point_3d = pixel_to_3d(impact_point[0], impact_point[1], frame_height, frame_width)
139
 
 
141
  f"Trajectory estimated successfully\n"
142
  f"Pitch point at frame {pitch_frame + 1}: ({pitch_point[0]:.1f}, {pitch_point[1]:.1f})\n"
143
  f"Impact point at frame {impact_frame + 1}: ({impact_point[0]:.1f}, {impact_point[1]:.1f})\n"
144
+ f"Detections in frames: {filtered_frames}"
145
  )
146
  return trajectory_2d, pitch_point, impact_point, pitch_frame, impact_frame, detections_3d, trajectory_3d, pitch_point_3d, impact_point_3d, debug_log
147