robot_face_rec/README.md

505 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 康达机器人人脸识别系统
## 项目简介
这是一个基于 CompreFace 的智能人脸识别系统,为康达新材的接待机器人提供实时人脸检测、识别和访客管理功能。系统通过 WebSocket 与机器人主控程序通信,支持视频展示、二维码引导和流媒体推送等多种功能。
## 核心功能
### 1. 人脸识别
- **实时检测**:基于 CompreFace API 进行高精度人脸检测
- **正脸检测**使用姿态检测技术获取人脸的yaw偏航角、pitch俯仰角、roll翻滚角数据只识别正面人脸有效过滤侧脸、抬头或低头
- **角度过滤**通过REST API直接调用CompreFace的pose插件设置±20°的角度阈值确保只检测正脸
- **身份识别**:自动识别员工和访客,支持相似度阈值配置
- **防重复识别**:智能冷却机制,避免短时间内重复识别同一人
- **质量评估**:使用 Laplacian 方差评估图像清晰度
### 2. 访客引导
- **二维码展示**:陌生访客自动弹出访客预约流程二维码
- **SOTA 设计**:采用现代化 UI 设计,左侧二维码 + 右侧步骤说明
- **自动关闭**:可配置显示时长(默认 10 秒)
### 3. 展厅讲解
- **视频播放**:当机器人角色为"展厅讲解员"时自动播放展厅视频
- **状态叠加**:在视频上实时显示机器人状态(思考、倾听、讲话)
- **循环播放**:支持视频循环播放配置
### 4. WebSocket 通信
- **双向通信**:与机器人主控程序实时交互
- **状态同步**:获取机器人说话、思考、倾听状态
- **自动重连**:连接断开时自动重连,保证系统稳定性
### 5. 流媒体推送
- **RTMP/RTSP 推流**:支持将识别画面推送到流媒体服务器
- **异步推流**:独立线程处理推流,不影响主流程性能
- **自动重试**:推流失败自动重试,带冷却机制
### 6. 摄像头管理
- **自动重连**:摄像头断开时自动尝试重新连接
- **故障恢复**:连续失败达到阈值时触发完整重新初始化
## 技术架构
### 技术栈
- **Python 3.x**
- **OpenCV**:图像处理和摄像头控制
- **CompreFace**:人脸检测和识别服务
- **WebSocket**:实时通信
- **Pillow (PIL)**:中文字体渲染和图像合成
- **FFmpeg**:流媒体推送
- **asyncio**:异步事件循环
### 系统架构
```
┌─────────────────────────────────────────────────────────┐
│ 人脸识别系统主程序 │
│ (face_rec.py) │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 摄像头模块 │ │ 识别模块 │ │ 显示模块 │ │
│ │ │ │ │ │ │ │
│ │ - 视频采集 │ │ - 人脸检测 │ │ - 信息叠加 │ │
│ │ - 自动重连 │ │ - 身份识别 │ │ - 二维码显示 │ │
│ │ - 质量评估 │ │ - 角色判定 │ │ - 视频播放 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ WebSocket │ │ 推流模块 │ │ 日志模块 │ │
│ │ │ │ │ │ │ │
│ │ - 状态同步 │ │ - FFmpeg推流 │ │ - 日志记录 │ │
│ │ - 消息通信 │ │ - 异步队列 │ │ - 日志轮转 │ │
│ │ - 自动重连 │ │ - 错误恢复 │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────┐ ┌──────────┐
│ CompreFace │ │ 机器人主控│ │ 流媒体 │
│ 服务 │ │ 程序 │ │ 服务器 │
└─────────────┘ └──────────┘ └──────────┘
```
## 安装部署
### 环境要求
- Python 3.7+
- Linux 系统(推荐 Ubuntu 20.04+
- 摄像头设备
- X11 显示服务器
### 依赖安装
```bash
pip install opencv-python
pip install websockets
pip install pyyaml
pip install numpy
pip install Pillow
pip install compreface-sdk
pip install screeninfo
pip install psutil # 可选,用于进程管理
```
### FFmpeg 安装(用于推流)
```bash
sudo apt-get update
sudo apt-get install ffmpeg
```
### 配置文件
编辑 `config.yaml` 配置系统参数:
```yaml
# CompreFace API 配置
compreface:
host: "http://10.0.0.202"
port: "8000"
recognition_api_key: "your_recognition_key"
detection_api_key: "your_detection_key"
# WebSocket 配置
websocket:
url: "ws://127.0.0.1:3344"
status_interval: 0.2
# 摄像头配置
camera:
device_id: 0 # 或使用设备路径
width: 1280
height: 720
fps: 30
# 人脸检测配置
face_detection:
frame_interval: 10 # 检测帧间隔(每N帧检测一次)
quality_threshold: 10 # 图像质量阈值(Laplacian方差)
min_face_size: 80 # 最小人脸尺寸(像素)
face_present_duration: 2.0 # 持续出现时长(秒)才触发识别
max_yaw: 20.0 # 最大允许的偏航角(度),超过此角度视为侧脸
max_pitch: 20.0 # 最大允许的俯仰角(度),超过此角度视为抬头或低头
# 人脸识别配置
face_recognition:
recognition_cooldown: 20.0 # 识别冷却时间(秒)
role_mapping:
stranger_threshold: 0.98 # 陌生人阈值
# 二维码配置
qrcode:
image_path: "preview_qrcode_sota.jpg"
display_duration: 30
# 视频配置
video:
path: "exhibition.mp4"
loop: true
# 推流配置(可选)
stream:
enabled: false # 是否启用推流
rtmp_url: "rtsp://127.0.0.1/live/video"
```
### 运行方式
#### 方式一:直接运行
```bash
python face_rec.py
```
#### 方式二:使用启动脚本
```bash
chmod +x start.sh
./start.sh
```
#### 方式三:系统服务(推荐生产环境)
```bash
# 复制服务文件
sudo cp face_rec.service /etc/systemd/system/
# 重载服务
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start face_rec
# 设置开机自启
sudo systemctl enable face_rec
# 查看服务状态
sudo systemctl status face_rec
# 查看日志
sudo journalctl -u face_rec -f
```
## 核心模块说明
### 1. FaceRecognitionSystem 类
系统主类,包含以下核心方法:
#### 初始化相关
- `__init__()`: 初始化系统,加载配置
- `_init_camera()`: 初始化摄像头
- `_init_compreface()`: 初始化 CompreFace 服务
- `_init_ffmpeg_stream()`: 初始化推流
#### 人脸识别
- `detect_faces()`: 检测人脸
- `recognize_face()`: 识别人脸
- `assess_frame_quality()`: 评估图像质量
- `determine_role()`: 判定人员角色
- `should_recognize()`: 判断是否需要识别
#### 显示相关
- `_show_qrcode()`: 显示二维码
- `_show_video()`: 显示展厅视频
- `draw_info_on_frame()`: 在画面上绘制信息
- `_draw_robot_status_on_video()`: 在视频上绘制机器人状态
- `_build_qrcode_instruction_canvas()`: 构建二维码指引画布
#### WebSocket 通信
- `connect_websocket()`: 连接 WebSocket
- `send_websocket_message()`: 发送消息
- `handle_websocket_messages()`: 处理接收消息
- `query_robot_status()`: 查询机器人状态
#### 推流相关
- `_start_stream_thread()`: 启动推流线程
- `_stream_worker()`: 推流工作线程
- `_push_frame_to_stream()`: 推送帧到流媒体
- `_force_cleanup_ffmpeg()`: 清理 FFmpeg 资源
#### 主流程
- `process_video_stream()`: 处理视频流主循环
- `run()`: 系统运行入口
### 2. 工作流程
```
启动系统
初始化配置、日志、CompreFace、摄像头
连接 WebSocket后台任务
启动推流(如果启用)
┌─────────────────────────────────────┐
│ 主循环(异步) │
│ │
│ 1. 读取摄像头帧 │
│ 2. 检查机器人角色,控制视频播放 │
│ 3. 更新视频帧(如果正在播放) │
│ 4. 检查二维码超时 │
│ 5. 每 N 帧进行人脸检测 │
│ 6. 检测到人脸 → 持续出现 2 秒 │
│ 7. 触发人脸识别 │
│ 8. 判定角色(员工/访客/陌生人) │
│ 9. 发送识别结果到机器人 │
│ 10. 陌生人 → 显示二维码 │
│ 11. 绘制识别信息到画面 │
│ 12. 推送画面到流媒体(如果启用) │
│ 13. 显示画面 │
│ │
│ 按 'q' 退出 │
└─────────────────────────────────────┘
清理资源(摄像头、推流、窗口)
退出系统
```
## 文件说明
```
kanda-robot-facial-recognition/
├── face_rec.py # 主程序
├── config.yaml # 配置文件
├── start.sh # 启动脚本
├── face_rec.service # systemd 服务文件
├── preview_qrcode_sota.png # 二维码引导图片(新版)
├── qrcode.jpg # 二维码图片(旧版)
├── exhibition.mp4 # 展厅讲解视频
├── preview_qrcode.py # 二维码预览生成工具
├── face_recognition.log # 运行日志
├── 001保存摄像头流.py # 工具:保存摄像头视频流
├── 002查看摄像头id.py # 工具:查看摄像头设备 ID
├── 003查看GUI后端.py # 工具:查看 GUI 后端
└── README.md # 本文档
```
## 配置说明
### 人脸识别参数
- `frame_interval`: 检测帧间隔,建议 5-15
- `quality_threshold`: 图像质量阈值,建议 10-50
- `min_face_size`: 最小人脸尺寸(像素),建议 60-100
- `face_present_duration`: 持续出现时长(秒),建议 1.5-3.0
- `max_yaw`: 最大允许的偏航角(度),超过此角度视为侧脸,推荐 20°
- `max_pitch`: 最大允许的俯仰角(度),超过此角度视为抬头或低头,推荐 20°
- `stranger_threshold`: 陌生人阈值,建议 0.95-0.99
- `recognition_cooldown`: 识别冷却时间(秒),建议 15-30
### 摄像头设备 ID
**方式一:使用数字 ID**
```yaml
camera:
device_id: 0 # 通常是第一个摄像头
```
**方式二:使用设备路径(推荐,更稳定)**
```bash
# 查看可用摄像头
ls /dev/v4l/by-id/
# 使用设备路径
camera:
device_id: "/dev/v4l/by-id/usb-xxx-video-index0"
```
### WebSocket 消息格式
**发送识别结果**
```json
{
"type": "face_recognition",
"message": {
"person_name": "张三",
"person_role": "员工",
"similarity": 0.99,
"timestamp": "2025-12-18 10:30:00"
}
}
```
**接收机器人状态**
```json
{
"type": "status",
"message": {
"is_speaking": false,
"is_thinking": true,
"listening": false,
"role_name": "展厅讲解员"
}
}
```
## 常见问题
### Q1: 摄像头无法打开
**A:**
1. 检查摄像头是否被其他程序占用
2. 确认设备 ID 是否正确:`ls /dev/video*`
3. 检查用户权限:`sudo usermod -a -G video $USER`
4. 重启系统
### Q2: 无法显示中文
**A:**
1. 确认系统已安装中文字体
2. 修改 `config.yaml` 中的 `font_path` 配置
3. 常见字体路径:
- Ubuntu: `/usr/share/fonts/truetype/wqy/wqy-microhei.ttc`
- CentOS: `/usr/share/fonts/wqy-microhei/wqy-microhei.ttc`
### Q3: WebSocket 连接失败
**A:**
1. 确认机器人主控程序已启动
2. 检查 WebSocket URL 配置
3. 查看防火墙设置
4. 系统会自动重连,检查日志确认状态
### Q4: 推流失败
**A:**
1. 确认 FFmpeg 已安装:`ffmpeg -version`
2. 检查流媒体服务器是否运行
3. 验证 RTMP/RTSP URL 格式
4. 查看日志中的 FFmpeg 错误信息
### Q5: 识别准确率低
**A:**
1. 提高 `quality_threshold` 确保图像清晰
2. 调整 `stranger_threshold` 阈值
3. 确保光线充足
4. 在 CompreFace 中添加更多训练照片
### Q6: 侧脸也被识别了
**A:**
1. 调整 `max_yaw``max_pitch` 参数,降低角度阈值
2. 默认设置为 ±30 度,可改为 ±20 度提高严格程度
3. 检查 CompreFace 服务是否支持 pose 插件
4. 查看日志中的角度检查信息进行调试
### Q7: 系统服务无法启动
**A:**
1. 检查服务文件路径配置
2. 确认 Python 环境和依赖
3. 查看日志:`sudo journalctl -u face_rec -n 50`
4. 检查 DISPLAY 和 XAUTHORITY 环境变量
## 性能优化建议
1. **降低检测频率**:增大 `frame_interval`
2. **降低分辨率**:适当降低摄像头分辨率
3. **关闭推流**:生产环境不需要时关闭推流功能
4. **调整日志级别**:生产环境使用 INFO 或 WARNING
5. **使用 GPU**:如有 GPU配置 OpenCV 使用 CUDA 加速
## 维护和监控
### 日志查看
```bash
# 查看应用日志
tail -f face_recognition.log
# 查看系统服务日志
sudo journalctl -u face_rec -f
# 查看启动脚本日志
tail -f /home/unitree/robot_face_rec/logs/face_rec/*.log
```
### 性能监控
```bash
# 查看 CPU 和内存占用
top -p $(pgrep -f face_rec.py)
# 查看 GPU 使用(如果使用 NVIDIA GPU
nvidia-smi
# 查看进程状态
ps aux | grep face_rec
```
### 重启服务
```bash
# 重启服务
sudo systemctl restart face_rec
# 强制停止
sudo systemctl kill face_rec
# 完全重启(包括清理资源)
sudo systemctl stop face_rec
sleep 2
sudo systemctl start face_rec
```
## 开发和调试
### 调试模式
修改 `config.yaml`
```yaml
logging:
level: "DEBUG"
```
### 测试工具
```bash
# 测试摄像头
python 001保存摄像头流.py
# 查看摄像头 ID
python 002查看摄像头id.py
# 预览二维码设计
python preview_qrcode.py
```
## 更新日志
### v1.1.0 (2025-12-18)
- ✅ 新增正脸检测功能基于CompreFace姿态检测技术过滤侧脸
- ✅ 添加人脸角度阈值配置max_yaw: 20°, max_pitch: 20°
- ✅ 使用REST API直接调用CompreFace绕过SDK限制获取pose数据
- ✅ 优化人脸识别准确性,适用于门禁场景,只识别正面人脸
- ✅ 二维码显示时间延长至30秒方便访客操作
- ✅ 二维码指引界面改为全屏显示,提升用户体验
- ✅ 修复PIL兼容性问题解决圆角矩形渲染错误
### v1.0.0 (2025-12-03)
- ✅ 完整的人脸检测和识别功能
- ✅ WebSocket 双向通信
- ✅ 二维码 SOTA 设计展示
- ✅ 展厅讲解视频播放
- ✅ 机器人状态叠加显示
- ✅ FFmpeg 流媒体推送
- ✅ 异步推流队列优化
- ✅ 摄像头自动重连机制
- ✅ 完善的日志系统
## 技术支持
如有问题,请联系开发团队或查看项目文档。
---
**泰奥理 © 2025**