|
|
|
""" |
|
RF-DETR SoccerNet - Complete Usage Examples |
|
|
|
This script demonstrates how to use the RF-DETR SoccerNet model for soccer analysis. |
|
Shows image processing, data analysis, and visualization using included sample files. |
|
""" |
|
|
|
import os |
|
import sys |
|
import pandas as pd |
|
import numpy as np |
|
from pathlib import Path |
|
|
|
|
|
from inference import RFDETRSoccerNet |
|
|
|
|
|
def basic_image_analysis(): |
|
"""Basic image processing example using included sample.""" |
|
print("πΌοΈ BASIC IMAGE ANALYSIS EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
print("Loading RF-DETR SoccerNet model...") |
|
model = RFDETRSoccerNet() |
|
|
|
|
|
image_path = "examples/sample_soccer_frame.jpg" |
|
|
|
if not os.path.exists(image_path): |
|
print(f"β οΈ Sample image not found: {image_path}") |
|
print("Please run this script from the repository root directory.") |
|
return None |
|
|
|
print(f"Processing sample image: {image_path}") |
|
|
|
|
|
df = model.process_image( |
|
image_path=image_path, |
|
confidence_threshold=0.5 |
|
) |
|
|
|
|
|
print(f"\nπ ANALYSIS RESULTS") |
|
print(f"Total detections: {len(df):,}") |
|
|
|
if len(df) > 0: |
|
|
|
print(f"\nπ― Detections by class:") |
|
class_stats = df['class_name'].value_counts() |
|
for class_name, count in class_stats.items(): |
|
avg_conf = df[df['class_name'] == class_name]['confidence'].mean() |
|
print(f" {class_name}: {count} (avg confidence: {avg_conf:.3f})") |
|
|
|
|
|
print(f"\nπΎ Saving results...") |
|
model.save_results(df, "image_analysis.csv", format="csv") |
|
model.save_results(df, "image_analysis.json", format="json") |
|
else: |
|
print("No detections found. Try lowering the confidence threshold.") |
|
|
|
return df |
|
|
|
|
|
def analyze_sample_data(): |
|
"""Analyze sample detection data included in repository.""" |
|
print("\nπ SAMPLE DATA ANALYSIS EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
csv_path = "examples/sample_detections.csv" |
|
|
|
if not os.path.exists(csv_path): |
|
print(f"β οΈ Sample data not found: {csv_path}") |
|
print("Please run this script from the repository root directory.") |
|
return None |
|
|
|
print(f"Loading sample detection data: {csv_path}") |
|
df = pd.read_csv(csv_path) |
|
|
|
|
|
print(f"\nπ Dataset Statistics:") |
|
print(f" Total detections: {len(df):,}") |
|
print(f" Frames: {df['frame'].nunique()}") |
|
print(f" Time span: {df['timestamp'].min():.2f}s - {df['timestamp'].max():.2f}s") |
|
|
|
|
|
print(f"\nπ― Class Distribution:") |
|
class_counts = df['class_name'].value_counts() |
|
for class_name, count in class_counts.items(): |
|
percentage = (count / len(df)) * 100 |
|
avg_conf = df[df['class_name'] == class_name]['confidence'].mean() |
|
print(f" {class_name}: {count} ({percentage:.1f}%) | Avg confidence: {avg_conf:.3f}") |
|
|
|
|
|
print(f"\nπ Confidence Analysis:") |
|
print(f" Overall mean: {df['confidence'].mean():.3f}") |
|
print(f" Overall std: {df['confidence'].std():.3f}") |
|
print(f" Range: {df['confidence'].min():.3f} - {df['confidence'].max():.3f}") |
|
|
|
|
|
print(f"\nπ Object Size Analysis:") |
|
df['area'] = df['width'] * df['height'] |
|
for class_name in df['class_name'].unique(): |
|
class_data = df[df['class_name'] == class_name] |
|
avg_area = class_data['area'].mean() |
|
print(f" {class_name}: {avg_area:.1f} pxΒ² average area") |
|
|
|
return df |
|
|
|
|
|
def ball_possession_example(): |
|
"""Demonstrate ball possession analysis using sample data.""" |
|
print("\nβ½ BALL POSSESSION ANALYSIS EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
csv_path = "examples/sample_detections.csv" |
|
if not os.path.exists(csv_path): |
|
print(f"β οΈ Sample data not found: {csv_path}") |
|
return None |
|
|
|
df = pd.read_csv(csv_path) |
|
|
|
|
|
model = RFDETRSoccerNet() |
|
|
|
print("Analyzing ball possession...") |
|
possession_df = model.analyze_ball_possession(df, distance_threshold=150) |
|
|
|
if len(possession_df) > 0: |
|
print(f"\nπ Possession Analysis Results:") |
|
print(f" Possession events: {len(possession_df)}") |
|
print(f" Average distance to ball: {possession_df['distance_to_ball'].mean():.1f} pixels") |
|
print(f" Frames with possession: {possession_df['frame'].nunique()}") |
|
|
|
|
|
model.save_results(possession_df, "ball_possession_analysis.csv") |
|
print(f"πΎ Possession analysis saved to: ball_possession_analysis.csv") |
|
else: |
|
print("No possession events found. Try increasing the distance threshold.") |
|
|
|
return possession_df |
|
|
|
|
|
def visualization_example(): |
|
"""Show how to work with detection visualizations.""" |
|
print("\nπ¨ VISUALIZATION EXAMPLE") |
|
print("=" * 50) |
|
|
|
|
|
viz_path = "examples/detection_visualization.jpg" |
|
|
|
if os.path.exists(viz_path): |
|
print(f"β
Sample visualization available: {viz_path}") |
|
print("This image shows detected objects with bounding boxes and labels.") |
|
print("Colors: Red=Ball, Green=Player, Yellow=Referee, Cyan=Goalkeeper") |
|
|
|
|
|
file_size = os.path.getsize(viz_path) / (1024 * 1024) |
|
print(f"π Visualization size: {file_size:.2f} MB") |
|
else: |
|
print(f"β οΈ Visualization not found: {viz_path}") |
|
print("You can create visualizations by drawing bounding boxes on images.") |
|
|
|
|
|
print(f"\nπ‘ To create your own visualizations:") |
|
print("1. Use cv2.rectangle() to draw bounding boxes") |
|
print("2. Use cv2.putText() to add labels") |
|
print("3. Use different colors for each class") |
|
print("4. Save with cv2.imwrite()") |
|
|
|
|
|
def advanced_usage_tips(): |
|
"""Show advanced usage patterns and tips.""" |
|
print("\nπ ADVANCED USAGE TIPS") |
|
print("=" * 50) |
|
|
|
print("π Model Configuration:") |
|
print(" - Use confidence_threshold=0.3 for more detections") |
|
print(" - Use confidence_threshold=0.7 for higher precision") |
|
print(" - Process every N frames: frame_skip=N for faster analysis") |
|
|
|
print(f"\nβ‘ Performance Tips:") |
|
print(" - GPU acceleration: Model automatically uses CUDA if available") |
|
print(" - Batch processing: Process multiple images in sequence") |
|
print(" - Memory: Large videos may need max_frames limit") |
|
|
|
print(f"\nπ Data Export Options:") |
|
print(" - CSV: Best for spreadsheet analysis") |
|
print(" - JSON: Best for web applications") |
|
print(" - Parquet: Best for large datasets") |
|
|
|
print(f"\nπ― Use Cases:") |
|
print(" - Player tracking and formation analysis") |
|
print(" - Ball possession and movement statistics") |
|
print(" - Referee positioning analysis") |
|
print(" - Automated highlight generation") |
|
print(" - Broadcast enhancement") |
|
|
|
|
|
def main(): |
|
"""Run all examples in sequence.""" |
|
print("π RF-DETR SOCCERNET - COMPLETE EXAMPLES") |
|
print("=" * 60) |
|
print("This script demonstrates all features using included sample files.") |
|
print("No external videos or images required!") |
|
print("=" * 60) |
|
|
|
try: |
|
|
|
image_results = basic_image_analysis() |
|
sample_analysis = analyze_sample_data() |
|
possession_results = ball_possession_example() |
|
visualization_example() |
|
advanced_usage_tips() |
|
|
|
print(f"\nπ ALL EXAMPLES COMPLETED SUCCESSFULLY!") |
|
print("Check the generated files:") |
|
print(" - image_analysis.csv") |
|
print(" - image_analysis.json") |
|
print(" - ball_possession_analysis.csv") |
|
|
|
except Exception as e: |
|
print(f"\nβ Error running examples: {e}") |
|
print("Make sure you're running from the repository root directory.") |
|
import traceback |
|
traceback.print_exc() |
|
|
|
|
|
if __name__ == "__main__": |
|
main() |