dschandra commited on
Commit
e24f9eb
·
verified ·
1 Parent(s): d72a7a2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -5
app.py CHANGED
@@ -133,6 +133,59 @@ def lbw_decision(ball_positions, full_trajectory, frames, pitch_point, impact_po
133
  return f"Out (Ball hits stumps)", full_trajectory, pitch_point, impact_point
134
  return f"Not Out (Missing stumps)", full_trajectory, pitch_point, impact_point
135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
  def draw_3d_scene(trajectory, pitch_point, impact_point, decision):
137
  if not HAS_OPENGL:
138
  return
@@ -198,6 +251,10 @@ def drs_review(video):
198
  full_trajectory, vis_trajectory, pitch_point, pitch_frame, impact_point, impact_frame, trajectory_log = estimate_trajectory_3d(ball_positions, detection_frames, frames)
199
  decision, full_trajectory, pitch_point, impact_point = lbw_decision(ball_positions, full_trajectory, frames, pitch_point, impact_point)
200
 
 
 
 
 
201
  if HAS_OPENGL:
202
  init_3d_window(800, 600)
203
  from OpenGL.GLUT import glutInit, glutSolidSphere
@@ -206,9 +263,6 @@ def drs_review(video):
206
  draw_3d_scene(full_trajectory, pitch_point, impact_point, decision)
207
  event.pump()
208
 
209
- output_path = f"output_{uuid.uuid4()}.mp4"
210
- slow_motion_path = None # To be enhanced with 3D export
211
-
212
  debug_output = f"{debug_log}\n{trajectory_log}"
213
  return f"DRS Decision: {decision}\nDebug Log:\n{debug_output}", slow_motion_path
214
 
@@ -218,10 +272,10 @@ iface = gr.Interface(
218
  inputs=gr.Video(label="Upload Video Clip"),
219
  outputs=[
220
  gr.Textbox(label="DRS Decision and Debug Log"),
221
- gr.Video(label="3D Visualization (Separate Window if enabled)")
222
  ],
223
  title="AI-Powered 3D DRS for LBW",
224
- description="Upload a video clip for 3D DRS analysis with pitching (green), impact (red), and wickets (orange) visualization."
225
  )
226
 
227
  if __name__ == "__main__":
 
133
  return f"Out (Ball hits stumps)", full_trajectory, pitch_point, impact_point
134
  return f"Not Out (Missing stumps)", full_trajectory, pitch_point, impact_point
135
 
136
+ def generate_slow_motion(frames, vis_trajectory, pitch_point, pitch_frame, impact_point, impact_frame, detection_frames, output_path, decision, frame_width, frame_height):
137
+ if not frames:
138
+ return None
139
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
140
+ out = cv2.VideoWriter(output_path, fourcc, FRAME_RATE / SLOW_MOTION_FACTOR, (frame_width, frame_height))
141
+
142
+ trajectory_points = np.array([[p[0] * frame_width / PITCH_LENGTH, frame_height - (p[1] * frame_height / (STUMPS_HEIGHT * 2))] for p in vis_trajectory], dtype=np.int32).reshape((-1, 1, 2))
143
+
144
+ for i, frame in enumerate(frames):
145
+ # Draw stumps outline (scaled back to pixel coordinates)
146
+ stumps_x = frame_width / 2
147
+ stumps_y = frame_height * 0.8
148
+ stumps_width_pixels = frame_width * (STUMPS_WIDTH / PITCH_LENGTH)
149
+ stumps_height_pixels = frame_height * (STUMPS_HEIGHT / (STUMPS_HEIGHT * 2))
150
+ cv2.line(frame, (int(stumps_x - stumps_width_pixels / 2), int(stumps_y)),
151
+ (int(stumps_x + stumps_width_pixels / 2), int(stumps_y)), (255, 255, 255), 2)
152
+ cv2.line(frame, (int(stumps_x - stumps_width_pixels / 2), int(stumps_y - stumps_height_pixels)),
153
+ (int(stumps_x - stumps_width_pixels / 2), int(stumps_y)), (255, 255, 255), 2)
154
+ cv2.line(frame, (int(stumps_x + stumps_width_pixels / 2), int(stumps_y - stumps_height_pixels)),
155
+ (int(stumps_x + stumps_width_pixels / 2), int(stumps_y)), (255, 255, 255), 2)
156
+
157
+ # Draw crease line
158
+ cv2.line(frame, (int(stumps_x - stumps_width_pixels / 2), int(stumps_y)),
159
+ (int(stumps_x + stumps_width_pixels / 2), int(stumps_y)), (255, 255, 0), 2)
160
+
161
+ if i in detection_frames and trajectory_points.size > 0:
162
+ idx = detection_frames.index(i) + 1
163
+ if idx <= len(trajectory_points):
164
+ cv2.polylines(frame, [trajectory_points[:idx]], False, (0, 0, 255), 2) # Blue trajectory
165
+
166
+ if pitch_point and i == pitch_frame:
167
+ x = pitch_point[0] * frame_width / PITCH_LENGTH
168
+ y = frame_height - (pitch_point[1] * frame_height / (STUMPS_HEIGHT * 2))
169
+ cv2.circle(frame, (int(x), int(y)), 8, (0, 255, 0), -1) # Green for pitching
170
+ cv2.putText(frame, "Pitching", (int(x) + 10, int(y) - 10),
171
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
172
+
173
+ if impact_point and i == impact_frame:
174
+ x = impact_point[0] * frame_width / PITCH_LENGTH
175
+ y = frame_height - (impact_point[1] * frame_height / (STUMPS_HEIGHT * 2))
176
+ cv2.circle(frame, (int(x), int(y)), 8, (0, 0, 255), -1) # Red for impact
177
+ cv2.putText(frame, "Impact", (int(x) + 10, int(y) + 20),
178
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
179
+
180
+ if impact_point and i == impact_frame and "Out" in decision:
181
+ cv2.putText(frame, "Wickets", (int(stumps_x) - 50, int(stumps_y) - 20),
182
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 165, 255), 1) # Orange for wickets
183
+
184
+ for _ in range(SLOW_MOTION_FACTOR):
185
+ out.write(frame)
186
+ out.release()
187
+ return output_path
188
+
189
  def draw_3d_scene(trajectory, pitch_point, impact_point, decision):
190
  if not HAS_OPENGL:
191
  return
 
251
  full_trajectory, vis_trajectory, pitch_point, pitch_frame, impact_point, impact_frame, trajectory_log = estimate_trajectory_3d(ball_positions, detection_frames, frames)
252
  decision, full_trajectory, pitch_point, impact_point = lbw_decision(ball_positions, full_trajectory, frames, pitch_point, impact_point)
253
 
254
+ frame_height, frame_width = frames[0].shape[:2]
255
+ output_path = f"output_{uuid.uuid4()}.mp4"
256
+ slow_motion_path = generate_slow_motion(frames, vis_trajectory, pitch_point, pitch_frame, impact_point, impact_frame, detection_frames, output_path, decision, frame_width, frame_height)
257
+
258
  if HAS_OPENGL:
259
  init_3d_window(800, 600)
260
  from OpenGL.GLUT import glutInit, glutSolidSphere
 
263
  draw_3d_scene(full_trajectory, pitch_point, impact_point, decision)
264
  event.pump()
265
 
 
 
 
266
  debug_output = f"{debug_log}\n{trajectory_log}"
267
  return f"DRS Decision: {decision}\nDebug Log:\n{debug_output}", slow_motion_path
268
 
 
272
  inputs=gr.Video(label="Upload Video Clip"),
273
  outputs=[
274
  gr.Textbox(label="DRS Decision and Debug Log"),
275
+ gr.Video(label="Slow-Motion Replay with 2D Annotations")
276
  ],
277
  title="AI-Powered 3D DRS for LBW",
278
+ description="Upload a video clip for 3D DRS analysis with pitching (green), impact (red), and wickets (orange) visualization, and 2D annotated video output."
279
  )
280
 
281
  if __name__ == "__main__":