共计 2362 个字符,预计需要花费 6 分钟才能阅读完成。
人群密度检测的商业价值与技术挑战
人群密度检测在公共安全和商业分析中有着广泛的应用场景。比如在商场、车站等公共场所,实时监测人群密度可以帮助管理人员及时疏导人流,预防踩踏事故的发生。在零售行业,客流分析可以优化店铺布局和营销策略。

但这项技术也面临诸多挑战:
- 遮挡问题:密集人群中个体相互遮挡严重
- 尺度变化:近处和远处行人尺寸差异大
- 实时性要求:公共场所需要快速响应
- 光照变化:不同时段的光照条件差异
为什么选择 YOLOv5?
在目标检测领域,主要有三类算法:
- 两阶段检测器(如 Faster R-CNN):精度高但速度慢
- 单阶段检测器(如 SSD):速度较快但小目标检测效果一般
- YOLO 系列:在速度和精度间取得良好平衡
YOLOv5 相比前代的主要优势:
- 更轻量的网络结构
- 自适应 anchor 计算
- 内置数据增强
- 完善的训练工具链
数据集准备与处理
数据格式转换
我们的 4574 张数据集原始格式是 COCO,需要转换为 YOLO 格式。转换的关键点是坐标归一化:
# COCO 转 YOLO 格式示例代码
import json
import os
with open('annotations.json') as f:
coco = json.load(f)
for img in coco['images']:
img_id = img['id']
img_w = img['width']
img_h = img['height']
# 找到该图片对应的标注
anns = [a for a in coco['annotations'] if a['image_id'] == img_id]
# 写入 YOLO 格式 txt 文件
with open(f'labels/{img_id}.txt', 'w') as out_f:
for ann in anns:
# COCO 是[x,y,width,height]
x, y, w, h = ann['bbox']
# 转换为 YOLO 格式 [center_x, center_y, width, height] 并归一化
x_center = (x + w/2) / img_w
y_center = (y + h/2) / img_h
w_norm = w / img_w
h_norm = h / img_h
# 类别 ID 从 0 开始
class_id = ann['category_id'] - 1
out_f.write(f'{class_id} {x_center} {y_center} {w_norm} {h_norm}\n')
数据增强策略
YOLOv5 内置了多种数据增强方法:
- Mosaic:四张图片拼接增强小目标检测
- MixUp:图像混合增加样本多样性
- HSV 调整:随机改变色调、饱和度和明度
在配置文件中可以这样开启:
# data/hyp.scratch.yaml
hsv_h: 0.015 # 色调增强系数
hsv_s: 0.7 # 饱和度增强系数
hsv_v: 0.4 # 明度增强系数
mosaic: 1.0 # 开启 Mosaic 的概率
mixup: 0.15 # 开启 MixUp 的概率
模型训练
关键配置参数
# 模型配置文件 yolov5s.yaml
nc: 1 # 类别数(人群检测只有 "person" 一类)
# 超参数配置 hyp.scratch.yaml
lr0: 0.01 # 初始学习率
lrf: 0.2 # 最终学习率 = lr0 * lrf
momentum: 0.937 # SGD 动量
weight_decay: 0.0005 # 权重衰减
# Anchor 配置(使用自适应的 autoanchor)
anchors: 3 # 每个输出层的 anchor 数量
类别不平衡处理
人群数据集中可能出现背景过多的问题,可以通过以下方法缓解:
- 调整损失函数权重
- 使用 Focal Loss
- 在线难例挖掘
在 YOLOv5 中可以通过设置类别权重:
# 在 train.py 中添加
model.class_weights = torch.tensor([1.5]) # 人群类别权重设为 1.5
模型优化与部署
TensorRT 加速
# 转换模型到 TensorRT 格式
python export.py --weights yolov5s.pt --include engine --device 0
# 使用 TensorRT 推理
import tensorrt as trt
# 加载引擎
with open('yolov5s.engine', 'rb') as f:
runtime = trt.Runtime(trt.Logger(trt.Logger.WARNING))
engine = runtime.deserialize_cuda_engine(f.read())
针对遮挡的改进
可以尝试以下方法提升遮挡情况下的检测效果:
- 添加注意力机制(如 CBAM)
- 使用 Repulsion Loss
- 增加遮挡样本的数据增强
常见问题与解决方案
标注错误的影响
我们遇到过标注框过大导致模型学习到过多背景特征的案例。解决方法:
- 使用标注清洗工具修正
- 训练时添加标注质量检测
显存不足处理
当遇到 ”CUDA out of memory” 错误时:
- 减小 batch size
- 使用梯度累积
- 尝试更小的模型(yolov5n)
# 梯度累积示例
for i, (images, targets) in enumerate(train_loader):
# 前向传播
loss = model(images, targets)
# 反向传播
loss.backward()
# 每 4 个 batch 更新一次参数
if i % 4 == 0:
optimizer.step()
optimizer.zero_grad()
延伸思考
模型轻量化
- 知识蒸馏
- 通道剪枝
- 量化训练
视频流处理
- 动态帧采样:根据运动检测调整帧率
- 背景差分法减少冗余计算
- 多帧信息融合提升准确性
总结
通过本教程,我们从数据准备到模型优化完整实现了人群密度检测系统。YOLOv5 凭借其出色的性能平衡和易用性,非常适合这类实时检测任务。在实际部署中,还需要根据具体场景持续优化,比如增加 reid 模块进行跨摄像头跟踪,或者集成到现有安防系统中。希望这篇教程能帮助初学者快速入门目标检测领域。
正文完
