1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
| import sys
import os
import numpy as np
import cv2 as cv
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog
root_dir = 'FaceDB_orl'
def createDataBase(path):
print('--------正在获取数据--------')
path1 = []
X = []
for dirpath, dirnames, filenames in os.walk(path):
for file in filenames:
temp_path = os.path.join(dirpath, file)
path1.append(temp_path)
for img_path in path1:
img = cv.imread(img_path, cv.IMREAD_GRAYSCALE)
# img = cv.resize(img, crop_size)
temp = img.reshape(-1, 1)
X.append(temp)
X = np.array(X)
# print(X.shape[0]) # m个数据
print('--------获取数据结束--------')
return X.reshape(X.shape[0], X.shape[1]).T # (row*col, 400)
def eigenface(X, k1=0, k2=0):
print('--------正在特征提取--------')
m = X.shape[1] # 400
# 计算平均脸及中心化
X_mean = np.mean(X, 1) # (r*l, 1)
X_mean = np.reshape(X_mean, (-1, 1))
X = X - X_mean # (r*l, 400)
# 计算协方差矩阵的特征值、特征向量
L_mat = np.dot(X.T, X) / (m - 1) # (400, 400)
[W, V] = np.linalg.eig(L_mat) # 求取特征向量eiv以及特征值eic
# 取出特征值大的特征向量 作为特征脸
L_eig_vec = []
if k1 != 0: # 根据特征值的值来选取向量
for i in range(len(V)):
if W[i] > k1:
L_eig_vec.append(V[:, i])
if k2 != 0: # 选取从大到小的k2个向量
index = np.argsort(W)[::-1]
L_eig_vec = V[index[:k2], :] # (k2, 400)
L_eig_vec = np.array(L_eig_vec)
# print(L_eig_vec.shape)
# 得到协方差矩阵的特征向量组成的投影子空间(脸空间)
Ei_Face = np.dot(X, L_eig_vec.T) # (r*l, 399)
print('--------特征提取结束--------')
return X_mean, X, Ei_Face
def recognition(TestImage, X_mean, X, Ei_Face):
print('----------正在识别----------')
# 将训练数据投影到脸空间内
EI_Num = Ei_Face.shape[1] # 合格个数 m
ProjectImage = np.dot(Ei_Face.T, X[:, :EI_Num]) # (m, m) 每一列是一个特征脸
# 读取输入图片 灰度读取
input_image = cv.imread(TestImage, cv.IMREAD_GRAYSCALE)
image = input_image.reshape(-1, 1) # (row*col, 1)
# 输入图片 中心化 同PCA的第一步
difference = image - X_mean
# print(difference)
# 输入图片投影到脸空间中 同PCA的最后一步
ProjectedTestImage = np.dot(difference.T, Ei_Face).T # (399, 1) 变成列向量
# print(ProjectedTestImage.shape)
# 计算欧式距离 将每行数据(axis=0) - 输入图片 计算欧式距离
Euclidean_dist = np.linalg.norm(ProjectedTestImage - ProjectImage, axis=0)
# 识别图片 距离最相近
Recognized_index = np.argmin(Euclidean_dist, axis=0)
# print(Euclidean_dist[Recognized_index])
OutputName = Recognized_index + 1
print('----------识别结束----------')
return OutputName
class PcaUI(object):
img_path = ''
k1 = 1
k2 = 0
def setUI(self, Form):
Form.setObjectName("Form")
Form.resize(1000, 600)
# 选择特征获取方式:按值分类 [ ] 按序分类 [ ]
self.label1_1 = QtWidgets.QLabel(Form)
self.label1_1.setGeometry(QtCore.QRect(250, 50, 150, 40))
self.label1_2 = QtWidgets.QLabel(Form)
self.label1_2.setGeometry(QtCore.QRect(390, 50, 80, 40))
self.label1_3 = QtWidgets.QLabel(Form)
self.label1_3.setGeometry(QtCore.QRect(640, 50, 80, 40))
self.textEdit1_1 = QtWidgets.QTextEdit(Form)
self.textEdit1_1.setGeometry(QtCore.QRect(465, 58, 150, 28))
self.textEdit1_2 = QtWidgets.QTextEdit(Form)
self.textEdit1_2.setGeometry(QtCore.QRect(715, 58, 150, 28))
# 选择测试图片: [ ] 浏览文件
self.label2 = QtWidgets.QLabel(Form)
self.label2.setGeometry(QtCore.QRect(250, 150, 150, 40))
self.textEdit2 = QtWidgets.QTextEdit(Form)
self.textEdit2.setGeometry(QtCore.QRect(390, 158, 280, 28))
self.pushButton2 = QtWidgets.QPushButton(Form)
self.pushButton2.setGeometry(QtCore.QRect(773, 154, 71, 31))
# 测试图片 预测图片 开始识别
self.label3_3 = QtWidgets.QLabel(Form)
self.label3_3.setGeometry(QtCore.QRect(250, 230, 80, 40))
self.label3_1 = QtWidgets.QLabel(Form)
self.label3_1.setGeometry(QtCore.QRect(250, 260, 92, 112))
self.label3_1.setStyleSheet("background-color: cyan;")
self.label3_1.setAlignment(QtCore.Qt.AlignCenter)
self.label3_4 = QtWidgets.QLabel(Form)
self.label3_4.setGeometry(QtCore.QRect(460, 230, 80, 40))
self.label3_2 = QtWidgets.QLabel(Form)
self.label3_2.setGeometry(QtCore.QRect(460, 260, 92, 112))
self.label3_2.setStyleSheet("background-color: cyan;")
self.label3_2.setAlignment(QtCore.Qt.AlignCenter)
self.pushButton3 = QtWidgets.QPushButton(Form)
self.pushButton3.setGeometry(QtCore.QRect(773, 260, 71, 31))
self.pushButton2.clicked.connect(self.openfile)
self.pushButton3.clicked.connect(self.runPCA)
self.reTranslateUI(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def openfile(self):
fname = QFileDialog.getOpenFileName(None, "打开文件", "./", "*.png;;All Files(*)")
self.img_path = fname[0]
s = fname[0].find('pca')
self.textEdit2.setText(fname[0][s:])
def runPCA(self):
if self.textEdit1_2.toPlainText() != '':
self.k1 = int(self.textEdit1_1.toPlainText())
if self.textEdit1_2.toPlainText() != '':
self.k2 = int(self.textEdit1_2.toPlainText())
png = QtGui.QPixmap(self.img_path).scaled(self.label3_1.width(), self.label3_1.height())
self.label3_1.setPixmap(png)
X = createDataBase(root_dir)
X_mean, X_cen, Ei_Face = eigenface(X, 300)
image_No = recognition(self.img_path, X_mean, X_cen, Ei_Face)
print('识别的图片是:' + str(image_No) + '.png')
img = X[:, image_No - 1].reshape(112, 92)
cv.imwrite('./result.png', img, [int(cv.IMWRITE_JPEG_QUALITY), 95])
png = QtGui.QPixmap('./result.png').scaled(self.label3_2.width(), self.label3_2.height())
self.label3_2.setPixmap(png)
def reTranslateUI(self, Form):
"""
选择特征获取方式:按值分类 [ ] 按序分类 [ ]
选择测试图片: [ ] 浏览文件
测试图片 预测图片 开始识别
"""
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "人脸识别--PCA"))
self.label1_1.setText(_translate("Form", "选择特征获取方式:"))
self.label1_2.setText(_translate("Form", "按值分类"))
self.label1_3.setText(_translate("Form", "按序分类"))
self.textEdit1_1.setPlaceholderText('k1(默认为1)')
self.textEdit1_2.setPlaceholderText('k2(≤400)')
self.label2.setText(_translate("Form", "选择测试图片:"))
self.pushButton2.setText(_translate("Form", "浏览文件"))
self.label3_3.setText(_translate("Form", "测试图片"))
self.label3_1.setText(_translate("Form", "测试图片"))
self.label3_4.setText(_translate("Form", "预测图片"))
self.label3_2.setText(_translate("Form", "预测图片"))
self.pushButton3.setText(_translate("Form", "开始识别"))
if __name__ == '__main__':
app = QApplication(sys.argv)
MainWindow = QMainWindow()
ui = PcaUI()
ui.setUI(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
|