识别结果保存到对应目录下
This commit is contained in:
175
core/all.py
175
core/all.py
@ -1,139 +1,70 @@
|
||||
import cv2
|
||||
from core.ocr import load_model as ocrLoadModel, detect as ocrDetect
|
||||
from core.face import load_model as faceLoadModel, detect as faceDetect
|
||||
from core.yolo import load_model as yoloLoadModel, detect as yoloDetect
|
||||
from concurrent.futures import ThreadPoolExecutor, Future
|
||||
import threading
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
# -------------------------- 核心配置参数 --------------------------
|
||||
MAX_WORKERS = 6 # 线程池最大线程数
|
||||
DETECTION_ORDER = ["yolo", "face", "ocr"] # 检测执行顺序
|
||||
TIMEOUT = 30 # 检测超时时间(秒) 【确保此常量可被外部导入】
|
||||
|
||||
# -------------------------- 全局状态管理 --------------------------
|
||||
_executor = None # 线程池实例
|
||||
_model_loaded = False # 模型加载状态标记
|
||||
_model_lock = threading.Lock() # 模型加载线程锁
|
||||
_executor_lock = threading.Lock() # 线程池初始化锁
|
||||
_task_counter = 0 # 任务计数器
|
||||
_task_counter_lock = threading.Lock() # 任务计数锁
|
||||
# 导入保存路径函数(根据实际文件位置调整导入路径)
|
||||
from core.establish import get_image_save_path
|
||||
# 模型加载状态标记(避免重复加载)
|
||||
|
||||
|
||||
# -------------------------- 工具函数 --------------------------
|
||||
def _get_next_task_id():
|
||||
"""获取唯一任务ID、用于日志追踪"""
|
||||
global _task_counter
|
||||
with _task_counter_lock:
|
||||
_task_counter += 1
|
||||
return _task_counter
|
||||
_model_loaded = False
|
||||
|
||||
|
||||
# -------------------------- 模型加载 --------------------------
|
||||
def load_model():
|
||||
"""加载所有检测模型并初始化线程池(仅执行一次)"""
|
||||
"""加载所有检测模型(仅首次调用时执行)"""
|
||||
global _model_loaded
|
||||
if not _model_loaded:
|
||||
with _model_lock:
|
||||
if not _model_loaded:
|
||||
print("=== 开始加载检测模型 ===")
|
||||
if _model_loaded:
|
||||
print("模型已加载,无需重复执行")
|
||||
return
|
||||
|
||||
# 按顺序加载模型
|
||||
print("加载YOLO模型...")
|
||||
yoloLoadModel()
|
||||
# 依次加载OCR、人脸、YOLO模型
|
||||
ocrLoadModel()
|
||||
faceLoadModel()
|
||||
yoloLoadModel()
|
||||
|
||||
print("加载人脸检测模型...")
|
||||
faceLoadModel()
|
||||
|
||||
print("加载OCR模型...")
|
||||
ocrLoadModel()
|
||||
|
||||
_model_loaded = True
|
||||
print("=== 所有模型加载完成 ===")
|
||||
|
||||
# 初始化线程池
|
||||
_init_thread_pool()
|
||||
_model_loaded = True
|
||||
print("所有检测模型加载完成")
|
||||
|
||||
|
||||
# -------------------------- 线程池管理 --------------------------
|
||||
def _init_thread_pool():
|
||||
"""初始化线程池(仅内部调用)"""
|
||||
global _executor
|
||||
with _executor_lock:
|
||||
if _executor is None:
|
||||
_executor = ThreadPoolExecutor(
|
||||
max_workers=MAX_WORKERS,
|
||||
thread_name_prefix="DetectionThread"
|
||||
)
|
||||
print(f"=== 线程池初始化完成、最大线程数: {MAX_WORKERS} ===")
|
||||
|
||||
|
||||
def shutdown():
|
||||
"""关闭线程池、释放资源"""
|
||||
global _executor
|
||||
with _executor_lock:
|
||||
if _executor is not None:
|
||||
_executor.shutdown(wait=True)
|
||||
_executor = None
|
||||
print("=== 线程池已安全关闭 ===")
|
||||
|
||||
|
||||
# -------------------------- 检测逻辑实现 --------------------------
|
||||
def _detect_in_thread(frame: np.ndarray, task_id: int) -> tuple:
|
||||
"""在子线程中执行检测逻辑(返回4元素tuple:检测是否成功、结果数据、检测器类型、任务ID)"""
|
||||
thread_name = threading.current_thread().name
|
||||
print(f"任务[{task_id}] 开始执行、线程: {thread_name}")
|
||||
|
||||
try:
|
||||
# 按照配置顺序执行检测
|
||||
for detector in DETECTION_ORDER:
|
||||
if detector == "yolo":
|
||||
success, result = yoloDetect(frame)
|
||||
elif detector == "face":
|
||||
success, result = faceDetect(frame)
|
||||
elif detector == "ocr":
|
||||
success, result = ocrDetect(frame)
|
||||
else:
|
||||
success, result = False, None
|
||||
|
||||
print(f"任务[{task_id}] {detector}检测状态: {'成功' if success else '未检测到内容'}")
|
||||
if success:
|
||||
print(f"任务[{task_id}] 完成检测、使用检测器: {detector}")
|
||||
return (success, result, detector, task_id) # 4元素tuple
|
||||
|
||||
# 所有检测器均未检测到结果
|
||||
print(f"任务[{task_id}] 所有检测器均未检测到有效内容")
|
||||
return (False, "未检测到任何有效内容", "none", task_id) # 4元素tuple
|
||||
|
||||
except Exception as e:
|
||||
print(f"任务[{task_id}] 检测过程发生错误: {str(e)}")
|
||||
return (False, f"检测错误: {str(e)}", "error", task_id) # 4元素tuple
|
||||
|
||||
|
||||
# -------------------------- 外部调用接口 --------------------------
|
||||
def detect(frame: np.ndarray) -> Future:
|
||||
def detect(frame):
|
||||
"""
|
||||
提交检测任务到线程池(返回Future对象,需调用result()获取4元素结果)
|
||||
|
||||
参数:
|
||||
frame: 待检测图像(ndarray格式、cv2.imdecode生成)
|
||||
|
||||
返回:
|
||||
Future对象、result()返回tuple: (success, data, detector_type, task_id)
|
||||
success: 布尔值,表示是否检测到有效内容
|
||||
data: 检测结果数据(成功时为具体结果,失败时为错误信息)
|
||||
detector_type: 使用的检测器类型("yolo"/"face"/"ocr"/"none"/"error")
|
||||
task_id: 任务唯一标识
|
||||
执行模型检测,检测到违规时按指定格式保存图片
|
||||
参数:
|
||||
frame: 待检测的图像帧(OpenCV格式,numpy.ndarray类型)
|
||||
返回:
|
||||
(检测结果布尔值, 检测详情, 检测模型类型)
|
||||
"""
|
||||
# 确保模型已加载
|
||||
if not _model_loaded:
|
||||
print("警告: 模型尚未加载、将自动加载")
|
||||
load_model()
|
||||
# 1. YOLO检测(优先级1)
|
||||
yolo_flag, yolo_result = yoloDetect(frame)
|
||||
print(f"YOLO检测结果:{yolo_result}")
|
||||
if yolo_flag:
|
||||
# 直接调用路径生成函数,无需传入原始图片名
|
||||
save_path = get_image_save_path(model_type="yolo")
|
||||
if save_path:
|
||||
cv2.imwrite(save_path, frame)
|
||||
print(f"✅ YOLO违规图片已保存:{save_path}")
|
||||
return (True, yolo_result, "yolo")
|
||||
|
||||
# 生成任务ID
|
||||
task_id = _get_next_task_id()
|
||||
# 2. 人脸检测(优先级2)
|
||||
face_flag, face_result = faceDetect(frame)
|
||||
print(f"人脸检测结果:{face_result}")
|
||||
if face_flag:
|
||||
save_path = get_image_save_path(model_type="face")
|
||||
if save_path:
|
||||
cv2.imwrite(save_path, frame)
|
||||
print(f"✅ 人脸违规图片已保存:{save_path}")
|
||||
return (True, face_result, "face")
|
||||
|
||||
# 提交任务到线程池(返回Future)
|
||||
future = _executor.submit(_detect_in_thread, frame, task_id)
|
||||
print(f"任务[{task_id}]: 已提交到线程池")
|
||||
return future
|
||||
# 3. OCR检测(优先级3)
|
||||
ocr_flag, ocr_result = ocrDetect(frame)
|
||||
print(f"OCR检测结果:{ocr_result}")
|
||||
if ocr_flag:
|
||||
save_path = get_image_save_path(model_type="ocr")
|
||||
if save_path:
|
||||
cv2.imwrite(save_path, frame)
|
||||
print(f"✅ OCR违规图片已保存:{save_path}")
|
||||
return (True, ocr_result, "ocr")
|
||||
|
||||
# 4. 无违规内容(不保存图片)
|
||||
print(f"❌ 未检测到任何违规内容,不保存图片")
|
||||
return (False, "未检测到任何内容", "none")
|
Reference in New Issue
Block a user