2025-09-04 22:59:27 +08:00
|
|
|
|
import os
|
2025-09-12 14:05:09 +08:00
|
|
|
|
import numpy as np
|
2025-09-04 22:59:27 +08:00
|
|
|
|
from ultralytics import YOLO
|
2025-09-12 14:05:09 +08:00
|
|
|
|
from service.model_service import get_current_yolo_model # 从模型管理模块获取模型
|
2025-09-04 22:59:27 +08:00
|
|
|
|
|
2025-09-12 14:05:09 +08:00
|
|
|
|
# 全局模型变量
|
2025-09-04 22:59:27 +08:00
|
|
|
|
_yolo_model = None
|
|
|
|
|
|
|
|
|
|
|
2025-09-12 14:05:09 +08:00
|
|
|
|
def load_model(model_path=None):
|
|
|
|
|
"""加载YOLO模型(优先使用模型管理模块的默认模型)"""
|
2025-09-04 22:59:27 +08:00
|
|
|
|
global _yolo_model
|
|
|
|
|
|
2025-09-12 14:05:09 +08:00
|
|
|
|
if model_path is None:
|
|
|
|
|
_yolo_model = get_current_yolo_model()
|
|
|
|
|
return _yolo_model is not None
|
|
|
|
|
|
2025-09-04 22:59:27 +08:00
|
|
|
|
try:
|
|
|
|
|
_yolo_model = YOLO(model_path)
|
2025-09-12 14:05:09 +08:00
|
|
|
|
return True
|
2025-09-04 22:59:27 +08:00
|
|
|
|
except Exception as e:
|
2025-09-12 14:05:09 +08:00
|
|
|
|
print(f"YOLO模型加载失败(指定路径):{str(e)}")
|
2025-09-04 22:59:27 +08:00
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def detect(frame, conf_threshold=0.2):
|
2025-09-12 14:05:09 +08:00
|
|
|
|
"""执行目标检测,返回(是否成功, 结果字符串)"""
|
2025-09-04 22:59:27 +08:00
|
|
|
|
global _yolo_model
|
|
|
|
|
|
2025-09-12 14:05:09 +08:00
|
|
|
|
# 确保模型已加载
|
|
|
|
|
if not _yolo_model:
|
|
|
|
|
if not load_model():
|
|
|
|
|
return (False, "模型未初始化")
|
|
|
|
|
|
|
|
|
|
if frame is None:
|
|
|
|
|
return (False, "无效输入帧")
|
2025-09-04 22:59:27 +08:00
|
|
|
|
|
|
|
|
|
try:
|
2025-09-12 14:05:09 +08:00
|
|
|
|
# 执行检测(frame应为numpy数组)
|
|
|
|
|
results = _yolo_model(frame, conf=conf_threshold, verbose=False)
|
2025-09-04 22:59:27 +08:00
|
|
|
|
has_results = len(results[0].boxes) > 0 if results else False
|
|
|
|
|
|
|
|
|
|
if not has_results:
|
|
|
|
|
return (False, "未检测到目标")
|
|
|
|
|
|
|
|
|
|
# 构建结果字符串
|
|
|
|
|
result_parts = []
|
|
|
|
|
for box in results[0].boxes:
|
|
|
|
|
cls = int(box.cls[0])
|
|
|
|
|
conf = float(box.conf[0])
|
2025-09-12 14:05:09 +08:00
|
|
|
|
bbox = [round(x, 2) for x in box.xyxy[0].tolist()] # 保留两位小数
|
2025-09-04 22:59:27 +08:00
|
|
|
|
class_name = _yolo_model.names[cls] if hasattr(_yolo_model, 'names') else f"类别{cls}"
|
2025-09-12 14:05:09 +08:00
|
|
|
|
result_parts.append(f"{class_name}(置信度:{conf:.2f},位置:{bbox})")
|
2025-09-04 22:59:27 +08:00
|
|
|
|
|
2025-09-12 14:05:09 +08:00
|
|
|
|
return (True, "; ".join(result_parts))
|
2025-09-04 22:59:27 +08:00
|
|
|
|
|
|
|
|
|
except Exception as e:
|
2025-09-12 14:05:09 +08:00
|
|
|
|
print(f"检测过程出错:{str(e)}")
|
|
|
|
|
return (False, f"检测错误:{str(e)}")
|