树莓派5打造完全离线疲劳驾驶预警系统:零订阅、零云端,安全驾驶新方案

所需组件
硬件
- 树莓派5 × 1
- 树莓派摄像头模块 V2 × 1
- MicroSD 存储卡 × 1
- 树莓派触摸显示屏 × 1
- 蜂鸣器 × 1
软件与在线服务
- 树莓派 Raspbian 系统
- OpenCV
项目背景与动机
驾驶疲劳的严峻问题
疲劳驾驶是道路交通事故中最致命、却最常被忽视的诱因之一。现有的商用驾驶员监控系统,如奔驰、宝马、特斯拉等高端车型搭载的方案,往往价格高昂,且与特定车型深度绑定。面向车队的独立系统则普遍依赖云端连接和持续付费模式。
DrowSAFE 是一个完全开源的替代方案:它是一套完全自包含的疲劳检测系统,任何人都可以自行搭建,并安装到任意车辆上。
系统运行原理
DrowSAFE 以约每秒 30 帧的速率持续执行检测流水线:

整个流水线在树莓派 5 的四核 Cortex-A76 CPU 上运行,无需 GPU、AI 加速卡,也不需要任何网络连接。
关键疲劳检测算法:眼纵横比(EAR)、嘴纵横比(MAR)与 PERCLOS
系统基于 MediaPipe Face Mesh 每帧检测到的 468 个人脸关键点,计算三项疲劳信号:

- 眼纵横比(EAR):由 Soukupová 与 Čech(2016)提出的指标——利用每只眼睛的 6 个关键点,测量眼睛纵向与横向跨度的比值。眼睛睁开时,EAR 通常处于 0.28–0.35 的范围;眨眼时该值急剧下降;持续偏低的 EAR 表明驾驶员处于疲劳状态。
- EAR = (|p1–p5| + |p2–p4|) / (2 × |p0–p3|)
- 嘴纵横比(MAR):将相同的几何计算方法应用于嘴部区域。当 MAR 超过设定阈值且持续 15 帧以上时,系统判定为一次确认打哈欠。
- PERCLOS(眼睛闭合时间百分比):美国 NHTSA 所采用的金标准疲劳指标。在 60 秒的滑动窗口内,统计眼睛闭合帧占比超过 80% 的时间比例。PERCLOS 值大于 15% 即可可靠地表明警觉性受损。
- 头部姿态:通过 OpenCV 的 solvePnP 函数实时估计,依据 6 个标准 3D 人脸关键点。头部前倾角度超过阈值,即典型的“微睡眠点头”动作,会计入疲劳评分。
综合疲劳评分机制
系统采用加权方式合成 0–100 分的复合疲劳评分:
- PERCLOS : 40%
- 实时 EAR : 25%
- 头部姿态(点头): 20%
- 打哈欠频率(MAR): 15%
警报分级状态机设计
疲劳评分驱动一个带有滞后机制的三级状态机——评分必须远低于对应阈值才会降级警报级别,从而防止帧间噪声导致的频繁跳变。

# 滞后机制防止闪烁——评分必须降至以下值才会降级WARNING_HYSTERESIS = 30 # 低于 30 恢复至 ALERTCRITICAL_HYSTERESIS = 55 # 低于 55 恢复至 WARNING
各警报级别在显示屏上的表现如下:

实时检测效果展示
以下截图直接取自运行中的树莓派 5 系统,使用 Camera Module 3 NoIR,并叠加了 MediaPipe 关键点。
警告状态——评分 43,EAR 0.188,MAR 1.677,头部俯仰角 -27.3°

危险状态——评分 81,EAR 0.029,眼睛完全闭合

