人脸识别

发布时间 2023-06-15 21:52:53作者: Ares-xh

1.导入库函数

1 import numpy as np 
2 import matplotlib.pyplot as plt
3 import cv2
4 import os #导入os库,用于实现与操作系统的交互
5 import imghdr #导入imghdr库,用于判断图像文件的类别

 

2.定义人脸识别函数

 1 def facedetector(img_name,output):
 2 #定义人脸识别函数,检测人脸后,把人脸保存到指定的文件中
 3     name = os.path.basename(img_name)
 4     #获取图像文件名
 5     
 6     img = cv2.imread(img_name)
 7     #读取图像文件
 8     
 9     gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
10     #将图像转为灰度图
11     
12     face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")
13     #加载人脸识别检测器
14     
15     #在灰度图中检测人脸
16     faces = face_detector.detectMultiScale(
17     gray, #灰度图像,即想要识别的人脸
18     scaleFactor=1.1,#表示每次缩小图像的比例,为1.1
19     minNeighbors=2, #表示图片需要有2个邻近矩形,才能被认为是人脸。
20     minSize=(20, 20),#定义匹配人脸的最小尺寸
21     flags=cv2.CASCADE_SCALE_IMAGE #选择检测模式,为正常比例检测
22 )  # 在灰度图像中检测人脸
23     
24     #将检测出来的人脸部分按照给定文件比蒙保存到指定的文件夹
25     for i,(x,y,w,h) in enumerate(faces):
26         pic_name = 'a{0}{1}'.format(i,name)# 根据人脸位置信息和文件名生成保存的文件名
27         f = cv2.resize(img[y:y+h,x:x+h],(200,200))# 从原图中截取人脸部分并调整大小为200x200像素
28         
29         cv2.imwrite(os.path.join(output,pic_name),f)# 将人脸图像保存到指定的输出路径
30         print(x,y)# 输出人脸位置信息

 

3.定义训练函数

1 def save_faces_for_train(path,output):
2 #保存训练样本中的人脸图像    
3     if not os.path.exists(output):
4     #如果输出目录不存在,则创建目录
5         os.makedirs(output)#创建目录
6         
7     for file in os.listdir(path):#遍历输入目录中的文件
8         file_name = os.path.join(path,file)# 获取文件的完整路径
9         facedetector(file_name,output)#对每个文件进行人脸检测并保存人脸图像

 

4.训练两个人脸模型

1 save_faces_for_train("msk","face_images/msk")# 调用函数保存"Msk"目录下的人脸图像
2 
3 save_faces_for_train("leijun","face_images/leijun")# 调用函数保存"Leijun"目录下的人脸图像
4 
5 print("OK")#如果调用成功,会打印OK

 

5.定义生成标签函数

 1 #生成样本标签
 2 def get_label(path):
 3     #打开标签文件
 4     fh = open("label.txt","w")
 5     # 创建一个空的标签文件,准备写入标签信息
 6     label = 0
 7     # 初始化标签值为0
 8     
 9     #遍历目录及子目录下的文件
10     for root,dirs,files in os.walk(path):
11         # 使用os.walk函数遍历目录及其子目录下的文件和文件夹
12         for subdir in dirs:
13             # 遍历子目录
14             subdir_path = os.path.join(root,subdir)# 获取子目录的完整路径
15             for file in os.listdir(subdir_path):
16                 # 遍历子目录中的文件
17                 filepath = os.path.join(subdir_path,file) # 获取文件的完整路径
18                 imgType = imghdr.what(filepath)# 判断文件类型
19                 
20                 # 将文件路径和对应的标签写入标签文件
21                 fh.write(filepath)# 写入文件路径
22                 fh.write(":")# 写入分隔符":"
23                 fh.write(str(label)) # 写入标签值(将数字转为字符串)
24                 fh.write("\n")# 写入换行符,用于分隔每个文件的标签
25                 
26             label += 1# 标签值自增,用于区分不同类别的文件
27 
28     
29     fh.close()# 关闭标签文件

 

6.生成标签

1 get_label("face_images")# 生成样本标签
2 
3 print("OK")#若生成成功,则打印OK

 

7.根据标签,打开对应的图像的灰度图,检查人脸识别情况,并手动删除脏数据

 1 import cv2
 2 import math #调用math库中的ceil函数来计算图像
 3 
 4 images = []  # 存储图像数据的列表
 5 labels = []  # 存储标签数据的列表
 6 
 7 fh = open("label.txt")  # 打开标签文件                       
 8 
 9 for line in fh:  # 逐行读取标签文件
