# 康达机器人人脸识别系统 ## 项目简介 这是一个基于 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**