1. 项目背景与核心思路
去年在开发一个紧急项目时,我发现自己经常写着代码就忍不住刷社交媒体,效率直线下降。为了解决这个"手贱"问题,我决定用技术手段对付自己——开发一个AI监工系统,实时监控我的工作状态。这个项目结合了计算机视觉和行为分析,当检测到我开小差时就会触发警报,实测效果相当硬核。
核心原理是通过摄像头捕捉我的面部和屏幕内容,用YOLO算法识别是否处于工作状态,再结合OpenCV分析视线方向和面部表情。系统会记录有效工作时间,并在检测到分心行为时通过语音提醒。整个项目用Python实现,代码量约800行,包含了完整的训练数据和模型部署方案。
2. 技术架构与工具选型
2.1 计算机视觉方案对比
最初考虑过以下三种方案:
- 纯OpenCV的Haar级联检测:实现简单但准确率低
- TensorFlow Lite的预训练模型:平衡精度和性能
- YOLOv5自定义训练:精度最高但需要标注数据
最终选择YOLOv5s(小型版本)因为:
- 在RTX 3060上能达到45FPS
- 自定义数据集训练后mAP@0.5达到92%
- 支持同时检测人脸、眼睛、手机等关键对象
2.2 核心组件清单
requirements.txt关键依赖: torch==1.12.1 torchvision==0.13.1 opencv-python==4.6.0.66 pyttsx3==2.90 # 语音提醒 numpy==1.23.3特别说明几个关键版本:
- OpenCV 4.6+ 才能正常使用YOLO的DNN模块
- PyTorch 1.12对CUDA 11.6支持最稳定
- 语音引擎需要额外安装libespeak1(Linux)或pywin32(Windows)
3. 实现细节与核心代码
3.1 行为检测算法设计
定义三种分心状态:
- 视线离开屏幕超过5秒
- 检测到手机出现在画面中
- 连续打哈欠超过3次
核心检测逻辑:
def check_distraction(eyes_status, phone_detected, yawn_count): if time.time() - eyes_status.last_seen > 5: return "EYES_AWAY" if phone_detected.confidence > 0.7: return "PHONE_USAGE" if yawn_count >= 3: return "TIRED" return "WORKING"3.2 YOLO自定义训练要点
数据收集:
- 录制自己编程时的200段视频(约30小时)
- 使用LabelImg标注关键对象:face, eyes, phone, cup
- 数据增强:添加随机旋转、亮度变化
训练参数:
# yolov5s.yaml lr0: 0.01 lrf: 0.1 epochs: 100 batch_size: 16 img_size: [640, 640]- 关键技巧:
- 冻结前10层只训练检测头
- 使用--evolve参数自动优化超参数
- 添加Focal Loss解决类别不平衡
4. 系统集成与优化
4.1 多线程处理架构
class MonitorSystem: def __init__(self): self.cap = cv2.VideoCapture(0) self.detector = YOLODetector() self.audio = AudioAlert() def run(self): while True: ret, frame = self.cap.read() detections = self.detector.detect(frame) # 主线程 status = analyze_behavior(detections) # 子线程 if status != "WORKING": self.audio.play_alert() # 独立进程4.2 性能优化技巧
- 图像处理:
- 将BGR转RGB放在模型推理后
- 使用cv2.UMat减少内存拷贝
- 模型推理:
- 开启TensorRT加速
- 使用半精度(FP16)推理
- 系统级:
- 设置CUDA流优先级
- 禁用Windows游戏模式
实测优化前后对比:
| 项目 | 优化前 | 优化后 |
|---|---|---|
| CPU占用 | 85% | 32% |
| 内存使用 | 1.8GB | 900MB |
| 延迟 | 120ms | 45ms |
5. 实际应用中的问题解决
5.1 常见故障排查
摄像头无法打开:
# Linux检查设备权限 ls -l /dev/video* sudo chmod 666 /dev/video0YOLO检测框闪烁:
- 增加NMS阈值从0.45到0.6
- 添加卡尔曼滤波跟踪
误报问题:
- 建立白名单(允许喝水、扶眼镜等动作)
- 添加状态持续时间阈值
5.2 效果调优记录
通过两周的实际使用,调整了这些参数:
- 视线离开的容忍时间从3秒→5秒
- 手机检测置信度从0.5→0.7
- 每小时允许5分钟"合法摸鱼"
- 添加了疲劳度指数计算:
fatigue = 0.3*yawn + 0.7*blink_rate
6. 项目扩展方向
- 数据看板功能:
- 使用Matplotlib生成日报
- 统计每日专注时长曲线
- 智能打断策略:
- 根据任务紧急程度调整提醒强度
- 重要阶段启用严格模式
- 多模态检测:
- 结合键盘鼠标活动分析
- 集成屏幕内容识别
这个项目最让我意外的收获是:当你知道有双"眼睛"在盯着时,真的会不自觉地保持专注。代码已放在GitHub上,包含完整训练数据和docker部署方案。有个小技巧分享:在系统设置里留个"紧急解除"快捷键,否则接电话时会被持续警告——别问我怎么知道的。