以下是一個基于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