Face_reg_app/FaceFeatureExtractorAPI/face_recognition_example.py

194 lines
5.5 KiB
Python
Raw Normal View History

2025-12-17 13:13:26 +08:00
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
人脸识别示例特征提取 + 相似度比对
"""
import cv2
import numpy as np
import sys
import os
# 添加父目录到路径
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from face_feature_extractor import FaceFeatureExtractor
class SimpleFaceRecognizer:
"""简单的人脸识别器"""
def __init__(self, threshold=0.7):
"""
初始化识别器
Args:
threshold: 相似度阈值大于此值认为是同一人
"""
self.extractor = FaceFeatureExtractor()
self.threshold = threshold
self.database = {} # 存储已注册的人脸特征
def register(self, name, image):
"""
注册人脸
Args:
name: 姓名
image: 人脸图像
Returns:
bool: 是否注册成功
"""
feature = self.extractor.extract_single_feature(image)
if feature is not None:
self.database[name] = feature
print(f"{name} 注册成功")
return True
else:
print(f"{name} 注册失败(质量检查未通过)")
return False
def recognize(self, image):
"""
识别人脸
Args:
image: 待识别的人脸图像
Returns:
tuple: (姓名, 相似度) (None, 0.0)
"""
if not self.database:
print("✗ 数据库为空,请先注册人脸")
return None, 0.0
# 提取待识别人脸特征
unknown_feature = self.extractor.extract_single_feature(image)
if unknown_feature is None:
print("✗ 未检测到人脸或质量不合格")
return None, 0.0
# 计算与数据库中所有人脸的相似度
best_match = None
best_similarity = 0.0
for name, known_feature in self.database.items():
# 计算余弦相似度(特征已归一化,所以直接点乘)
similarity = np.dot(unknown_feature, known_feature)
if similarity > best_similarity:
best_similarity = similarity
best_match = name
# 判断是否超过阈值
if best_similarity >= self.threshold:
return best_match, best_similarity
else:
return None, best_similarity
def get_database_info(self):
"""获取数据库信息"""
return {
'total_persons': len(self.database),
'persons': list(self.database.keys())
}
def main():
"""主函数"""
print("=" * 60)
print("人脸识别演示")
print("=" * 60)
# 创建识别器
recognizer = SimpleFaceRecognizer(threshold=0.7)
# 示例1: 注册人脸
print("\n步骤1: 注册人脸到数据库")
print("-" * 60)
# 这里需要替换为实际的图像路径
registration_data = [
("袁中群", "1.jpg"),
("袁慧", "yh.jpg"),
("曾其乐", "zql.jpg"),
]
for name, image_path in registration_data:
if os.path.exists(image_path):
image = cv2.imread(image_path)
if image is not None:
recognizer.register(name, image)
else:
print(f"⚠ 图像文件不存在: {image_path}")
# 显示数据库信息
db_info = recognizer.get_database_info()
print(f"\n数据库状态:")
print(f" 已注册人数: {db_info['total_persons']}")
print(f" 人员列表: {', '.join(db_info['persons'])}")
# 示例2: 人脸识别
print("\n步骤2: 识别人脸")
print("-" * 60)
test_images = [
"2.jpg",
# "test_person2.jpg",
# "unknown_person.jpg",
]
for test_image_path in test_images:
if not os.path.exists(test_image_path):
print(f"⚠ 测试图像不存在: {test_image_path}")
continue
test_image = cv2.imread(test_image_path)
if test_image is None:
print(f"✗ 无法读取图像: {test_image_path}")
continue
print(f"\n识别图像: {test_image_path}")
name, similarity = recognizer.recognize(test_image)
if name:
print(f"✓ 识别结果: {name} (相似度: {similarity:.4f})")
else:
print(f"✗ 未识别到已注册人员 (最高相似度: {similarity:.4f})")
# 示例3: 批量识别
print("\n步骤3: 批量处理")
print("-" * 60)
batch_dir = "./test_faces/"
if os.path.exists(batch_dir):
results = []
for filename in os.listdir(batch_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
image_path = os.path.join(batch_dir, filename)
image = cv2.imread(image_path)
if image is not None:
name, similarity = recognizer.recognize(image)
results.append({
'filename': filename,
'name': name,
'similarity': similarity
})
# 输出批量结果
print(f"批量处理完成,共处理 {len(results)} 张图像")
for result in results:
status = "" if result['name'] else ""
name = result['name'] if result['name'] else "未知"
print(f"{status} {result['filename']}: {name} ({result['similarity']:.4f})")
else:
print(f"⚠ 批量处理目录不存在: {batch_dir}")
if __name__ == "__main__":
main()