两张截图均确认系统在 Pi 5 上稳定运行于 30.0 fps,完整的 MediaPipe 流水线已激活。危险截图中 EAR 值低至 0.029,表明眼睛几乎完全闭合,警报被正确触发。
可视化仪表盘界面
7 寸树莓派触摸显示屏上运行全屏 Pygame 仪表盘,信息一目了然:
- 左侧面板(60%):实时摄像头画面 + MediaPipe 关键点叠加(可通过配置项 SHOW_LANDMARKS 控制)
- 右侧面板(40%):大号、颜色编码的疲劳评分、评分进度条、实时 EAR/MAR/头部俯仰角、警报级别徽标
- 底部横幅:全宽条,显示警报信息——颜色和文字随警报级别动态变化
为何选择边缘 AI 方案
大多数商用驾驶员监控系统要么依赖昂贵的高端车辆,要么需要将视频上传至云端。DrowSAFE 则截然不同:
- 无需网络:任何地方均可使用,包括隧道和农村偏远地区
- 零延迟:无需网络往返,检测指令瞬间完成
- 完全隐私:驾驶员面部数据绝不离开设备本身
- 一次性成本:无订阅费用,无 API 调用费
MediaPipe 的 Face Mesh 模型针对 ARM 架构进行了优化,在 Pi 5 上无需 GPU 或额外 AI 加速器即可稳定维持 30 fps。
硬件搭建步骤
步骤一:烧录操作系统镜像
使用 Raspberry Pi Imager 烧录 Raspberry Pi OS(Legacy,64 位),基于 Debian 12 Bookworm。
注意:截至 2026 年 4 月,默认的 Pi OS 镜像安装的是 Debian 13 Trixie + Python 3.13。MediaPipe 目前尚不支持 Python 3.13。请务必在 Imager 的“Raspberry Pi OS(other)”分类下明确选择 “Raspberry Pi OS(Legacy,64-bit)”。
烧录前,在 Imager 自定义设置界面启用 SSH 并配置好登录凭据。
步骤二:连接显示屏
通过 DSI 排线将 7 寸触摸显示屏连接到 Pi 5。显示屏由 Pi 的 USB-C 接口直接供电。
步骤三:连接摄像头
Pi 5 采用 mini CSI 接口,而 Camera Module 3 自带标准 15 针 FPC 线缆。因此需要使用 Standard-to-Mini 转接线(推荐 300mm 长度)。连接到 Pi 5 的 CAM/DISP 0 端口。
步骤四:连接蜂鸣器
将有源压电蜂鸣器连接到 GPIO 18。
软件环境配置
步骤一:克隆仓库并安装依赖
git clone https://github.com/Bedair/DrowSAFE.git
cd drowsafe
bash scripts/setup_drowsafe.sh
预期验证输出:
✓ OpenCV 4.11.0
✓ MediaPipe 0.10.18
✓ ONNX Runtime 1.24.4
✓ Pygame 2.6.1
✓ NumPy 1.26.4
All packages OK!
步骤二:无摄像头测试(模拟模式)
python src/main.py --simulate
运行完整仪表盘,模拟 90 秒疲劳周期——自动循环经历所有三个警报级别,无需连接摄像头或运行 MediaPipe。
步骤三:启动实时检测
bash scripts/run.sh
脚本将激活虚拟环境,为 SSH 会话设置 DISPLAY=:0,并启动检测流水线。
个人校准指南
每个人的面部特征不同,因此需要使用内置校准工具测量自己的基准 EAR 和 MAR 值:
bash scripts/calibrate.sh
输出示例:
EAR-L EAR-R EAR-AVG MAR PITCH
0.312 0.298 0.305 0.312 1.2° ← 嘴巴闭合,眼睛睁开
0.089 0.076 0.083 0.712 18.4° ← 眼睛闭合,打哈欠
将 EAR_THRESHOLD 设置为睁眼平均 EAR 的约 65%。将 MAR_THRESHOLD 设置在静息 MAR 和打哈欠 MAR 之间。所有阈值均可在 config/config.py 中修改。
参数配置说明
所有参数集中在 config/config.py 中:
CAMERA_FLIP = True # 如果摄像头倒置安装,翻转 180°
# 检测阈值——根据个人面部特征进行校准
EAR_THRESHOLD = 0.22 # 低于此值视为眼睛闭合
MAR_THRESHOLD = 0.75 # 高于此值判定为打哈欠
HEAD_PITCH_THRESHOLD = 20 # 头部前倾角度阈值(度)
# PERCLOS —— 遵循 NHTSA 标准
PERCLOS_WINDOW_SEC = 60
PERCLOS_THRESHOLD = 0.15 # >15% 闭合视为疲劳
# 警报等级
WARNING_SCORE = 40
CRITICAL_SCORE = 70
WARNING_HYSTERESIS = 30
CRITICAL_HYSTERESIS = 55
# GPIO
BUZZER_PIN = 18
获取源代码
DrowSAFE 项目地址:
https://github.com/Bedair/DrowSAFE
直接下载 zip:
https://codeload.github.com/Bedair/DrowSAFE/zip/refs/heads/main