|
|
|
""" |
|
RF-DETR SoccerNet - Simple Usage Examples |
|
|
|
This script demonstrates how to use the RF-DETR SoccerNet model for soccer analysis. |
|
Shows basic video processing, image analysis, and advanced ball possession analysis. |
|
""" |
|
|
|
import os |
|
import sys |
|
import pandas as pd |
|
from pathlib import Path |
|
|
|
|
|
from inference import RFDETRSoccerNet |
|
|
|
|
|
def basic_video_analysis(): |
|
"""Basic video processing example.""" |
|
print("🎬 BASIC VIDEO ANALYSIS EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
print("Loading RF-DETR SoccerNet model...") |
|
model = RFDETRSoccerNet() |
|
|
|
|
|
video_path = "sample_soccer_match.mp4" |
|
|
|
if not os.path.exists(video_path): |
|
print(f"⚠️ Video not found: {video_path}") |
|
print("Please provide a valid video path to test the model.") |
|
return |
|
|
|
|
|
print(f"\nProcessing video: {video_path}") |
|
df = model.process_video( |
|
video_path=video_path, |
|
confidence_threshold=0.5, |
|
frame_skip=5, |
|
max_frames=300, |
|
save_results=True |
|
) |
|
|
|
|
|
print(f"\n📊 ANALYSIS RESULTS") |
|
print(f"Total detections: {len(df):,}") |
|
print(f"Frames analyzed: {df['frame'].nunique():,}") |
|
print(f"Time span: {df['timestamp'].max():.1f} seconds") |
|
|
|
|
|
print(f"\n🎯 Detections by class:") |
|
class_stats = df['class_name'].value_counts() |
|
for class_name, count in class_stats.items(): |
|
percentage = (count / len(df)) * 100 |
|
print(f" {class_name}: {count:,} ({percentage:.1f}%)") |
|
|
|
|
|
print(f"\n💾 Saving results...") |
|
model.save_results(df, "video_analysis.csv", format="csv") |
|
model.save_results(df, "video_analysis.json", format="json") |
|
|
|
return df |
|
|
|
|
|
def image_analysis_example(): |
|
"""Single image processing example.""" |
|
print("\n🖼️ IMAGE ANALYSIS EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
model = RFDETRSoccerNet() |
|
|
|
|
|
image_path = "sample_soccer_frame.jpg" |
|
|
|
if not os.path.exists(image_path): |
|
print(f"⚠️ Image not found: {image_path}") |
|
print("Please provide a valid image path to test the model.") |
|
return |
|
|
|
|
|
print(f"Processing image: {image_path}") |
|
df = model.process_image(image_path, confidence_threshold=0.4) |
|
|
|
|
|
print(f"\n📊 Found {len(df)} objects in the image:") |
|
for _, detection in df.iterrows(): |
|
print(f" - {detection['class_name']}: {detection['confidence']:.2f} " |
|
f"at ({detection['x1']:.0f}, {detection['y1']:.0f})") |
|
|
|
|
|
model.save_results(df, "image_analysis.csv") |
|
|
|
return df |
|
|
|
|
|
def ball_possession_analysis(video_df): |
|
"""Advanced ball possession analysis example.""" |
|
print("\n⚽ BALL POSSESSION ANALYSIS") |
|
print("=" * 50) |
|
|
|
|
|
model = RFDETRSoccerNet() |
|
|
|
|
|
print("Analyzing ball possession events...") |
|
possession_df = model.analyze_ball_possession( |
|
video_df, |
|
distance_threshold=150 |
|
) |
|
|
|
if len(possession_df) == 0: |
|
print("❌ No possession events found. Try lowering the distance threshold.") |
|
return |
|
|
|
|
|
print(f"\n📈 POSSESSION STATISTICS") |
|
print(f"Total possession events: {len(possession_df):,}") |
|
print(f"Average distance to ball: {possession_df['distance_to_ball'].mean():.1f} pixels") |
|
print(f"Possession timeframe: {possession_df['timestamp'].min():.1f}s - {possession_df['timestamp'].max():.1f}s") |
|
|
|
|
|
possession_df['time_interval'] = (possession_df['timestamp'] // 10) * 10 |
|
possession_timeline = possession_df.groupby('time_interval').size() |
|
|
|
print(f"\n⏱️ POSSESSION TIMELINE (10-second intervals):") |
|
for interval, count in possession_timeline.items(): |
|
print(f" {interval:3.0f}s-{interval+10:3.0f}s: {count:3d} events") |
|
|
|
|
|
closest_interactions = possession_df.nsmallest(5, 'distance_to_ball') |
|
print(f"\n🎯 CLOSEST BALL-PLAYER INTERACTIONS:") |
|
for i, interaction in closest_interactions.iterrows(): |
|
print(f" {interaction['timestamp']:.1f}s: {interaction['distance_to_ball']:.1f}px distance") |
|
|
|
|
|
model.save_results(possession_df, "ball_possession_analysis.csv") |
|
print(f"\n💾 Possession analysis saved to ball_possession_analysis.csv") |
|
|
|
return possession_df |
|
|
|
|
|
def advanced_filtering_examples(video_df): |
|
"""Examples of advanced DataFrame filtering and analysis.""" |
|
print("\n🔍 ADVANCED FILTERING EXAMPLES") |
|
print("=" * 50) |
|
|
|
|
|
high_conf_df = video_df[video_df['confidence'] > 0.8] |
|
print(f"High confidence detections (>0.8): {len(high_conf_df):,}") |
|
|
|
|
|
large_objects = video_df[video_df['area'] > 5000] |
|
print(f"Large objects (>5000px²): {len(large_objects):,}") |
|
|
|
|
|
ball_df = video_df[video_df['class_name'] == 'ball'] |
|
if len(ball_df) > 0: |
|
print(f"\n⚽ Ball detection timeline:") |
|
print(f" First ball seen: {ball_df['timestamp'].min():.1f}s") |
|
print(f" Last ball seen: {ball_df['timestamp'].max():.1f}s") |
|
print(f" Ball visible in {ball_df['frame'].nunique()} frames") |
|
print(f" Average ball confidence: {ball_df['confidence'].mean():.2f}") |
|
|
|
|
|
player_density = video_df[video_df['class_name'] == 'player'].groupby('frame').size() |
|
print(f"\n👥 Player density statistics:") |
|
print(f" Average players per frame: {player_density.mean():.1f}") |
|
print(f" Max players in single frame: {player_density.max()}") |
|
print(f" Frames with 10+ players: {(player_density >= 10).sum()}") |
|
|
|
|
|
referee_df = video_df[video_df['class_name'] == 'referee'] |
|
if len(referee_df) > 0: |
|
print(f"\n👨⚖️ Referee activity:") |
|
print(f" Referee visible in {referee_df['frame'].nunique()} frames") |
|
print(f" Average referee confidence: {referee_df['confidence'].mean():.2f}") |
|
|
|
|
|
def main(): |
|
"""Main demo function.""" |
|
print("🚀 RF-DETR SOCCERNET - COMPLETE DEMO") |
|
print("=" * 60) |
|
print("This demo shows how to use RF-DETR SoccerNet for soccer analysis.") |
|
print("Make sure to replace the sample paths with actual video/image files.") |
|
print("=" * 60) |
|
|
|
try: |
|
|
|
video_df = basic_video_analysis() |
|
|
|
|
|
image_df = image_analysis_example() |
|
|
|
|
|
if 'video_df' in locals() and video_df is not None and len(video_df) > 0: |
|
|
|
possession_df = ball_possession_analysis(video_df) |
|
|
|
|
|
advanced_filtering_examples(video_df) |
|
|
|
print(f"\n✅ DEMO COMPLETE!") |
|
print("Check the generated CSV/JSON files for detailed results.") |
|
print("\n📚 Next steps:") |
|
print("1. Replace sample paths with your own soccer videos/images") |
|
print("2. Adjust confidence thresholds and parameters") |
|
print("3. Integrate the DataFrame results into your analysis pipeline") |
|
print("4. Use the ball possession analysis for tactical insights") |
|
|
|
except Exception as e: |
|
print(f"❌ Error during demo: {e}") |
|
print("\nMake sure you have:") |
|
print("1. Installed all requirements: pip install -r requirements.txt") |
|
print("2. Valid video/image files in the current directory") |
|
print("3. CUDA-compatible GPU (or CPU will be used automatically)") |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |