Files changed (4) hide show
  1. .gitignore +7 -0
  2. example.py +43 -3
  3. inference.py +2 -2
  4. out/README.md +1 -0
.gitignore ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ .venv/
2
+ out/*
3
+ !out/README.md
4
+ __pycache__/
5
+
6
+ # ignore model weight in github, they will be re-downloaded
7
+ *.pth
example.py CHANGED
@@ -15,6 +15,40 @@ from pathlib import Path
15
  # Import our RF-DETR SoccerNet class
16
  from inference import RFDETRSoccerNet
17
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
  def basic_image_analysis():
20
  """Basic image processing example using included sample."""
@@ -44,6 +78,12 @@ def basic_image_analysis():
44
  # Display results
45
  print(f"\n๐Ÿ“Š ANALYSIS RESULTS")
46
  print(f"Total detections: {len(df):,}")
 
 
 
 
 
 
47
 
48
  if len(df) > 0:
49
  # Show detections by class
@@ -55,8 +95,8 @@ def basic_image_analysis():
55
 
56
  # Save results
57
  print(f"\n๐Ÿ’พ Saving results...")
58
- model.save_results(df, "image_analysis.csv", format="csv")
59
- model.save_results(df, "image_analysis.json", format="json")
60
  else:
61
  print("No detections found. Try lowering the confidence threshold.")
62
 
@@ -136,7 +176,7 @@ def ball_possession_example():
136
  print(f" Frames with possession: {possession_df['frame'].nunique()}")
137
 
138
  # Save possession analysis
139
- model.save_results(possession_df, "ball_possession_analysis.csv")
140
  print(f"๐Ÿ’พ Possession analysis saved to: ball_possession_analysis.csv")
141
  else:
142
  print("No possession events found. Try increasing the distance threshold.")
 
15
  # Import our RF-DETR SoccerNet class
16
  from inference import RFDETRSoccerNet
17
 
18
+ # for drawing result
19
+ from PIL import Image, ImageDraw, ImageFont
20
+
21
+ def draw_detections_on_image(image, df):
22
+ """Draw bounding boxes on PIL image"""
23
+ draw = ImageDraw.Draw(image)
24
+
25
+ try:
26
+ font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16)
27
+ except:
28
+ font = ImageFont.load_default()
29
+
30
+ colors = {
31
+ 'ball': (255, 0, 0),
32
+ 'player': (0, 255, 0),
33
+ 'referee': (255, 255, 0),
34
+ 'goalkeeper': (0, 0, 255)
35
+ }
36
+
37
+ for _, row in df.iterrows():
38
+ x1, y1, x2, y2 = row['x1'], row['y1'], row['x2'], row['y2']
39
+ class_name = row['class_name']
40
+ conf = row['confidence']
41
+ color = colors.get(class_name, (255, 255, 255))
42
+
43
+ draw.rectangle([x1, y1, x2, y2], outline=color, width=3)
44
+
45
+ text = f"{class_name}: {conf:.2f}"
46
+ bbox = draw.textbbox((x1, y1-20), text, font=font)
47
+ draw.rectangle([bbox[0]-2, bbox[1]-2, bbox[2]+2, bbox[3]+2], fill=color)
48
+ draw.text((x1, y1-20), text, fill=(0, 0, 0), font=font)
49
+
50
+ return image
51
+
52
 
53
  def basic_image_analysis():
54
  """Basic image processing example using included sample."""
 
78
  # Display results
79
  print(f"\n๐Ÿ“Š ANALYSIS RESULTS")
80
  print(f"Total detections: {len(df):,}")
81
+
82
+ # save result image with drawn boxes
83
+ image = Image.open(image_path).convert("RGB")
84
+ result_image = draw_detections_on_image(image, df)
85
+ result_image.save("out/image_analysis_result.jpg")
86
+
87
 
88
  if len(df) > 0:
89
  # Show detections by class
 
95
 
96
  # Save results
97
  print(f"\n๐Ÿ’พ Saving results...")
98
+ model.save_results(df, "out/image_analysis.csv", format="csv")
99
+ model.save_results(df, "out/image_analysis.json", format="json")
100
  else:
101
  print("No detections found. Try lowering the confidence threshold.")
102
 
 
176
  print(f" Frames with possession: {possession_df['frame'].nunique()}")
177
 
178
  # Save possession analysis
179
+ model.save_results(possession_df, "out/ball_possession_analysis.csv")
180
  print(f"๐Ÿ’พ Possession analysis saved to: ball_possession_analysis.csv")
181
  else:
182
  print("No possession events found. Try increasing the distance threshold.")
inference.py CHANGED
@@ -13,7 +13,7 @@ import cv2
13
  import pandas as pd
14
  import numpy as np
15
  import torch
16
- from rfdetr import RFDETRBase
17
  from PIL import Image
18
  from typing import Union, Optional, List, Dict, Tuple
19
  import os
@@ -84,7 +84,7 @@ class RFDETRSoccerNet:
84
  print(f"๐Ÿ“ฆ Loading model from {self.model_path}...")
85
 
86
  # Initialize base model
87
- self.model = RFDETRBase()
88
 
89
  # Reinitialize detection head for 4 classes (critical for compatibility)
90
  print(f"๐Ÿ”ง Reinitializing detection head for {self.num_classes} classes...")
 
13
  import pandas as pd
14
  import numpy as np
15
  import torch
16
+ from rfdetr import RFDETRLarge
17
  from PIL import Image
18
  from typing import Union, Optional, List, Dict, Tuple
19
  import os
 
84
  print(f"๐Ÿ“ฆ Loading model from {self.model_path}...")
85
 
86
  # Initialize base model
87
+ self.model = RFDETRLarge()
88
 
89
  # Reinitialize detection head for 4 classes (critical for compatibility)
90
  print(f"๐Ÿ”ง Reinitializing detection head for {self.num_classes} classes...")
out/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ This directory is for output files.