ixxan's picture
Update app.py
776ce65 verified
import gradio as gr
import os
import numpy as np
from utils import read_video, save_video
from trackers import Tracker
from team_assigner import TeamAssigner
from player_ball_assigner import PlayerBallAssigner
from camera_movement_estimator import CameraMovementEstimator
from view_transformer import ViewTransformer
from speed_and_distance_estimator import SpeedAndDistance_Estimator
def process_video(input_video, player_stats=True, ball_stats=True):
print("input: " + input_video)
# Read Video
video_frames = read_video(input_video) # use the uploaded file
# Initialize Tracker
tracker = Tracker('models/best.pt')
if input_video.endswith("121364_0_small.mp4"):
print("loading cached tracks")
tracks = tracker.get_object_tracks(video_frames,
read_from_stub=True,
stub_path='stubs/track_stub_121364_0_small.pkl')
else:
tracks = tracker.get_object_tracks(video_frames)
# Interpolate Ball Positions
tracks["ball"] = tracker.interpolate_ball_positions(tracks["ball"])
# Get object positions
tracker.add_position_to_tracks(tracks)
# Camera movement estimator
camera_movement_estimator = CameraMovementEstimator(video_frames[0])
if input_video.endswith("121364_0_small.mp4"):
print("loading cached camera movements")
camera_movement_per_frame = camera_movement_estimator.get_camera_movement(video_frames,
read_from_stub=True,
stub_path='stubs/camera_movement_stub_121364_0_small.pkl')
else:
camera_movement_per_frame = camera_movement_estimator.get_camera_movement(video_frames)
camera_movement_estimator.add_adjust_positions_to_tracks(tracks, camera_movement_per_frame)
# View Transformer
view_transformer = ViewTransformer()
view_transformer.add_transformed_position_to_tracks(tracks)
# Speed and distance estimator
speed_and_distance_estimator = SpeedAndDistance_Estimator()
exclude_objects=['referees', 'players', 'ball']
if player_stats:
exclude_objects.remove('players')
if ball_stats:
exclude_objects.remove('ball')
speed_and_distance_estimator.add_speed_and_distance_to_tracks(tracks, exclude_objects)
# Assign Player Teams
team_assigner = TeamAssigner()
team_assigner.assign_team_color(video_frames[0], tracks['players'][0])
for frame_num, player_track in enumerate(tracks['players']):
for player_id, track in player_track.items():
team = team_assigner.get_player_team(video_frames[frame_num], track['bbox'], player_id)
tracks['players'][frame_num][player_id]['team'] = team
tracks['players'][frame_num][player_id]['team_color'] = team_assigner.team_colors[team]
# Assign Ball Acquisition
player_assigner = PlayerBallAssigner()
team_ball_control = []
for frame_num, player_track in enumerate(tracks['players']):
ball_bbox = tracks['ball'][frame_num][1]['bbox']
assigned_player = player_assigner.assign_ball_to_player(player_track, ball_bbox)
if assigned_player != -1:
tracks['players'][frame_num][assigned_player]['has_ball'] = True
team_ball_control.append(tracks['players'][frame_num][assigned_player]['team'])
else:
if team_ball_control: # in case first few frames assigned_player == -1
team_ball_control.append(team_ball_control[-1])
team_ball_control = np.array(team_ball_control)
# Draw output
output_video_frames = tracker.draw_annotations(video_frames, tracks, team_ball_control)
output_video_frames = camera_movement_estimator.draw_camera_movement(output_video_frames, camera_movement_per_frame)
speed_and_distance_estimator.draw_speed_and_distance(output_video_frames, tracks)
# Save output video
output_path = 'output_videos/output_video.avi'
save_video(output_video_frames, output_path)
return output_path
# Gradio Interface
title="Football Match Analytics with YOLO and OpenCV"
description="""
This demo processes football game videos to detect players and referees, track the ball, assign players to teams using color pixel clustering, and compute ball possession per team.
It also estimates camera movement with Lucas-Kanade optical flow and applies perspective transformation to calculate the real-time speed and total distance traveled by each player and the ball.
The YOLO detection model was fine-tuned with this dataset: https://universe.roboflow.com/roboflow-jvuqo/football-players-detection-3zvbc/dataset
Original Tutorial Reference: https://www.youtube.com/watch?v=neBZ6huolkg
**Note**: this space is running on a CPU, so inferencing new video may take some time. (Avg time during test: 1min processing per 5 second of video)"""
examples = [["input_videos/121364_0_small.mp4", True, True]]
interface = gr.Interface(fn=process_video,
inputs=[
gr.Video(label="Upload Video (mp4, avi, mov) Max: 30sec"),
gr.Checkbox(label="Include Player Stats", value=True),
gr.Checkbox(label="Include Ball Stats", value=True)
],
outputs=gr.Video(label="Processed Video"),
examples=examples,
live=False, # No live update to avoid real-time processing issues
title=title,
description=description) # Allow users to download the processed video
interface.launch(debug=True, show_error = True)