39 lines
1.6 KiB
Python
39 lines
1.6 KiB
Python
"""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.
|
|
|
|
YOLO-only, but multi-model: every path in ``config.detector_models`` (ticked under
|
|
models/yolo/<category>/) becomes a YoloDetector tagged with its category, and they
|
|
run together via :class:`~.multi.MultiYoloDetector`. The classic-CV detector and the
|
|
``combined`` composite were removed (noisy/approximate on real footage).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from ...config import AppConfig
|
|
from .base import Detector
|
|
from .registry import category_of
|
|
|
|
|
|
def build_detector(config: AppConfig) -> Detector:
|
|
models = [m for m in config.detector_models if Path(m).is_file()]
|
|
if not models:
|
|
raise ValueError(
|
|
"Не выбрана ни одна модель детекции.\n"
|
|
"Положите веса YOLO в models/yolo/<категория>/ (например models/yolo/mosaic/) "
|
|
"и отметьте их галочкой в меню «Модели». См. README."
|
|
)
|
|
# lazy imports: YoloDetector pulls in torch/ultralytics only when a detect runs
|
|
from .multi import MultiYoloDetector
|
|
from .yolo import YoloDetector
|
|
|
|
nms_iou = config.nms_iou if config.cross_model_nms else None
|
|
return MultiYoloDetector(
|
|
[YoloDetector(m, config.detection, label=category_of(m)) for m in models],
|
|
nms_iou=nms_iou,
|
|
)
|