1 #-*- coding: utf-8 -*-
2 from __future__ importunicode_literals3 #操作文件
4 importos5 #科学计算
6 importnumpy as np7 #图像识别
8 importcv2 as cv9 #数据预处理, 该项目中只使用了标签编码
10 importsklearn.preprocessing as sp11
12
13 defload_imgs(directory):14 '''加载 directory 该文件夹下所有以 .jpg 结尾的图片'''
15 #识别 系统环境 自动分配当前系统的路径分隔符并替换
16 directory =os.path.normpath(directory)17 #判断当前路径是否为存在
18 if notos.path.isdir(directory):19 #手动抛出异常 biu biu biu
20 raise IOError("The directory '" + directory + "' doesn't exist!")21 #创建图片集合 用于存储文件夹名和该文件夹下所有的图片
22 faces ={}23 #os.walk(directory) 获取当前文件夹下所有的文件夹以及文件
24 #curdir: 当前文件夹路径
25 #subdirs: 当前文件夹下所有文件夹 (列表)
26 #files: 当前文件夹下所有文件 (列表)
27 for curdir, subdirs, files inos.walk(directory):28 #首先便利所有的文件 筛选.jpg结尾文件并循环
29 for jpeg in (file for file in files if file.endswith('.jpg')):30 #拼接图片路径
31 path =os.path.join(curdir, jpeg)32 #获取该图片分类名称
33 label = path.split(os.path.sep)[-2]34 #判断当前key值是否存在图片集合中, 如果为空则创建该键并赋值空列表
35 #否则给图片集合中的 key 添加图片路径
36 if label not infaces:37 faces[label] =[]38 faces[label].append(path)39 #返回图片集合
40 returnfaces41
42
43 defLBPHModel(fd, codec, train_path):44 '''
45 -------------------46 参数说明: fd, codec, [model_path]47 fd: Haar-like(人脸特征模型对象)48 codec: LabelEncoder(标签编码器对象)49 model_path: 服用模型路径(功能未实现, 没找到读取的函数...)50 -------------------51 返回: 训练后的模型对象52 '''
53 #加载当前文件加下所有.jpg结尾的图片
54 train_faces = load_imgs(train_path) #'traom_imgs'
55 #将所有标签放入编码器进行训练
56 codec.fit(list(train_faces.keys()))57 #创建空的训练集数组x y
58 train_x, train_y =[], []59 #循环所有训练组
60 for label, filenames intrain_faces.items():61 #循环当前样本组中的图片
62 for filename infilenames:63 #读取图片
64 image =cv.imread(filename)65 #将图片转成灰度图
66 gray =cv.cvtColor(image, cv.COLOR_BGR2GRAY)67 #获取人脸特征位置
68 faces =fd.detectMultiScale(69 gray, 1.1, 2, minSize=(100, 100))70 #循环脸部特征数组
71 for l, t, w, h infaces:72 #将图片中的脸部特征裁剪下来
73 train_x.append(gray[t:t + h, l:l +w])74 #标签编码结果存储
75 train_y.append(codec.transform([label])[0])76 train_y =np.array(train_y)77 #创建LBPH人脸检测器
78 model =cv.face.LBPHFaceRecognizer_create()79 #对训练集进行训练
80 model.train(train_x, train_y)81 returnmodel82
83
84 if __name__ == "__main__":85 #训练集图片存储路径
86 train_path = 'train_imgs'
87 #读取人脸描述文件, 构建人脸检测器
88 fd = cv.CascadeClassifier('face.xml')89 #创建标签编码器
90 codec =sp.LabelEncoder()91 #获取model
92 model =LBPHModel(fd, codec, train_path)93 #打开视频捕捉设备
94 vc =cv.VideoCapture(0)95 whileTrue:96 #读取视频帧
97 frame = vc.read()[1]98 #反转图片
99 frame = cv.flip(frame, 1)100 #print(frame)
101 #人脸位置检测, 返回数组
102 faces = fd.detectMultiScale(frame, 1.3, 5)103 #循环人脸位置数组
104 for l, t, w, h infaces:105 #给人脸描边
106 cv.rectangle(frame, (l, t), (l + w, t +h),107 (255, 0, 0), 4)108 #复制原图片文本
109 gray =frame.copy()110 #将图片变化成灰度图
111 gray =cv.cvtColor(gray, cv.COLOR_BGR2GRAY)112 #对面部特征进行识别
113 pred_test_y = model.predict(gray[t:t + h, l:l +w])[0]114 #将预测后的结果进行标签解码
115 face_name =codec.inverse_transform([pred_test_y])[0]116 #给图片添加文本 图片矩阵, 添加文本名称, 设置文本显示位置,
117 #字体样式, 字体大小, 字体颜色, 字体粗细
118 cv.putText(frame, face_name, (l + 5, t - 15),119 cv.FONT_HERSHEY_SIMPLEX, 1,120 (255, 255, 255), 3)121 #打印名称
122 #print(face_name)
123
124 #显示图片
125 cv.imshow('VideoCapture', frame)126 #等待按下ESC键退出, 每次等待33毫秒
127 if cv.waitKey(33) == 27:128 break
129 #关闭视频捕捉设备
130 vc.release()131 #关闭视频窗口
132 cv.destroyAllWindows()