使用Eigenface重构近似的人脸图像

看这篇文章前,可以先阅读Eigenface(PCA)人脸识别实验

1、数据提取与处理

%matplotlib inline
# 导入所需模块
import matplotlib.pyplot as plt
import numpy as np
import os
import cv2
# plt显示灰度图片
def plt_show(img):
    plt.imshow(img,cmap='gray')
    plt.show()
# 读取一个文件夹下的所有图片,输入参数是文件名,返回文件地址列表
def read_directory(directory_name):
    faces_addr = []
    for filename in os.listdir(directory_name):
        faces_addr.append(directory_name + "/" + filename)
    return faces_addr
# 读取所有人脸文件夹,保存图像地址在faces列表中
faces = []
for i in range(1,41):
    faces_addr = read_directory('C:/Users/ASUS/Desktop/att_faces/s'+str(i))
    for addr in faces_addr:
        faces.append(addr)
# 读取图片数据,生成列表标签
images = []
labels = []
for index,face in enumerate(faces):
    # enumerate函数可以同时获得索引和值
    image = cv2.imread(face,0)
    images.append(image)
    labels.append(int(index/10+1))   
# 画出最后20组人脸图像
# 创建画布和子图对象
fig, axes = plt.subplots(10,20
                       ,figsize=(20,10)
                       ,subplot_kw = {
     "xticks":[],"yticks":[]} #不要显示坐标轴
                       )
# 图片x行y列,画布x宽y高
# 填充图像
for i, ax in enumerate(axes.flat):
    ax.imshow(images[i+200],cmap="gray") #选择色彩的模式

使用Eigenface重构近似的人脸图像_第1张图片

2、使用Eigenface重构近似的人脸图像

# 导入sklearn的pca模块
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
import pandas as pd
# 图像数据转换特征矩阵
image_data = []
for image in images:
    data = image.flatten()
    # a是个矩阵或者数组,a.flatten()就是把a降到一维,默认是按横的方向降
    image_data.append(data)
# 转换为numpy数组
X = np.array(image_data)
y = np.array(labels)
data = pd.DataFrame(X)
# 划分数据集
x_train,x_test,y_train,y_test = train_test_split(X, y, test_size=0.2) # train训练,test测试

def pca_fit_transform(i,x_train):
    # 训练PCA模型
    pca=PCA(n_components=i) # 保留100个纬度
    pca.fit(x_train) # 训练过程
    # 返回训练集降维后的数据集
    x_train_pca = pca.transform(x_train) # 转换过程
    V = pca.components_
    return x_train_pca,V

#返回重构的人脸图像的标签
def res_predict(img,X):
    pca=PCA(n_components=100)
    pca.fit(X)
    X1 = pca.transform(X)
    model = cv2.face.EigenFaceRecognizer_create()
    model.train(X1,y)
    
    imgs = []
    imgs.append(img)
    image_data = []
    for img in imgs:
        data = img.flatten()
        image_data.append(data)
    predict = np.array(image_data)
    predict = pca.transform(predict)
    res = model.predict(predict)
    return res[0]

重构人脸图像公式:平均脸+特征向量×降维后的数据=重构图像

# 输出重构的近似人脸
fig, axes = plt.subplots(1,7
                       ,figsize=(20,10)
                       ,subplot_kw = {
     "xticks":[],"yticks":[]} #不要显示坐标轴
                       )
i = 100
for h, ax in enumerate(axes.flat):
    x_train_pca , V = pca_fit_transform(i,x_train)
    ax.imshow(np.mean(X, axis=0).reshape(112,92) + np.dot(x_train_pca[0], V).reshape(112, 92), cmap="gray") # np.dot()矩阵乘法
    i = i + 50

img = np.mean(X, axis=0).reshape(112,92) + np.dot(x_train_pca[0], V).reshape(112, 92)
res = res_predict(img,X)
# 输出原图
fig, axes = plt.subplots(1,7
                       ,figsize=(20,10)
                       ,subplot_kw = {
     "xticks":[],"yticks":[]} #不要显示坐标轴
                       )
for i, ax in enumerate(axes.flat):
    ax.imshow(images[res*10-9+i],cmap="gray") #选择色彩的模式

下图分别为保留100、150、200、250、300、350、400维数据后重构的人脸图像:
使用Eigenface重构近似的人脸图像_第2张图片
为了方便上下对比,输出7张原始图像:
使用Eigenface重构近似的人脸图像_第3张图片
可以发现,在保留350维数据后,重构的人脸和原始输入的人脸图像之间就难以区分了。

如果你觉得还不错,那就给我点个赞吧(* ̄︶ ̄)

你可能感兴趣的:(模式识别,python,人脸识别,人工智能,模式识别,pca降维)