1. 项目概述与准备工作
在嵌入式设备上实现实时目标检测一直是个有趣的挑战。最近我在树莓派4B(4GB内存版)上成功部署了YOLOv5s模型,整个过程踩了不少坑,也积累了一些优化经验。相比在PC端运行,树莓派的ARM架构和有限计算资源带来了独特的部署难题。
1.1 为什么选择YOLOv5s?
YOLOv5系列有多个尺寸的模型(n/s/m/l/x),经过实测发现:
- YOLOv5n(nano版)虽然体积最小(仅1.9MB),但检测精度较低
- YOLOv5s(small版)在树莓派4B上能达到3-5FPS,是精度和速度的最佳平衡点
- 更大的模型(m/l/x)在树莓派上基本无法实时运行
提示:如果使用树莓派5,可以尝试YOLOv5m模型,得益于更强的处理器性能
1.2 硬件准备清单
-
核心设备:
- 树莓派4B(4GB内存版最佳)
- 16GB以上TF卡(建议使用A1/UHS-I以上规格)
- 5V3A电源(性能模式需要充足供电)
-
视觉组件:
- 官方CSI摄像头模块(推荐IMX219)
- 或USB摄像头(建议选择免驱UVC协议设备)
-
散热方案:
- 金属散热片(必备)
- 小型风扇(长时间运行建议加装)
1.3 软件环境规划
我选择的软件组合经过多次验证:
- 操作系统:Raspberry Pi OS Lite(32位)
- Python环境:3.7.3(系统自带)
- 深度学习框架:
- PyTorch 1.8.1(官方预编译版)
- TorchVision 0.9.1
- 关键依赖:
- OpenCV 4.4.0(带GTK支持)
- NumPy 1.21.4(ARM优化版)
2. 系统环境配置详解
2.1 基础系统设置
首先执行系统更新:
bash复制sudo apt update && sudo apt full-upgrade -y
sudo reboot
配置交换空间(避免内存不足):
bash复制sudo nano /etc/dphys-swapfile
# 修改为:CONF_SWAPSIZE=2048
sudo /etc/init.d/dphys-swapfile restart
警告:交换空间会加速TF卡损耗,长期使用建议改用ZRAM方案
2.2 PyTorch环境搭建
安装ARM兼容的PyTorch:
bash复制wget https://github.com/KumaTea/pytorch-aarch64/releases/download/v1.8.1/torch-1.8.1-cp37-cp37m-linux_armv7l.whl
pip install torch-1.8.1-cp37-cp37m-linux_armv7l.whl
pip install torchvision==0.9.1
验证安装:
python复制import torch
print(torch.__version__) # 应输出1.8.1
print(torch.backends.quantized.supported_engines) # 检查量化支持
2.3 OpenCV优化安装
使用预编译版提高性能:
bash复制sudo apt install libopencv-dev python3-opencv
pip install opencv-python==4.4.0.44
验证硬件加速:
python复制import cv2
print(cv2.getBuildInformation()) # 查看FFMPEG/V4L2支持
3. YOLOv5部署实战
3.1 模型获取与准备
克隆官方仓库(指定v6.2版本):
bash复制git clone --branch v6.2 https://github.com/ultralytics/yolov5
cd yolov5
pip install -r requirements.txt
下载预训练模型:
bash复制wget https://github.com/ultralytics/yolov5/releases/download/v6.2/yolov5s.pt
3.2 基础检测测试
首次运行测试:
bash复制python detect.py --source data/images/bus.jpg --imgsz 320 --weights yolov5s.pt
关键参数说明:
--imgsz 320:输入图像缩放尺寸(越小越快)--conf-thres 0.5:置信度阈值(平衡误检/漏检)--device cpu:强制使用CPU(默认会自动检测)
3.3 摄像头实时检测
使用CSI摄像头:
bash复制python detect.py --source 0 --imgsz 320 --weights yolov5s.pt
USB摄像头需指定:
bash复制v4l2-ctl --list-devices # 查看设备号
python detect.py --source /dev/video0 --imgsz 256
4. 性能优化技巧
4.1 模型量化加速
将FP32模型转为INT8:
python复制# 在export.py中添加
model.model.fuse().eval()
model = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8)
torch.save(model.state_dict(), 'yolov5s_quant.pt')
实测效果:
- 模型大小:从14.4MB → 3.6MB
- 推理速度:提升约40%
4.2 树莓派超频设置
编辑config.txt:
bash复制sudo nano /boot/config.txt
# 添加:
over_voltage=2
arm_freq=1750
gpu_freq=600
监控温度:
bash复制watch -n 1 vcgencmd measure_temp
注意:超频可能导致不稳定,建议逐步测试
4.3 OpenCV后端优化
改用V4L2采集:
python复制cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M','J','P','G'))
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 320)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 240)
5. 常见问题与解决方案
5.1 内存不足错误
症状:
code复制Killed process python3 (out of memory)
解决方案:
- 增加交换空间(前文已述)
- 使用
--img-size 160更小分辨率 - 关闭桌面环境:
bash复制sudo systemctl set-default multi-user.target sudo reboot
5.2 摄像头无法识别
检查步骤:
- 确认摄像头已启用:
bash复制sudo raspi-config # Interface Options → Camera - 测试原始采集:
bash复制
libcamera-hello --list-cameras
5.3 低帧率优化
提升技巧:
- 使用
--half半精度推理 - 减少检测类别:
bash复制python detect.py --classes 0 2 3 # 只检测人、车等 - 设置检测间隔:
python复制# detect.py中修改 if frame_count % 5 == 0: # 每5帧检测一次 results = model(frame)
6. 进阶应用方向
6.1 Flask视频流服务
创建简易API:
python复制from flask import Flask, Response
app = Flask(__name__)
@app.route('/stream')
def video_feed():
return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')
def gen_frames():
cap = cv2.VideoCapture(0)
while True:
ret, frame = cap.read()
if not ret: break
# 添加YOLO检测逻辑
_, buffer = cv2.imencode('.jpg', frame)
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')
6.2 模型剪枝定制
使用TorchPruner精简模型:
python复制from torchpruner import SparsePruner
pruner = SparsePruner(model, sparsity=0.3)
pruner.step()
pruned_model = pruner.prune()
torch.save(pruned_model, 'yolov5s_pruned.pt')
经过半年多的实际部署,这套方案在智能门禁、工业质检等场景都表现稳定。最关键的经验是:在嵌入式设备上跑AI,一定要在精度和速度之间找到适合自己场景的平衡点。后续我还会尝试用TensorRT进一步优化推理管线,到时候再和大家分享新的发现。