import os from functools import lru_cache from typing import Callable, Dict, Optional from models.detectors.base import ObjectDetector from models.detectors.owlv2 import Owlv2Detector from models.detectors.yolov8 import HuggingFaceYoloV8Detector from models.detectors.yolov8_defence import HuggingFaceYoloV8DefenceDetector from models.detectors.yolov12_bot_sort import HuggingFaceYoloV12BotSortDetector DEFAULT_DETECTOR = "owlv2" _REGISTRY: Dict[str, Callable[[], ObjectDetector]] = { "owlv2": Owlv2Detector, "hf_yolov8": HuggingFaceYoloV8Detector, "hf_yolov8_defence": HuggingFaceYoloV8DefenceDetector, "hf_yolov12_bot_sort": HuggingFaceYoloV12BotSortDetector, } def _create_detector(name: str) -> ObjectDetector: try: factory = _REGISTRY[name] except KeyError as exc: available = ", ".join(sorted(_REGISTRY)) raise ValueError(f"Unknown detector '{name}'. Available: {available}") from exc return factory() @lru_cache(maxsize=None) def _get_cached_detector(name: str) -> ObjectDetector: return _create_detector(name) def load_detector(name: Optional[str] = None) -> ObjectDetector: """Return a cached detector instance selected via arg or OBJECT_DETECTOR env.""" detector_name = name or os.getenv("OBJECT_DETECTOR", DEFAULT_DETECTOR) return _get_cached_detector(detector_name) # Backwards compatibility for existing callers. def load_model(): return load_detector()