aishaikds/soccernet_object_tracking
1
1import gradio as gr2from PIL import Image, ImageDraw, ImageFont3import cv24import numpy as np5import pandas as pd6import tempfile7import sys8import os9from huggingface_hub import hf_hub_download10 11print("="*60)12print("Setting up RF-DETR SoccerNet Model...")13print("="*60)14 15repo_id = "julianzu9612/RFDETR-Soccernet"16 17try:18 # Download inference.py19 print("\nDownloading inference.py...")20 inference_path = hf_hub_download(repo_id=repo_id, filename="inference.py")21 22 # Read the file23 with open(inference_path, 'r') as f:24 inference_code = f.read()25 26 print("\n๐ง Patching inference.py...")27 print(" Changing: RFDETRBase() โ RFDETRLarge()")28 29 # THE FIX: Replace RFDETRBase with RFDETRLarge30 inference_code = inference_code.replace(31 'from rfdetr import RFDETRBase',32 'from rfdetr import RFDETRLarge'33 )34 inference_code = inference_code.replace(35 'self.model = RFDETRBase()',36 'self.model = RFDETRLarge()'37 )38 39 # Save the patched version40 with open(inference_path, 'w') as f:41 f.write(inference_code)42 print("โ Patched inference.py successfully!")43 44 # Download weights45 print("\nDownloading model weights...")46 weights_path = hf_hub_download(repo_id=repo_id, filename="weights/checkpoint_best_regular.pth")47 print(f"โ Downloaded weights")48 49 # Setup environment50 cache_dir = os.path.dirname(inference_path)51 52 if cache_dir not in sys.path:53 sys.path.insert(0, cache_dir)54 55 original_dir = os.getcwd()56 os.chdir(cache_dir)57 58 # Create weights directory structure59 weights_dir = os.path.join(cache_dir, "weights")60 os.makedirs(weights_dir, exist_ok=True)61 62 expected_weights = os.path.join(weights_dir, "checkpoint_best_regular.pth")63 if not os.path.exists(expected_weights):64 import shutil65 shutil.copy(weights_path, expected_weights)66 print(f"โ Weights copied to: {expected_weights}")67 68 print("\n" + "="*60)69 print("Initializing RF-DETR SoccerNet Model...")70 print("="*60)71 72 # Import and initialize the patched model73 from inference import RFDETRSoccerNet74 75 detector = RFDETRSoccerNet()76 print("\nโ
Model loaded successfully!")77 78 os.chdir(original_dir)79 80except Exception as e:81 print(f"\nโ Error: {e}")82 import traceback83 traceback.print_exc()84 raise85 86# Helper functions for Gradio87def draw_detections_on_image(image, df):88 """Draw bounding boxes on PIL image"""89 draw = ImageDraw.Draw(image)90 91 try:92 font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 16)93 except:94 font = ImageFont.load_default()95 96 colors = {97 'ball': (255, 0, 0),98 'player': (0, 255, 0),99 'referee': (255, 255, 0),100 'goalkeeper': (0, 0, 255)101 }102 103 for _, row in df.iterrows():104 x1, y1, x2, y2 = row['x1'], row['y1'], row['x2'], row['y2']105 class_name = row['class_name']106 conf = row['confidence']107 color = colors.get(class_name, (255, 255, 255))108 109 draw.rectangle([x1, y1, x2, y2], outline=color, width=3)110 111 text = f"{class_name}: {conf:.2f}"112 bbox = draw.textbbox((x1, y1-20), text, font=font)113 draw.rectangle([bbox[0]-2, bbox[1]-2, bbox[2]+2, bbox[3]+2], fill=color)114 draw.text((x1, y1-20), text, fill=(0, 0, 0), font=font)115 116 return image117 118def process_image_interface(image, confidence_threshold):119 """Process image with the model"""120 if image is None:121 return None, pd.DataFrame()122 123 try:124 # Save temporary image125 temp_path = tempfile.mktemp(suffix='.jpg')126 Image.fromarray(image if isinstance(image, np.ndarray) else np.array(image)).save(temp_path)127 128 # Process with model129 df = detector.process_image(temp_path, confidence_threshold=confidence_threshold)130 131 # Draw detections132 img = Image.open(temp_path)133 annotated_img = draw_detections_on_image(img, df)134 135 # Cleanup136 os.remove(temp_path)137 138 return annotated_img, df139 140 except Exception as e:141 print(f"Error processing image: {e}")142 import traceback143 traceback.print_exc()144 return None, pd.DataFrame()145 146def process_video_interface(video, confidence_threshold, frame_skip, max_frames):147 """Process video with the model"""148 if video is None:149 return None, pd.DataFrame()150 151 try:152 max_frames_val = int(max_frames) if max_frames > 0 else None153 154 # Process video155 print(f"Processing video with confidence={confidence_threshold}, frame_skip={frame_skip}, max_frames={max_frames_val}")156 df = detector.process_video(157 video,158 confidence_threshold=confidence_threshold,159 frame_skip=int(frame_skip),160 max_frames=max_frames_val161 )162 163 # Create annotated video164 cap = cv2.VideoCapture(video)165 fps = int(cap.get(cv2.CAP_PROP_FPS))166 width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))167 height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))168 169 output_path = tempfile.mktemp(suffix='.mp4')170 fourcc = cv2.VideoWriter_fourcc(*'mp4v')171 out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))172 173 frame_num = 0174 while cap.isOpened():175 ret, frame = cap.read()176 if not ret:177 break178 179 # Get detections for this frame180 frame_detections = df[df['frame'] == frame_num]181 182 if not frame_detections.empty:183 rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)184 pil_img = Image.fromarray(rgb_frame)185 annotated_pil = draw_detections_on_image(pil_img, frame_detections)186 frame = cv2.cvtColor(np.array(annotated_pil), cv2.COLOR_RGB2BGR)187 188 out.write(frame)189 frame_num += 1190 191 cap.release()192 out.release()193 194 return output_path, df195 196 except Exception as e:197 print(f"Error processing video: {e}")198 import traceback199 traceback.print_exc()200 return None, pd.DataFrame()201 202# Create Gradio interface203with gr.Blocks(title="โฝ Soccer Object Detection", theme=gr.themes.Soft()) as demo:204 gr.Markdown("""205 # โฝ Soccer Object Detection with RF-DETR206 207 Professional-grade object detection for soccer videos using RF-DETR-Large model.208 209 ### Model: [julianzu9612/RFDETR-Soccernet](https://huggingface.co/julianzu9612/RFDETR-Soccernet)210 - **Architecture**: RF-DETR-Large (128M parameters)211 - **Performance**: 85.7% mAP@50, 49.8% mAP212 - **Dataset**: SoccerNet-Tracking 2023 (42,750 images)213 - **Classes**: Ball, Player, Referee, Goalkeeper214 """)215 216 with gr.Tab("๐ธ Image Detection"):217 gr.Markdown("### Upload a soccer image to detect objects")218 219 with gr.Row():220 with gr.Column():221 image_input = gr.Image(label="Upload Soccer Image", type="numpy")222 image_confidence = gr.Slider(223 minimum=0.1, 224 maximum=1.0, 225 value=0.5, 226 step=0.05, 227 label="Confidence Threshold",228 info="Lower values detect more objects but may include false positives"229 )230 image_button = gr.Button("๐ Detect Objects", variant="primary", size="lg")231 232 with gr.Column():233 image_output = gr.Image(label="Detected Objects")234 235 image_detections = gr.Dataframe(236 label="Detection Results",237 wrap=True,238 interactive=False239 )240 241 image_button.click(242 fn=process_image_interface,243 inputs=[image_input, image_confidence],244 outputs=[image_output, image_detections]245 )246 247 gr.Examples(248 examples=[],249 inputs=image_input,250 label="Example Images (Upload your own!)"251 )252 253 with gr.Tab("๐ฅ Video Detection"):254 gr.Markdown("### Upload a soccer video to track objects frame by frame")255 256 with gr.Row():257 with gr.Column():258 video_input = gr.Video(label="Upload Soccer Video")259 video_confidence = gr.Slider(260 minimum=0.1,261 maximum=1.0,262 value=0.5,263 step=0.05,264 label="Confidence Threshold"265 )266 video_frame_skip = gr.Slider(267 minimum=1,268 maximum=10,269 value=5,270 step=1,271 label="Frame Skip",272 info="Process every Nth frame (higher = faster but less detections)"273 )274 video_max_frames = gr.Number(275 value=300,276 label="Max Frames to Process",277 info="Set to 0 to process entire video (300 frames โ 10 seconds at 30 FPS)"278 )279 280 gr.Markdown("""281 #### โก Performance Tips:282 - **CPU**: 2-3 FPS (slow) - Use frame_skip=5 and limit frames283 - **GPU**: 12-30 FPS (fast) - Can process full videos284 - **Quick test**: Use 300 frames with frame_skip=5285 """)286 287 video_button = gr.Button("๐ฌ Process Video", variant="primary", size="lg")288 289 with gr.Column():290 video_output = gr.Video(label="Annotated Video")291 292 video_detections = gr.Dataframe(293 label="Detection Results",294 wrap=True,295 interactive=False296 )297 298 video_button.click(299 fn=process_video_interface,300 inputs=[video_input, video_confidence, video_frame_skip, video_max_frames],301 outputs=[video_output, video_detections]302 )303 304 with gr.Tab("โน๏ธ About"):305 gr.Markdown("""306 ## About This Model307 308 ### ๐ฏ Detected Classes309 310 | Class | Color | Precision | Description |311 |-------|-------|-----------|-------------|312 | ๐ด Ball | Red | 78.5% | Soccer ball detection |313 | ๐ข Player | Green | 91.3% | Field players from both teams |314 | ๐ก Referee | Yellow | 85.2% | Match officials |315 | ๐ต Goalkeeper | Blue | 88.9% | Specialized goalkeeper detection |316 317 ### ๐ Model Performance318 319 - **mAP@50**: 85.7%320 - **mAP**: 49.8%321 - **mAP@75**: 52.0%322 - **Parameters**: 128M323 - **Training Time**: ~14 hours on NVIDIA A100 40GB324 325 ### ๐ Training Details326 327 - **Dataset**: SoccerNet-Tracking 2023328 - **Images**: 42,750 annotated images329 - **Source**: Professional soccer broadcasts330 - **Input Resolution**: 1280x1280 pixels331 - **Optimizer**: AdamW (lr=1e-4)332 333 ### ๐ก Best Practices334 335 1. **Confidence Threshold**: 336 - Use 0.5 for general detection337 - Use 0.7+ for high-precision applications338 339 2. **Video Quality**:340 - Works best on 720p+ broadcast footage341 - Standard broadcast camera angles preferred342 343 3. **Frame Processing**:344 - frame_skip=1: Every frame (best accuracy, slow)345 - frame_skip=5: Every 5th frame (good balance)346 - frame_skip=10: Every 10th frame (fast, lower accuracy)347 348 ### ๐จ Limitations349 350 - Optimized for professional broadcast footage351 - May have reduced accuracy in poor lighting352 - Small balls may be missed when heavily occluded353 - Camera angle dependency354 355 ### ๐ Use Cases356 357 - **Sports Analytics**: Player tracking, formation analysis358 - **Broadcast Enhancement**: Automatic highlighting, statistics overlay359 - **Research**: Tactical analysis, computer vision benchmarking360 - **Video Analytics**: Automated video processing pipelines361 362 ### ๐ Links363 364 - [Model on Hugging Face](https://huggingface.co/julianzu9612/RFDETR-Soccernet)365 - [SoccerNet Dataset](https://www.soccer-net.org/)366 - [RF-DETR Paper](https://arxiv.org/abs/2304.08069)367 368 ### ๐ Citation369 370 ```bibtex371 @misc{rfdetr-soccernet-2025,372 title={RF-DETR SoccerNet: High-Performance Soccer Object Detection},373 author={Computer Vision Research Team},374 year={2025},375 publisher={Hugging Face},376 url={https://huggingface.co/julianzu9612/rf-detr-soccernet}377 }378 ```379 380 ---381 382 **License**: Apache 2.0383 """)384 385print("\n" + "="*60)386print("๐ Launching Gradio Interface...")387print("="*60)388 389demo.launch()