以下是一个基于face_recognition
库的人脸管理系统,支持从文件夹加载人脸数据、实时识别并显示姓名,以及动态添加新人脸。系统采用模块化设计,代码结构清晰,易于扩展。
一、系统架构
face_recognition_system/
├── faces/ # 人脸数据库(按姓名命名子文件夹)
│ ├── person1/
│ │ ├── photo1.jpg
│ │ ├── photo2.jpg
│ ├── person2/
│ │ ├── photo1.jpg
├── main.py # 主程序
├── face_manager.py # 人脸管理模块
└── utils.py # 工具函数
二、核心代码实现
1. 人脸管理模块(face_manager.py)
import os
import pickle
import face_recognition
import cv2
from typing import List, Dict, Tupleclass FaceManager:def __init__(self, data_dir="faces", encodings_file="face_encodings.pkl"):"""初始化人脸管理器"""self.data_dir = data_dir # 人脸数据库目录self.encodings_file = encodings_file # 编码数据缓存文件self.known_face_encodings = [] # 已知人脸编码self.known_face_names = [] # 对应的姓名self.load_known_faces() # 加载已知人脸数据def load_known_faces(self):"""从文件或目录加载已知人脸数据"""# 优先从缓存文件加载if os.path.exists(self.encodings_file):try:with open(self.encodings_file, "rb") as f:data = pickle.load(f)self.known_face_encodings = data["encodings"]self.known_face_names = data["names"]print(f"从缓存加载了 {len(self.known_face_names)} 个人脸")returnexcept Exception as e:print(f"加载缓存失败: {e},将从文件重新加载")# 从目录加载并生成缓存self._load_faces_from_directory()self._save_face_encodings()def _load_faces_from_directory(self):"""从目录加载人脸数据"""print(f"正在从 {self.data_dir} 加载人脸数据...")if not os.path.exists(self.data_dir):os.makedirs(self.data_dir)returnfor person_name in os.listdir(self.data_dir):person_dir = os.path.join(self.data_dir, person_name)if not os.path.isdir(person_dir):continue# 遍历每个人的照片for filename in os.listdir(person_dir):image_path = os.path.join(person_dir, filename)if not filename.lower().endswith(('.png', '.jpg', '.jpeg')):continuetry:# 加载图像并提取人脸编码image = face_recognition.load_image_file(image_path)face_encodings = face_recognition.face_encodings(image)if len(face_encodings) == 0:print(f"警告: 在 {image_path} 中未检测到人脸")continue# 通常一张照片只有一个人脸face_encoding = face_encodings[0]self.known_face_encodings.append(face_encoding)self.known_face_names.append(person_name)print(f"已加载 {person_name} 的人脸: {filename}")except Exception as e:print(f"处理 {image_path} 时出错: {e}")print(f"共加载了 {len(self.known_face_names)} 个人脸")def _save_face_encodings(sel