10     arr = line.split(":")  # 使用冒号":"分割每行的文件路径和标签值
11     img = cv2.imread(arr[0])  # 读取图像文件                                                     
12     gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)  # 将图像转换为灰度图像
13     
14     images.append(gray)  # 将灰度图像添加到图像列表中
15     labels.append(int(arr[1]))  # 将标签值转换为整数后添加到标签列表中
16 
17 n = math.ceil(len(images) / 10)  # 计算图像显示的行数
18 plt.figure(figsize=(10, n))  # 创建一个图像显示窗口,指定宽度为10,高度为n
19 
20 # 遍历图像列表并显示图像         
21 for i, img in enumerate(images):
22     plt.subplot(n, 10, i+1)  # 在图像显示窗口中创建子图
23     plt.imshow(img, "gray")  # 显示灰度图像                                                                 
24     plt.title(labels[i])  # 设置子图标题为对应的标签值
25     plt.axis("off")  # 不显示坐标轴
26     plt.tight_layout()  # 调整子图布局,确保图像显示完整
27     
28 plt.show()  # 显示图像窗口

 

8.保存自己训练的模型

 1 import cv2
 2 import math
 3 
 4 images = []# 存储图像数据的列表
 5 labels = []# 存储标签数据的列表
 6 
 7 fh = open("label.txt")# 打开标签文件
 8 
 9 for line in fh:# 逐行读取标签文件
10     arr = line.split(":")# 使用冒号":"分割每行的文件路径和标签值
11     img = cv2.imread(arr[0])#读取图像
12     gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)#将图像转为灰度图 
13      
14     images.append(gray)# 将灰度图像添加到图像列表中
15     labels.append(int(arr[1]))# 将标签值转换为整数后添加到标签列表中
16 
17 model = cv2.face.EigenFaceRecognizer_create()# 创建一个Eigenfaces人脸识别模型
18 model.save("0611_face_trained.yml")# 保存训练好的模型为"0611_face_trained.yml"文件
19  
20 print("OK")#模型保存运行成功,打印OK

 

9.识别人脸

 1 import cv2
 2 import matplotlib.pyplot as plt
 3 
 4 model = cv2.face.EigenFaceRecognizer_create() # 创建一个Eigenfaces人脸识别模型
 5 model.read("0611_face_trained.yml")#导入训练好的模型
 6 
 7 img_name = "leijun1.jpg"  # 导入想要识别的图片            
 8 img = cv2.imread(img_name)  # 读取图片
 9 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 将图片转换为灰度图像
10 
11 face_detector = cv2.CascadeClassifier("haarcascade_frontalface_alt.xml")  # 加载人脸识别检测器
12 
13 faces = face_detector.detectMultiScale(
14     gray, #灰度图像,即想要识别的人脸
15     scaleFactor=1.1,#表示每次缩小图像的比例,为1.1
16     minNeighbors=2, #表示图片需要有2个邻近矩形,才能被认为是人脸。
17     minSize=(20, 20),#定义匹配人脸的最小尺寸
18     flags=cv2.CASCADE_SCALE_IMAGE #选择检测模式,为正常比例检测
19 )  # 在灰度图像中检测人脸
20 
21 if len(faces) == 1:  # 如果检测到一个人脸
22     x, y, w, h = faces[0]  # 提取人脸的位置和尺寸
23     face = cv2.resize(gray[y:y+h, x:x+h], (200, 200))  # 调整人脸图像的大小为200x200像素
24     cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)  # 在原图中标记人脸位置,用红色矩形框表示
25 
26     params = model.predict(face)  # 使用模型预测人脸标签
27     if params[0] == 0:  # 如果预测结果为0
28         print("该图片是雷军!")
29     elif params[0] == 1:  # 如果预测结果为1
30         print("该图片是马斯克!")
31     else:  # 如果预测结果不是0也不是1
32         print("不是雷军也不是马斯克!此人不认识!")
33 else:  # 如果未检测到人脸或检测到多个人脸
34     print("无法识别!")
35 
36 img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # 将图片从BGR格式转换为RGB格式
37 plt.axis("off")  # 不显示坐标轴
38 plt.imshow(img)  # 显示图片