facerecognition/register_face.py
2025-04-07 08:08:39 +08:00

119 lines
3.7 KiB
Python

import cv2
import time
import argparse
import os
from face_utils import FaceDetector, FaceRecognizer, draw_face_box
from face_db import FaceDatabase
from voice_prompt import VoicePrompt
def parse_args():
"""解析命令行参数"""
parser = argparse.ArgumentParser(description='人脸注册程序')
parser.add_argument('--name', type=str, help='要注册的人员姓名')
parser.add_argument('--camera', type=int, default=0, help='摄像头索引')
parser.add_argument('--threshold', type=float, default=0.5, help='人脸检测置信度阈值')
return parser.parse_args()
def register_face():
"""人脸注册主函数"""
args = parse_args()
# 初始化组件
voice = VoicePrompt()
detector = FaceDetector(conf_thres=args.threshold)
recognizer = FaceRecognizer(detector=detector)
db = FaceDatabase()
# 打开摄像头
cap = cv2.VideoCapture(args.camera)
if not cap.isOpened():
print("无法打开摄像头")
return
# 获取姓名(如果命令行没有提供,则交互输入)
name = args.name
if name is None:
name = input("请输入姓名: ")
# 创建新的人员记录
person_id = db.add_person(name)
print(f"已创建人员记录: {name} (ID: {person_id})")
voice.speak(f"开始为{name}注册人脸信息,请正视摄像头", block=True)
# 采集计数器和状态
face_count = 0
target_count = 5 # 需要采集的人脸图像数量
last_capture_time = 0
capture_interval = 1.0 # 每次采集间隔秒数
print(f"请看向摄像头,将采集{target_count}张人脸图像...")
while face_count < target_count:
# 读取摄像头帧
ret, frame = cap.read()
if not ret:
print("无法获取摄像头画面")
break
# 镜像翻转以便更直观
frame = cv2.flip(frame, 1)
# 显示帧
display_frame = frame.copy()
cv2.putText(
display_frame,
f"请直视摄像头 ({face_count}/{target_count})",
(10, 30),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
(0, 255, 0),
2
)
# 检测人脸
faces = detector.detect_faces(frame)
# 如果检测到人脸
current_time = time.time()
if faces and (current_time - last_capture_time) >= capture_interval:
# 只处理最大的一个人脸
faces.sort(key=lambda x: (x[2]-x[0])*(x[3]-x[1]), reverse=True)
face_box = faces[0]
# 绘制人脸框
draw_face_box(display_frame, face_box)
# 提取人脸特征
face_feature = recognizer.extract_face_features(frame, face_box[:4])
if face_feature is not None:
# 保存人脸特征到数据库
feature_id = db.add_face_feature(person_id, face_feature)
face_count += 1
last_capture_time = current_time
print(f"已采集第 {face_count}/{target_count} 张人脸")
voice.speak(f"已完成第{face_count}次采集", block=False)
# 显示图像
cv2.imshow("人脸注册", display_frame)
# 按ESC键退出
key = cv2.waitKey(1) & 0xFF
if key == 27:
break
# 释放资源
cap.release()
cv2.destroyAllWindows()
db.close()
if face_count >= target_count:
print(f"成功完成{name}的人脸注册!")
voice.speak(f"已完成{name}的人脸信息注册", block=True)
else:
print("人脸注册未完成")
if __name__ == "__main__":
register_face()