Files
mediaproc/detect/profiles/soccer.py
2026-03-26 04:40:00 -03:00

76 lines
2.6 KiB
Python

"""Soccer broadcast profile — pitch hoardings, kits, scoreboards."""
from __future__ import annotations
from detect.models import BrandDetection, BrandStats, DetectionReport, PipelineStats
from .base import (
CropContext,
DetectionConfig,
FrameExtractionConfig,
OCRConfig,
ResolverConfig,
SceneFilterConfig,
)
class SoccerBroadcastProfile:
name = "soccer_broadcast"
def frame_extraction_config(self) -> FrameExtractionConfig:
return FrameExtractionConfig(fps=2.0, max_frames=500)
def scene_filter_config(self) -> SceneFilterConfig:
return SceneFilterConfig(hamming_threshold=8, enabled=True)
def detection_config(self) -> DetectionConfig:
return DetectionConfig(
model_name="yolov8n.pt",
confidence_threshold=0.3,
target_classes=[], # empty = accept all COCO classes (until custom model)
)
def ocr_config(self) -> OCRConfig:
return OCRConfig(languages=["en", "es"], min_confidence=0.5)
def resolver_config(self) -> ResolverConfig:
return ResolverConfig(fuzzy_threshold=75)
def vlm_prompt(self, crop_context: CropContext) -> str:
hint = f" Position: {crop_context.position_hint}." if crop_context.position_hint else ""
text = f" Nearby text: '{crop_context.surrounding_text}'." if crop_context.surrounding_text else ""
return (
f"Identify the brand or sponsor visible in this cropped region "
f"from a soccer broadcast.{hint}{text} "
f"Respond with: brand, confidence (0-1), reasoning."
)
def aggregate(self, detections: list[BrandDetection]) -> DetectionReport:
brands: dict[str, BrandStats] = {}
for d in detections:
if d.brand not in brands:
brands[d.brand] = BrandStats()
s = brands[d.brand]
s.total_appearances += 1
s.total_screen_time += d.duration
s.avg_confidence = (
(s.avg_confidence * (s.total_appearances - 1) + d.confidence)
/ s.total_appearances
)
if s.first_seen == 0.0 or d.timestamp < s.first_seen:
s.first_seen = d.timestamp
if d.timestamp > s.last_seen:
s.last_seen = d.timestamp
return DetectionReport(
video_source="",
content_type=self.name,
duration_seconds=0.0,
brands=brands,
timeline=sorted(detections, key=lambda d: d.timestamp),
pipeline_stats=PipelineStats(),
)
def auxiliary_detections(self, source: str) -> list[BrandDetection]:
return []