人脸识别

发布时间 2023-06-15 22:34:23作者: 曦西西

1、引入库函数

1 import cv2
2 import os
3 import imghdr
4 import numpy as np
5 import matplotlib.pyplot as plt

2、#定义函数:检测人脸并保存

 1 def detect_faces(image_path, output_dir):
 2     # 读取图像
 3     image = cv2.imread(image_path)
 4     # 将图像转换为灰度图像
 5     grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 6     # 加载人脸检测器(使用Haar级联分类器)
 7     face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
 8     # 检测人脸
 9     faces = face_detector.detectMultiScale(
10         grayscale_image,
11         scaleFactor=1.1,
12         minNeighbors=2,
13         minSize=(20, 20),
14         flags=cv2.CASCADE_SCALE_IMAGE
15     )
16     # 对于每个检测到的人脸
17     for i, (x, y, w, h) in enumerate(faces):
18         # 生成人脸图像的文件名
19         pic_name = f"face_{i}_{os.path.basename(image_path)}"
20         # 提取人脸图像
21         face = cv2.resize(image[y:y+h, x:x+w], (200, 200))
22         # 将人脸图像保存到输出目录
23         cv2.imwrite(os.path.join(output_dir, pic_name), face)

3、定义函数:保存用于训练的人脸图像

 1 def save_faces_for_training(data_dir, output_dir):
 2     # 如果输出目录不存在,则创建它
 3     if not os.path.exists(output_dir):
 4         os.makedirs(output_dir)
 5     # 遍历数据目录中的文件
 6     for file in os.listdir(data_dir):
 7         # 构建文件路径
 8         file_path = os.path.join(data_dir, file)
 9         # 检测并保存人脸图像
10         detect_faces(file_path, output_dir)

 

4、定义函数:生成标签文件

 1 def generate_labels(data_dir):
 2     # 打开标签文件,准备写入标签
 3     with open("label.txt", "w") as label_file:
 4         label = 0
 5         # 遍历数据目录中的子目录
 6         for root, dirs, files in os.walk(data_dir):
 7             for subdir in dirs:
 8                 # 构建子目录路径
 9                 subdir_path = os.path.join(root, subdir)
10                 # 遍历子目录中的文件
11                 for file in os.listdir(subdir_path):
12                     # 构建文件路径
13                     file_path = os.path.join(subdir_path, file)
14                     # 获取文件的图像类型
15                     image_type = imghdr.what(file_path)
16                     # 如果是支持的图像类型(如jpeg、png、jpg),则将文件路径写入标签文件
17                     if image_type in ("jpeg", "png", "jpg"):
18                         label_file.write(f"{file_path}\n")
19                 label += 1

5、定义函数:加载图像和标签

 1 def load_images_and_labels():
 2     images = []
 3     labels = []
 4     # 打开标签文件,读取图像和标签
 5     with open("label.txt") as label_file:
 6         for line in label_file:
 7             # 去除每行的换行符,并获取图像路径
 8             image_path = line.strip()
 9             # 获取标签(从图像路径中提取)
10             label = os.path.basename(os.path.dirname(image_path))
11             # 读取图像并将其转换为灰度图像
12             image = cv2.imread(image_path)
13             # 将图像转换为灰度图像
14             grayscale_image = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
15             # 将灰度图像添加到图像列表中
16             images.append(grayscale_image)
17             # 将标签添加到标签列表中
18             labels.append(label)
19     return images, labels

6、定义函数:训练模型

 1 def train_model(images, labels):
 2     # 获取唯一的标签值
 3     unique_labels = list(set(labels))
 4     # 创建标签到索引的映射
 5     label_map = {label: idx for idx, label in enumerate(unique_labels)}
 6     # 将标签转换为映射后的整数标签
 7     mapped_labels = [label_map[label] for label in labels]
 8 
 9     # 创建人脸识别模型(使用Eigenfaces算法)
10     model = cv2.face.EigenFaceRecognizer_create()
11     # 将标签转换为NumPy数组
12     labels_array = np.array(mapped_labels, dtype=np.int32)
13     # 训练模型
14     model.train(images, labels_array)
15     # 保存训练后的模型
16     model.save("face_trained.yml")

7、定义函数:识别人脸

 1 def recognize_face(image_path, model):
 2     # 读取图像
 3     image = cv2.imread(image_path)
 4     # 将图像转换为灰度图像
 5     grayscale_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
 6     # 将图像转换为RGB图像(用于显示)
 7     rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
 8     # 不显示坐标轴
 9     plt.axis("off")
10     # 显示图像
11     plt.imshow(rgb_image)
12     # 加载人脸检测器
13     face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
14     # 检测人脸
15     faces = face_detector.detectMultiScale(
16         grayscale_image,
17         scaleFactor=1.1,
18         minNeighbors=2,
19         minSize=(20, 20),
20         flags=cv2.CASCADE_SCALE_IMAGE
21     )
22     # 如果检测到一个人脸
23     if len(faces) == 1:
24         x, y, w, h = faces[0]
25         # 提取人脸图像并调整大小
26         face = cv2.resize(grayscale_image[y:y+h, x:x+w], (200, 200))
27         # 使用模型预测人脸图像的标签
28         params = model.predict(face)
29         # 根据预测的标签输出结果
30         if params[0] == 1:
31             print("该图片里的人是蔡徐坤!")
32         elif params[0] == 0:
33             print("该图片里的人是李晨!")
34         else:
35             print("该图片里的人不是蔡徐坤也不是李晨!此人不认识。")
36     else:
37         print("无法识别!")

8、保存人脸图像用于训练

 1 save_faces_for_training("caixukun", "face_images/wang")
 2 save_faces_for_training("lichen", "face_images/angel")
 3 print("读取并截取人脸图片OK")
 4 
 5 # 生成标签文件
 6 generate_labels("face_images")
 7 print("保存截取的人脸图片OK")
 8 
 9 # 加载图像和标签
10 images, labels = load_images_and_labels()
11 # 训练模型
12 train_model(images, labels)
13 print("正在开始识别请稍等")
14 
15 # 识别人脸
16 image_path = "c01.jpg"
17 # 创建人脸识别模型
18 model = cv2.face.EigenFaceRecognizer_create()
19 # 从文件中加载训练好的模型
20 model.read("face_trained.yml")
21 # 使用模型识别人脸
22 recognize_face(image_path, model)