"""Detector factory: build a Detector from AppConfig. Kept separate from ``app.py`` so both the app bootstrap and the UI can build detectors without an import cycle. Raises ``ValueError`` (not ``SystemExit``) on bad config so the GUI can show the message instead of exiting. """ from __future__ import annotations from ...config import AppConfig from .base import Detector from .classic_cv import ClassicCVDetector from .types import CensorType def _require_model(config: AppConfig) -> str: if not config.model_path: raise ValueError( "Для детектора YOLO укажите путь к весам (.pt) в Параметрах " "или скачайте модель LADA — см. README." ) return config.model_path def build_detector(config: AppConfig) -> Detector: if config.detector == "classic": return ClassicCVDetector(config.detection) if config.detector == "yolo": from .yolo import YoloDetector # lazy: pulls torch/ultralytics return YoloDetector(_require_model(config), config.detection) if config.detector == "combined": # YOLO handles mosaic; classic-CV handles black bars / blur. from .composite import CompositeDetector from .yolo import YoloDetector return CompositeDetector([ YoloDetector(_require_model(config), config.detection), ClassicCVDetector(config.detection, types={CensorType.BLACK_BAR, CensorType.BLUR}), ]) raise ValueError(f"Неизвестный детектор: {config.detector!r}")