1. 新增3套PaddlePaddle车辆检测相关模型文件 2. 新增车辆检测服务类与违停检测功能 3. 更新服务依赖并添加环境初始化脚本与文档 4. 修复YOLO检测tensor转换兼容问题 5. 新增PyTorch版本兼容性修复逻辑 6. 扩展模型服务支持Paddle模型加载
模型文件目录
此目录用于存放 AI 检测模型文件。
模型清单
| 模型 | 文件名 | 来源 | 大小 |
|---|---|---|---|
| 火灾检测 | fire_detection/best.pt |
fire_detection/models/best.pt | ~61MB |
| 安全帽检测 | helmet_detection/yolov8n.pt |
yolov/yolov8n.pt | ~6MB |
| 人群检测 | crowd_detection/yolov8l.pt |
behavior_detection/Crowd-Gathering/models/yolov8l.pt | ~100MB |
| 抽烟检测 | smoking_detection/smoking_yolov8n.pt |
behavior_detection/smoker-detection/models/smoking_yolov8n.pt | ~6MB |
| 徘徊检测 | loitering_detection/yolov8n.pt |
behavior_detection/Loitering-Detection/yolov8n.pt | ~6MB |
设置模型
方式1: 符号链接(开发环境)
# 在项目根目录执行
ln -sf /path/to/fire_detection/models/best.pt models/fire_detection/
ln -sf /path/to/yolov/yolov8n.pt models/helmet_detection/
ln -sf /path/to/behavior_detection/Crowd-Gathering/models/yolov8l.pt models/crowd_detection/
ln -sf /path/to/behavior_detection/smoker-detection/models/smoking_yolov8n.pt models/smoking_detection/
ln -sf /path/to/behavior_detection/Loitering-Detection/yolov8n.pt models/loitering_detection/
方式2: 复制文件
cp /path/to/fire_detection/models/best.pt models/fire_detection/
cp /path/to/yolov/yolov8n.pt models/helmet_detection/
cp /path/to/behavior_detection/Crowd-Gathering/models/yolov8l.pt models/crowd_detection/
cp /path/to/behavior_detection/smoker-detection/models/smoking_yolov8n.pt models/smoking_detection/
cp /path/to/behavior_detection/Loitering-Detection/yolov8n.pt models/loitering_detection/
方式3: 使用初始化脚本
bash scripts/setup-models.sh
算法目录规范
当需要在检测模型基础上添加自定义算法逻辑时,请在对应模型目录下创建以下子目录:
algorithms/ - 独立算法模块
用于存放独立的算法实现,如密度估计、流动分析、行为识别等。
crowd_detection/
├── yolov8l.pt
└── algorithms/
├── __init__.py
├── density_estimator.py # 人群密度估计算法
├── flow_analysis.py # 人群流动分析算法
├── anomaly_detector.py # 异常行为检测算法
└── crowd_counting.py # 人群计数算法
示例代码:
# crowd_detection/algorithms/density_estimator.py
import numpy as np
class DensityEstimator:
"""人群密度估计器"""
def __init__(self, grid_size=10):
self.grid_size = grid_size
def estimate(self, detections, image_shape):
"""
根据检测结果估计人群密度
Args:
detections: YOLO检测结果 [(x1,y1,x2,y2,conf,cls), ...]
image_shape: (height, width)
Returns:
density_map: 密度热力图
"""
h, w = image_shape
grid_h, grid_w = h // self.grid_size, w // self.grid_size
density_map = np.zeros((grid_h, grid_w))
for det in detections:
cx, cy = int((det[0] + det[2]) / 2), int((det[1] + det[3]) / 2)
grid_x, grid_y = cx // self.grid_size, cy // self.grid_size
if 0 <= grid_x < grid_w and 0 <= grid_y < grid_h:
density_map[grid_y, grid_x] += 1
return density_map
def is_crowded(self, density_map, threshold=5):
"""判断是否拥挤"""
return np.max(density_map) > threshold
processors/ - 检测结果二次处理
用于对模型检测结果进行后处理,如过滤、分析、告警判断等。
crowd_detection/
├── yolov8l.pt
└── processors/
├── __init__.py
├── post_processor.py # 检测结果后处理
├── crowd_analyzer.py # 人群分析器
└── alert_rules.py # 告警规则判断
示例代码:
# crowd_detection/processors/alert_rules.py
from datetime import datetime, timedelta
class CrowdAlertRules:
"""人群检测告警规则"""
def __init__(self):
self.alert_history = []
self.cooldown_minutes = 5
def check_crowd_gathering(self, person_count, density, duration_seconds):
"""
检查是否触发人群聚集告警
Args:
person_count: 检测到的人数
density: 人群密度值
duration_seconds: 持续时长
Returns:
alert: 告警信息或None
"""
# 规则:人数>20 且 密度>0.5 且 持续>30秒
if person_count > 20 and density > 0.5 and duration_seconds > 30:
if self._can_trigger_alert("crowd_gathering"):
alert = {
"type": "crowd_gathering",
"level": "high" if person_count > 50 else "medium",
"message": f"检测到人群聚集,人数: {person_count}",
"timestamp": datetime.now()
}
self._record_alert("crowd_gathering")
return alert
return None
def check_intrusion(self, detections, restricted_zones):
"""
检查是否触发区域入侵告警
Args:
detections: 检测结果
restricted_zones: 限制区域列表 [(x1,y1,x2,y2), ...]
"""
alerts = []
for det in detections:
person_box = (det[0], det[1], det[2], det[3])
for zone in restricted_zones:
if self._is_intersect(person_box, zone):
alerts.append({
"type": "zone_intrusion",
"level": "high",
"message": "检测到人员进入限制区域"
})
return alerts
def _can_trigger_alert(self, alert_type):
"""检查是否可以通过冷却期触发告警"""
cutoff_time = datetime.now() - timedelta(minutes=self.cooldown_minutes)
recent_alerts = [
a for a in self.alert_history
if a["type"] == alert_type and a["timestamp"] > cutoff_time
]
return len(recent_alerts) == 0
def _record_alert(self, alert_type):
"""记录告警历史"""
self.alert_history.append({
"type": alert_type,
"timestamp": datetime.now()
})
@staticmethod
def _is_intersect(box1, box2):
"""判断两个框是否相交"""
x1 = max(box1[0], box2[0])
y1 = max(box1[1], box2[1])
x2 = min(box1[2], box2[2])
y2 = min(box1[3], box2[3])
return x1 < x2 and y1 < y2
目录选择建议
| 场景 | 推荐目录 | 说明 |
|---|---|---|
| 实现新的检测算法(如密度估计、行为识别) | algorithms/ |
独立的算法逻辑,可复用 |
| 对检测结果进行过滤、分析 | processors/ |
针对业务场景的后处理 |
| 简单的工具函数 | utils/ |
辅助函数,无状态逻辑 |
注意
模型文件较大,未包含在 Git 仓库中。请从原始位置复制或创建符号链接。