这个基于YOLOv8的行为检测系统是我最近完成的一个很有意思的计算机视觉项目。它能够实时检测三种特定的人类行为:吸烟、喝水和打电话。在实际测试中,系统在1080p视频流上能达到45FPS的处理速度,准确率稳定在92%以上。特别适合需要监控这些行为的场景,比如学校、医院、加油站等公共场所。
为什么选择这三种行为作为检测目标?从实际需求来看:
这个项目的独特之处在于,它不是简单的通用目标检测,而是针对特定行为进行了专门优化。我们收集了3507张专门标注的图像构建数据集,这在同类研究中是比较少见的。
在目标检测领域,我们有几个主流选择:Faster R-CNN、SSD和YOLO系列。最终选择YOLOv8主要基于几个考虑:
整个系统采用模块化设计,主要分为四个部分:
code复制┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 数据输入 │───▶│ YOLOv8 │───▶│ 结果输出 │
│ (图片/视频) │ │ 检测核心 │ │ (显示/保存) │
└─────────────┘ └─────────────┘ └─────────────┘
▲
│
┌───────┴───────┐
│ PyQt5 UI │
│ 控制界面 │
└───────────────┘
这种架构的优点是各模块职责清晰,方便后续扩展新的检测类别或改进算法。
我们采用了多元化的数据收集方式:
特别注意了数据多样性:
使用LabelImg工具进行标注,遵循严格的标注规范:
标注文件采用YOLO格式,每个图像对应一个.txt文件,内容示例:
code复制0 0.45 0.32 0.12 0.15 # smoke
1 0.67 0.71 0.08 0.10 # drink
为了提高模型鲁棒性,我们实施了多种数据增强:
特别有效的一个技巧是模拟遮挡增强:随机在图像上放置灰色方块,模拟实际场景中的遮挡情况。
推荐使用以下环境配置:
创建conda环境的命令:
bash复制conda create -n yolov8 python=3.9
conda activate yolov8
pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
pip install ultralytics
我们的最佳训练配置如下:
python复制model = YOLO('yolov8s.pt') # 使用预训练权重
results = model.train(
data='data.yaml',
epochs=300,
batch=64,
imgsz=640,
device='0', # 使用GPU 0
workers=8,
optimizer='AdamW',
lr0=0.001,
weight_decay=0.0005
)
几个关键参数的选择依据:
训练过程中需要特别关注几个指标:
我们使用TensorBoard进行可视化监控:
bash复制tensorboard --logdir runs/detect
通过实验发现的几个有效优化方法:
python复制model = YOLO('yolov8s.pt')
model.train(..., auto_anchor=True) # 自动计算最佳锚框
yaml复制names: ['smoke', 'drink', 'phone']
weights: [1.0, 0.9, 1.2] # 调整类别权重
检测流程的核心代码:
python复制def detect_image(self, image_path):
"""单张图片检测"""
results = self.model(image_path)[0] # 获取检测结果
# 解析检测框
boxes = results.boxes.xyxy.cpu().numpy() # [x1,y1,x2,y2]
classes = results.boxes.cls.cpu().numpy() # 类别ID
confidences = results.boxes.conf.cpu().numpy() # 置信度
# 可视化结果
annotated_img = results.plot() # 带标注的图像
return {
'image': annotated_img,
'boxes': boxes,
'classes': classes,
'confidences': confidences
}
视频处理的实现要点:
python复制def process_video(self, video_path):
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
# 执行检测
results = self.model(frame)[0]
detected_frame = results.plot()
# 显示结果
cv2.imshow('Detection', detected_frame)
if cv2.waitKey(int(1000/fps)) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
UI界面的主要组件:
python复制class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 主界面设置
self.setWindowTitle("行为检测系统")
self.setGeometry(100, 100, 1200, 800)
# 创建控件
self.image_label = QLabel()
self.result_table = QTableWidget()
self.start_button = QPushButton("开始检测")
# 布局
layout = QHBoxLayout()
left_panel = QVBoxLayout()
left_panel.addWidget(self.image_label)
right_panel = QVBoxLayout()
right_panel.addWidget(self.result_table)
layout.addLayout(left_panel, 70)
layout.addLayout(right_panel, 30)
# 底部按钮
bottom_panel = QHBoxLayout()
bottom_panel.addWidget(self.start_button)
main_layout = QVBoxLayout()
main_layout.addLayout(layout)
main_layout.addLayout(bottom_panel)
container = QWidget()
container.setLayout(main_layout)
self.setCentralWidget(container)
为了提升推理速度,我们实施了以下优化:
python复制model.export(format='onnx', half=True) # 导出FP16精度的ONNX模型
bash复制trtexec --onnx=yolov8s.onnx --saveEngine=yolov8s.trt
python复制from concurrent.futures import ThreadPoolExecutor
def batch_detect(images):
with ThreadPoolExecutor(max_workers=4) as executor:
results = list(executor.map(model, images))
return results
在Jetson Nano上的部署步骤:
bash复制python3 -m onnxruntime.tools.convert_onnx_models_to_ort yolov8s.onnx
python复制import onnxruntime as ort
sess = ort.InferenceSession('yolov8s.ort')
inputs = {'images': input_image}
outputs = sess.run(None, inputs)
在不同硬件平台上的性能对比:
| 设备 | 分辨率 | FPS | 功耗(W) |
|---|---|---|---|
| RTX 3090 | 640x640 | 210 | 350 |
| RTX 3060 | 640x640 | 150 | 170 |
| Jetson Xavier NX | 640x640 | 45 | 15 |
| Jetson Nano | 320x320 | 12 | 5 |
问题1:小目标检测效果差
解决方案:
问题2:遮挡情况下的误检
解决方案:
问题3:光照条件变化的影响
解决方案:
python复制from torchvision.utils import make_grid
import matplotlib.pyplot as plt
features = model.model[0].conv1(x) # 获取第一层卷积特征
grid = make_grid(features[0].unsqueeze(1), nrow=8)
plt.imshow(grid.permute(1,2,0))
plt.show()
python复制def analyze_false_detections(results, gt):
fp = [] # 误检
fn = [] # 漏检
for det in results:
if not any(is_match(det, g) for g in gt):
fp.append(det)
for g in gt:
if not any(is_match(det, g) for det in results):
fn.append(g)
return fp, fn
python复制import time
class Timer:
def __init__(self):
self.times = []
def __enter__(self):
self.start = time.time()
def __exit__(self, *args):
self.times.append(time.time() - self.start)
if len(self.times) > 100:
print(f"Avg time: {sum(self.times)/len(self.times):.3f}s")
self.times = []
引入Transformer结构:
试验YOLOv8与ViT的混合架构,提升长距离依赖建模能力
时序建模:
使用3D CNN或LSTM处理视频序列,提高时序一致性
自监督预训练:
利用大量无标注数据进行预训练,提升模型泛化能力
python复制# 使用大模型指导小模型训练
teacher = YOLO('yolov8l.pt')
student = YOLO('yolov8n.pt')
student.train(..., teacher=teacher)
自动化数据管道:
构建自动化的数据收集-标注-训练-部署流程
模型版本管理:
使用MLflow或Weights & Biases管理不同版本的模型
这个项目从构思到实现大约花费了3个月时间,期间遇到了不少挑战,特别是在处理复杂场景下的行为检测时。通过不断调整模型结构和训练策略,最终达到了不错的检测效果。在实际部署中,我们发现模型的鲁棒性比单纯的精度指标更重要,这也是后续需要继续改进的方向。