feat: 新增PaddlePaddle检测支持,重构项目架构
1. 新增concurrently依赖用于并行启动服务 2. 新增服务器启动脚本统一管理环境变量和虚拟环境 3. 新增PaddlePaddle推理引擎和配套工具代码 4. 新增抽烟检测Paddle模型支持,完善模型管理 5. 重构开发启动脚本,优化开发体验 6. 更新.gitignore排除不必要的外部目录和缓存 7. 完善文档说明,新增PaddlePaddle部署指南
This commit is contained in:
@@ -4,6 +4,7 @@ import numpy as np
|
||||
import time
|
||||
import uuid
|
||||
import logging
|
||||
import torch
|
||||
from typing import Dict, List, Optional
|
||||
from PIL import Image, ImageDraw, ImageFont
|
||||
|
||||
@@ -45,19 +46,60 @@ class DetectionService:
|
||||
|
||||
try:
|
||||
results = model(image, conf=confidence, iou=iou, verbose=False)
|
||||
|
||||
|
||||
detections = []
|
||||
for result in results:
|
||||
boxes = result.boxes
|
||||
|
||||
|
||||
if len(boxes) == 0:
|
||||
logger.info(f"模型 {model_id} 没有检测到目标")
|
||||
continue
|
||||
|
||||
for box in boxes:
|
||||
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
|
||||
conf = float(box.conf[0].cpu().numpy())
|
||||
cls = int(box.cls[0].cpu().numpy())
|
||||
class_name = result.names[cls]
|
||||
try:
|
||||
|
||||
if isinstance(box.xyxy, torch.Tensor) and box.xyxy.dim() > 0:
|
||||
x1, y1, x2, y2 = float(box.xyxy[0]), float(box.xyxy[1]), float(box.xyxy[2]), float(box.xyxy[3])
|
||||
elif isinstance(box.xyxy, (list, tuple)):
|
||||
x1, y1, x2, y2 = float(box.xyxy[0]), float(box.xyxy[1]), float(box.xyxy[2]), float(box.xyxy[3])
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
|
||||
if isinstance(box.conf, torch.Tensor):
|
||||
if box.conf.dim() == 0:
|
||||
conf = float(box.conf)
|
||||
else:
|
||||
conf = float(box.conf[0])
|
||||
elif hasattr(box.conf, '__getitem__'):
|
||||
conf = float(box.conf[0])
|
||||
else:
|
||||
conf = float(box.conf)
|
||||
|
||||
if isinstance(box.cls, torch.Tensor):
|
||||
if box.cls.dim() == 0:
|
||||
cls = int(box.cls)
|
||||
else:
|
||||
cls = int(box.cls[0])
|
||||
elif hasattr(box.cls, '__getitem__'):
|
||||
cls = int(box.cls[0])
|
||||
else:
|
||||
cls = int(box.cls)
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
logger.error(f"访问 box 属性失败: {e}, box 类型: {type(box)}")
|
||||
logger.error(f"错误堆栈: {traceback.format_exc()}")
|
||||
logger.error(f"box 属性: {vars(box) if hasattr(box, '__dict__') else '无法获取'}")
|
||||
continue
|
||||
|
||||
class_name = result.names[cls]
|
||||
|
||||
label_map = self.model_service.model_configs[model_id]['labels']
|
||||
label = label_map.get(class_name, class_name)
|
||||
|
||||
|
||||
detections.append({
|
||||
'class': class_name,
|
||||
'label': label,
|
||||
@@ -120,21 +162,58 @@ class DetectionService:
|
||||
detections = []
|
||||
for result in results:
|
||||
boxes = result.boxes
|
||||
|
||||
|
||||
for box in boxes:
|
||||
x1, y1, x2, y2 = box.xyxy[0].cpu().numpy()
|
||||
conf = float(box.conf[0].cpu().numpy())
|
||||
cls = int(box.cls[0].cpu().numpy())
|
||||
class_name = result.names[cls]
|
||||
|
||||
label_map = self.model_service.model_configs[model_id]['labels']
|
||||
label = label_map.get(class_name, class_name)
|
||||
|
||||
detections.append({
|
||||
'class': class_name,
|
||||
'label': label,
|
||||
'confidence': round(conf, 3),
|
||||
'bbox': [int(x1), int(y1), int(x2), int(y2)]
|
||||
})
|
||||
try:
|
||||
|
||||
|
||||
if isinstance(box.xyxy, torch.Tensor) and box.xyxy.dim() > 0:
|
||||
x1, y1, x2, y2 = float(box.xyxy[0]), float(box.xyxy[1]), float(box.xyxy[2]), float(box.xyxy[3])
|
||||
elif isinstance(box.xyxy, (list, tuple)):
|
||||
x1, y1, x2, y2 = float(box.xyxy[0]), float(box.xyxy[1]), float(box.xyxy[2]), float(box.xyxy[3])
|
||||
else:
|
||||
continue
|
||||
|
||||
|
||||
if isinstance(box.conf, torch.Tensor):
|
||||
if box.conf.dim() == 0:
|
||||
conf = float(box.conf)
|
||||
else:
|
||||
conf = float(box.conf[0])
|
||||
elif hasattr(box.conf, '__getitem__'):
|
||||
conf = float(box.conf[0])
|
||||
else:
|
||||
conf = float(box.conf)
|
||||
|
||||
if isinstance(box.cls, torch.Tensor):
|
||||
if box.cls.dim() == 0:
|
||||
cls = int(box.cls)
|
||||
else:
|
||||
cls = int(box.cls[0])
|
||||
elif hasattr(box.cls, '__getitem__'):
|
||||
cls = int(box.cls[0])
|
||||
else:
|
||||
cls = int(box.cls)
|
||||
|
||||
|
||||
class_name = result.names[cls]
|
||||
|
||||
label_map = self.model_service.model_configs[model_id]['labels']
|
||||
label = label_map.get(class_name, class_name)
|
||||
|
||||
detections.append({
|
||||
'class': class_name,
|
||||
'label': label,
|
||||
'confidence': round(conf, 3),
|
||||
'bbox': [int(x1), int(y1), int(x2), int(y2)]
|
||||
})
|
||||
except Exception as e:
|
||||
import traceback
|
||||
logger.error(f"VIDEO DEBUG: 访问 box 属性失败: {e}, box 类型: {type(box)}")
|
||||
logger.error(f"VIDEO DEBUG: 错误堆栈: {traceback.format_exc()}")
|
||||
logger.error(f"VIDEO DEBUG: box 属性: {vars(box) if hasattr(box, '__dict__') else '无法获取'}")
|
||||
continue
|
||||
|
||||
processing_time = time.time() - start_time
|
||||
fps = 1.0 / processing_time if processing_time > 0 else 0
|
||||
|
||||
Reference in New Issue
Block a user