限制识别角度,修改引导图片
This commit is contained in:
parent
5b81d6ae95
commit
a6f91fed23
26
README.md
26
README.md
@ -8,6 +8,7 @@
|
||||
|
||||
### 1. 人脸识别
|
||||
- **实时检测**:基于 CompreFace API 进行高精度人脸检测
|
||||
- **正脸检测**:使用姿态检测技术,只识别正面人脸,过滤侧脸、抬头或低头
|
||||
- **身份识别**:自动识别员工和访客,支持相似度阈值配置
|
||||
- **防重复识别**:智能冷却机制,避免短时间内重复识别同一人
|
||||
- **质量评估**:使用 Laplacian 方差评估图像清晰度
|
||||
@ -128,6 +129,15 @@ camera:
|
||||
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: 30.0 # 最大允许的偏航角(度),超过此角度视为侧脸
|
||||
max_pitch: 30.0 # 最大允许的俯仰角(度),超过此角度视为抬头或低头
|
||||
|
||||
# 人脸识别配置
|
||||
face_recognition:
|
||||
recognition_cooldown: 20.0 # 识别冷却时间(秒)
|
||||
@ -290,6 +300,8 @@ kanda-robot-facial-recognition/
|
||||
- `quality_threshold`: 图像质量阈值,建议 10-50
|
||||
- `min_face_size`: 最小人脸尺寸(像素),建议 60-100
|
||||
- `face_present_duration`: 持续出现时长(秒),建议 1.5-3.0
|
||||
- `max_yaw`: 最大允许的偏航角(度),超过此角度视为侧脸,建议 20-40
|
||||
- `max_pitch`: 最大允许的俯仰角(度),超过此角度视为抬头或低头,建议 20-40
|
||||
- `stranger_threshold`: 陌生人阈值,建议 0.95-0.99
|
||||
- `recognition_cooldown`: 识别冷却时间(秒),建议 15-30
|
||||
|
||||
@ -377,7 +389,14 @@ camera:
|
||||
3. 确保光线充足
|
||||
4. 在 CompreFace 中添加更多训练照片
|
||||
|
||||
### Q6: 系统服务无法启动
|
||||
### Q6: 侧脸也被识别了
|
||||
**A:**
|
||||
1. 调整 `max_yaw` 和 `max_pitch` 参数,降低角度阈值
|
||||
2. 默认设置为 ±30 度,可改为 ±20 度提高严格程度
|
||||
3. 检查 CompreFace 服务是否支持 pose 插件
|
||||
4. 查看日志中的角度检查信息进行调试
|
||||
|
||||
### Q7: 系统服务无法启动
|
||||
**A:**
|
||||
1. 检查服务文件路径配置
|
||||
2. 确认 Python 环境和依赖
|
||||
@ -455,6 +474,11 @@ python preview_qrcode.py
|
||||
|
||||
## 更新日志
|
||||
|
||||
### v1.1.0 (2025-12-18)
|
||||
- ✅ 新增正脸检测功能,基于姿态检测技术过滤侧脸
|
||||
- ✅ 添加人脸角度阈值配置(max_yaw, max_pitch)
|
||||
- ✅ 优化人脸识别准确性,适用于门禁场景
|
||||
|
||||
### v1.0.0 (2025-12-03)
|
||||
- ✅ 完整的人脸检测和识别功能
|
||||
- ✅ WebSocket 双向通信
|
||||
|
||||
@ -42,6 +42,8 @@ face_detection:
|
||||
quality_threshold: 10 # 图像质量阈值(Laplacian方差)
|
||||
min_face_size: 80 # 最小人脸尺寸(像素)
|
||||
face_present_duration: 2.0 # 持续出现时长(秒)才触发识别
|
||||
max_yaw: 30.0 # 最大允许的偏航角(度),超过此角度视为侧脸
|
||||
max_pitch: 30.0 # 最大允许的俯仰角(度),超过此角度视为抬头或低头
|
||||
|
||||
# 人脸识别配置
|
||||
face_recognition:
|
||||
|
||||
54
face_rec.py
54
face_rec.py
@ -683,16 +683,16 @@ class FaceRecognitionSystem:
|
||||
try:
|
||||
import screeninfo
|
||||
screen = screeninfo.get_monitors()[0]
|
||||
canvas_width = int(screen.width * 0.8)
|
||||
canvas_height = int(screen.height * 0.8)
|
||||
x_pos = (screen.width - canvas_width) // 2
|
||||
y_pos = (screen.height - canvas_height) // 2
|
||||
canvas_width = int(screen.width)
|
||||
canvas_height = int(screen.height)
|
||||
x_pos = 0
|
||||
y_pos = 0
|
||||
except Exception as e:
|
||||
self.logger.warning(f"无法获取屏幕信息,使用默认尺寸: {e}")
|
||||
canvas_width = max(qr_width * 2, 1400)
|
||||
canvas_height = max(qr_height, 900)
|
||||
x_pos = 100
|
||||
y_pos = 60
|
||||
canvas_width = max(qr_width * 2, 1920)
|
||||
canvas_height = max(qr_height, 1080)
|
||||
x_pos = 0
|
||||
y_pos = 0
|
||||
|
||||
rendered = self._build_qrcode_instruction_canvas(qr_image, (canvas_width, canvas_height))
|
||||
if rendered is None:
|
||||
@ -708,6 +708,9 @@ class FaceRecognitionSystem:
|
||||
cv2.resizeWindow(self.qrcode_window_name, canvas_width, canvas_height)
|
||||
cv2.moveWindow(self.qrcode_window_name, x_pos, y_pos)
|
||||
|
||||
# 设置窗口全屏显示
|
||||
cv2.setWindowProperty(self.qrcode_window_name, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
|
||||
|
||||
cv2.imshow(self.qrcode_window_name, rendered)
|
||||
|
||||
# 设置窗口置顶
|
||||
@ -1242,19 +1245,40 @@ class FaceRecognitionSystem:
|
||||
# 将帧编码为JPEG
|
||||
_, img_encoded = cv2.imencode('.jpg', frame)
|
||||
|
||||
# 调用CompreFace检测API
|
||||
result = self.detection_service.detect(img_encoded.tobytes())
|
||||
# 调用CompreFace检测API,启用pose插件
|
||||
result = self.detection_service.detect(
|
||||
img_encoded.tobytes(),
|
||||
face_plugins="pose"
|
||||
)
|
||||
|
||||
if result and 'result' in result and len(result['result']) > 0:
|
||||
faces = result['result']
|
||||
|
||||
# 过滤掉太小的人脸
|
||||
min_size = self.config['face_detection']['min_face_size']
|
||||
valid_faces = [
|
||||
face for face in faces
|
||||
if face['box']['x_max'] - face['box']['x_min'] >= min_size
|
||||
and face['box']['y_max'] - face['box']['y_min'] >= min_size
|
||||
]
|
||||
valid_faces = []
|
||||
|
||||
# 获取角度阈值
|
||||
max_yaw = self.config['face_detection'].get('max_yaw', 30.0)
|
||||
max_pitch = self.config['face_detection'].get('max_pitch', 30.0)
|
||||
|
||||
for face in faces:
|
||||
# 检查人脸尺寸
|
||||
face_width = face['box']['x_max'] - face['box']['x_min']
|
||||
face_height = face['box']['y_max'] - face['box']['y_min']
|
||||
|
||||
if face_width >= min_size and face_height >= min_size:
|
||||
# 检查人脸角度
|
||||
pose = face.get('pose', {})
|
||||
yaw = pose.get('yaw', 0.0)
|
||||
pitch = pose.get('pitch', 0.0)
|
||||
|
||||
# 判断是否为正脸
|
||||
if abs(yaw) <= max_yaw and abs(pitch) <= max_pitch:
|
||||
valid_faces.append(face)
|
||||
self.logger.debug(f"人脸角度检查通过: yaw={yaw:.1f}°, pitch={pitch:.1f}°")
|
||||
else:
|
||||
self.logger.debug(f"人脸角度超出范围,跳过: yaw={yaw:.1f}°(阈值±{max_yaw}°), pitch={pitch:.1f}°(阈值±{max_pitch}°)")
|
||||
|
||||
if valid_faces:
|
||||
# 返回第一个(最大的)人脸
|
||||
|
||||
@ -326,8 +326,8 @@ def main():
|
||||
cv2.destroyAllWindows()
|
||||
|
||||
# Save for verification
|
||||
cv2.imwrite("preview_qrcode_sota.jpg", canvas)
|
||||
print("Saved preview to preview_qrcode_sota.jpg")
|
||||
cv2.imwrite("preview_qrcode_sota.png", canvas)
|
||||
print("Saved preview to preview_qrcode_sota.png")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
BIN
preview_qrcode_sota.png
Normal file
BIN
preview_qrcode_sota.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 484 KiB |
|
Before Width: | Height: | Size: 264 KiB After Width: | Height: | Size: 264 KiB |
Loading…
Reference in New Issue
Block a user