Files
dataset-yolo-script/sam2-cpu/frigate_mini/detector/yolo_detector.py
T
2026-02-04 15:29:36 +07:00

124 lines
3.6 KiB
Python

"""
Ultralytics YOLO detector backend.
"""
import numpy as np
import logging
from typing import List, Optional
from .base import BaseDetector, Detection, BBox
logger = logging.getLogger(__name__)
class YOLODetector(BaseDetector):
"""
Ultralytics YOLO detector.
Supports YOLOv5, YOLOv8, YOLOv9, etc.
"""
def __init__(
self,
model_path: str,
conf_threshold: float = 0.25,
nms_threshold: float = 0.45,
device: str = "cpu",
class_names: Optional[dict] = None,
):
"""
Initialize YOLO detector.
Args:
model_path: Path to .pt model file
conf_threshold: Confidence threshold
nms_threshold: NMS IoU threshold
device: Device to run on ('cpu', 'cuda', '0', etc.)
class_names: Class ID to name mapping
"""
super().__init__(
model_path=model_path,
conf_threshold=conf_threshold,
nms_threshold=nms_threshold,
class_names=class_names,
)
self.device = device
def load_model(self) -> bool:
"""Load YOLO model."""
try:
from ultralytics import YOLO
logger.info(f"Loading YOLO model: {self.model_path}")
self.model = YOLO(self.model_path)
self.model.to(self.device)
# Update class names from model if available
if hasattr(self.model, 'names'):
self.class_names = self.model.names
logger.info(f"YOLO model loaded on {self.device}")
return True
except ImportError:
logger.error("ultralytics package not found. Install with: pip install ultralytics")
return False
except Exception as e:
logger.error(f"Failed to load YOLO model: {e}")
return False
def detect(self, frame: np.ndarray) -> List[Detection]:
"""
Run detection on frame.
Args:
frame: Input image (BGR, HWC)
Returns:
List of Detection objects
"""
if self.model is None:
logger.warning("Model not loaded")
return []
try:
# Run inference
results = self.model.predict(
frame,
conf=self.conf_threshold,
iou=self.nms_threshold,
verbose=False,
)
detections = []
for result in results:
if result.boxes is None:
continue
for box in result.boxes:
class_id = int(box.cls[0].item())
confidence = float(box.conf[0].item())
x1, y1, x2, y2 = box.xyxy[0].tolist()
class_name = self.class_names.get(class_id, str(class_id))
detection = Detection(
class_id=class_id,
class_name=class_name,
confidence=confidence,
bbox=BBox(x1=x1, y1=y1, x2=x2, y2=y2),
)
detections.append(detection)
return detections
except Exception as e:
logger.error(f"Detection error: {e}")
return []
def release(self) -> None:
"""Release resources."""
self.model = None
logger.info("YOLO detector released")