## 实验内容和原理

PCA

PCA（Principal Components Analysis）是一种统计分析、简化数据集的方法。它利用正交变换来对一系列可能相关的变量的观测值进行线性变换，从而投影为一系列线性不相关变量的值，这些不相关变量称为主成分（Principal Components）。

（线性代数知识回顾：PCA 的数学原理[ http://blog.codinglabs.org/articles/pca-tutorial.html ]）

PCA 的数学定义是：一个正交化线性变换，把数据变换到一个新的坐标系统中，使得这一数据的任何投影的第一大方差在第一个坐标（称为第一主成分）上，第二大方差在第二个坐标（第二主成分）上，依次类推。

```img = cv.imread(path, -1)
Scan = FACE.detectMultiScale(img,scaleFactor=1.1,minNeighbors=3)
if len(Scan) == 1 :
for (x,y,w,h) in Scan:
cropped = img[y:y+h, x:x+w]
# cropped is where face is
cv.rectangle(img, (x,y), (x+w, y+h), (255, 255, 255), 1)
cropped = cv.equalizeHist(cropped)
cropped = cv.resize(cropped, (250, 250))
# change it to 250 * 250 (then will be 62500)
cv.imshow("ori",img)
cv.imshow("figure",cropped)
cv.waitKey(1)
print(path)
# change it to 1-D and append it to T
cropped = cropped.reshape(cropped.size, 1)
T.append(cropped)```

PCA

```ENERGY = float(input("input the energy(float in 0~1)"))
Sum = 0
for i in range(vs.shape[0]):
Sum += vs[i]/sum(vs)
if Sum >= ENERGY:
break
NUM_EIGEN_FACES = max([i, NUM_EIGEN_FACES])
vs = vs[0:NUM_EIGEN_FACES].copy()
Vs = Vs[:, 0:NUM_EIGEN_FACES].copy()
print(Vs.shape)```

`Mean, Vs = cv.PCACompute(T, mean=None, maxComponents=NUM_EIGEN_FACES)`

EigenFace

```for V in Vs:
eigenFace = V.reshape((250, 250))
# here we will show the eigenface
cv.imshow('figure', eigenFace)
cv.waitKey(1)
eigenFaces.append(eigenFace)
eigenFaces = np.array(eigenFaces)
eigenFace_mean = eigenFaces.mean(axis=0)
Mean = Mean.reshape((250, 250))
plt.figure()
plt.title('Mean')
plt.subplot(1, 2, 1)
plt.imshow(Mean, cmap = plt.get_cmap('gray'))
plt.subplot(1, 2, 2)
plt.imshow(eigenFace_mean, cmap = plt.get_cmap('gray'))
plt.show()```

```np.save('save_database\\save_Mean', Mean)
np.save('save_database\\save_A', T)
np.save('save_database\\eigenface', eigenFaces)```

PRO 矩阵用于存储将图像映射到若干特征脸的空间时，每张图像对应的坐标

```PRO = A.dot(Vectors)
# …
# to 1-D
Array = cropped.reshape(cropped.size,1)
Array = np.mat(np.array(Array)).squeeze()
# get the difference and project it to the eiganface space
meanVector = Mean.flatten()
meanVector = meanVector.squeeze()
diff = Array - meanVector
diff = diff.squeeze()
pro = diff.dot(Vectors)```

```distance = []
for i in range(0, A.shape[0]):
cur = PRO[i,:]
temp = np.linalg.norm(pro - cur)
distance.append(temp)
print('No.' + str(i) + ' = ' + str(distance[i]))
minDistance = min(distance)
index = distance.index(minDistance) - 1```

```# load the train-data to find the most similar photo
TRAIN_PATH = 'BioFaceDatabase\BioID-FaceDatabase-V1.2'
TrainFiles = os.listdir(TRAIN_PATH)
paths = glob.glob(os.path.join(TRAIN_PATH, '*.pgm'))
paths.sort()
# …
testImg = cv.putText(testImg, "Most Similar: ", (40, 50), cv.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), 2)
testImg = cv.putText(testImg, paths[index].split ( "\\" ) [ -1 ], (40, 100), cv.FONT_HERSHEY_PLAIN, 1.0, (0, 0, 0), 2)
cv.imshow("ori",testImg)
cv.imshow("recognize result",result)
cv.waitKey(0)```

Train

Cv2 自带的 PCA 的结果：