疲劳检测方案
系统集成基于 WebAssembly 的视觉疲劳检测,在学习过程中实时监测用户疲劳状态并自动调整学习强度。
架构总览
┌─────────────────────────────────────────────────────────────────┐
│ 主线程 (SolidJS) │
│ ┌──────────┐ ┌──────────────┐ ┌───────────────────────────┐ │
│ │摄像头管理 │ │fatigueStore │ │ UI 组件 │ │
│ │Camera │→ │ createRoot │→ │ FatigueIndicator │ │
│ │Manager │ │ 单例 store │ │ FatigueWarningModal │ │
│ └─────┬─────┘ └──────▲───────┘ │ CameraPermissionDialog │ │
│ │ │ └───────────────────────────┘ │
│ │ ImageBitmap │ postMessage(结果) │
│ ▼ │ │
│ ┌─────────────────────┴────────────────────────────┐ │
│ │ Web Worker │ │
│ │ ┌─────────────────┐ ┌────────────────────────┐ │ │
│ │ │ MediaPipe │ │ Rust WASM 算法模块 │ │ │
│ │ │ FaceLandmarker │→ │ EAR → PERCLOS → 眨眼 │ │ │
│ │ │ (478 关键点) │ │ MAR → 哈欠检测 │ │ │
│ │ │ (Blendshapes) │ │ 头部姿态 → 综合评分 │ │ │
│ │ └─────────────────┘ └────────────────────────┘ │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘核心设计原则
- MediaPipe 做面部关键点检测(利用 WebGL 加速),Rust WASM 做纯数值疲劳算法
- 所有推理和计算在 Web Worker 中运行,不阻塞主线程
- 视频数据不离开浏览器,仅上报疲劳数值(隐私优先)
- 用户主动开启,随时可关闭
算法模块
| 模块 | 输入 | 输出 | 算法 |
|---|---|---|---|
ear.rs | 眼部关键点坐标 | EAR 值 + 置信度 | 6点/16点 EAR 公式 |
perclos.rs | EAR 值序列 | PERCLOS 百分比 | 60秒滑动窗口 |
blink.rs | EAR 值 + 时间戳 | 眨眼事件 + 频率 | 四状态机 |
yawn.rs | 嘴部关键点坐标 | 哈欠事件 + 频率 | MAR 阈值检测 |
head_pose.rs | 面部变换矩阵 | pitch/yaw/roll | 欧拉角提取 |
fatigue.rs | 以上所有指标 | 0-100 综合疲劳分 | 五维加权融合 |
疲劳等级
| 等级 | 分数范围 | 颜色 | 行为 |
|---|---|---|---|
| 清醒 (Alert) | 0-25 | 绿色 | 正常学习 |
| 轻度疲劳 (Mild) | 25-50 | 黄色 | Toast 提示"适当休息" |
| 中度疲劳 (Moderate) | 50-75 | 橙色 | 警告提示 + 指示器变色 |
| 严重疲劳 (Severe) | 75-100 | 红色 | Modal 弹窗建议停止学习 |
隐私保护
- 用户主动授权:点击按钮 → 显示说明弹窗 → 确认后请求摄像头
- 本地处理:所有视频帧在浏览器 Worker 中处理,绝不上传服务器
- 不存储视频:处理完立即丢弃帧数据,仅保留数值指标
- 可见状态:摄像头激活时显示绿色圆点指示器
- 一键关闭:随时停止检测并释放摄像头