基于PCA的人脸识别---Python

实验一 基于PCA的人脸识别
一、 实验目的
1 理解和掌握PCA原理
2 利用PCA降维,辅助完成一项实战内容。
二、 实验原理
矩阵的主成分就是其协方差矩阵对应的特征向量,按照对应的特征值大小进行排序,最大的特征值就是第一主成分,其次是第二主成分,以此类推。
三、 算法流程
基于PCA的人脸识别---Python_第1张图片
四、 人脸识别步骤
1.利用给定的数据集,执行上述算法,得到投影矩阵W;
2.计算训练集的投影后的矩阵:P=WX;
3.加载一个测试图片T,测试图片投影后的矩阵为:TestT=WT;
4.计算TestT和P中每个样本距离,选出最近的那个即可。
5.显示投影前后的两张图片。
五、 代码和执行结果展示
(一)实现代码

# -*- coding: utf-8 -*-
"""
Created on Fri Apr 10 16:48:22 2020

@author: tangchunhua
"""

import  numpy as np
import tkinter as tk
from PIL import Image,ImageTk
from tkinter.filedialog import askopenfilename
Image_size=(40,30)

#将图片库中的图片按顺序命名,并将其像数值存到一个数组中
def Database(path,n):
    ImageMatrix=[]
    for i in range(1,n+1):
        ImageXn=Image.open(path+'\\'+str(i)+'.jpg')
        ImageXn=ImageXn.resize(Image_size)
        grayImage=ImageXn.convert('L')
        ImageArray=list(grayImage.getdata())
        ImageMatrix.append(ImageArray)
    ImageMatrix=np.array(ImageMatrix)
    return ImageMatrix 

def TrainDatabase(matrix):
    #对样本进行中心化
    picNumber,picSize=np.shape(matrix)
    meanArray=matrix.mean(axis=0)
    diffMatrix=matrix-meanArray
    diffMatrix=np.mat(diffMatrix).T
    #计算样本的协方差矩阵
    covariance=diffMatrix*diffMatrix.T
    eigenvalues,eigenvectors=np.linalg.eig(covariance)
    eigenvectors=list(eigenvectors)
    #取特征向量,选择特征值大于一的,特征向量和特征值不用排序
    for i in range(0,picNumber):
        if eigenvalues[i]<1:
            eigenvectors.pop(i)
    eigenvectors=np.array(eigenvectors)
    #调用mat()函数可以将数组转换为矩阵,然后可以对矩阵进行一些线性代数的操作
    w=np.mat(eigenvectors)
    p=w*diffMatrix
    return p,w,meanArray
  
def TestDatabase(testfile,w,p,meanArray):
    ImageXn=Image.open(testfile)
    ImageXn=ImageXn.resize(Image_size)
    grayImage=ImageXn.convert('L')
    ImageArray=list(grayImage.getdata())
    ImageArray=np.array(ImageArray)
    ImageData=ImageArray-meanArray
    ImageData=np.mat(ImageData).T
    testPic=w*ImageData
    #计算距离
    distance=p-testPic
    distance=np.array(distance)
    distance=distance**2
    sumDistance=np.sum(distance,axis=0)
    minDistance=np.min(sumDistance)
    index=np.where(sumDistance==minDistance)
    return (index[0][0]+1)

def resetpic(leftfilename,rightfilename=None):
    img = Image.open(leftfilename)
    #把图片放在label里后在窗口显示
    photo = ImageTk.PhotoImage(img)
    label.config(image=photo)
    label.image=photo
    testImage=rightfilename;
    if rightfilename==None:
        name=TestDatabase(leftfilename,w,p,meanArray)
        testImage='B:\学习文件\机器学习\实验\TrainDatabase\\'+str(name)+'.jpg'
    img_1 = Image.open(testImage)
    photo_1 = ImageTk.PhotoImage(img_1)
    label_1.config(image=photo_1)
    label_1.image=photo_1

def go():
    path= askopenfilename()
    #print(path)
    resetpic(path)
    
if __name__=="__main__":
    trainNumber=20
    path='B:\学习文件\机器学习\实验\TrainDatabase'
    Matrix=Database(path,trainNumber)
    global w,p,meanArray
    p,w,meanArray=TrainDatabase(Matrix)
    Windows=tk.Toplevel()
    Windows.title('Face Recognition')
    Windows.geometry('600x450')
    button=tk.Button(Windows,text='请选择图片',width=15,height=1,command=go)
    label = tk.Label(Windows)
    label_1=tk.Label(Windows)
    label_2=tk.Label(Windows,text="成功识别后的图片")
    label.pack()
    label.place(relx=0,rely=0)
    label_1.pack()
    label_1.place(relx=0.55,rely=0)
    label_2.pack()
    label_2.place(relx=0.7,rely=0.9)
    button.pack()
    button.place(relx=0.1,rely=0.9)
    resetpic("A.jpg","B.jpg") 
    Windows.mainloop()

(二)执行结果
基于PCA的人脸识别---Python_第2张图片
图5.1 初始界面
基于PCA的人脸识别---Python_第3张图片
图5.2 选择测试图片
基于PCA的人脸识别---Python_第4张图片
图5.3 测试图1结果
基于PCA的人脸识别---Python_第5张图片
图5.4 测试图2结果
基于PCA的人脸识别---Python_第6张图片
图5.5 测试图3结果
基于PCA的人脸识别---Python_第7张图片
图5.6 测试图4结果
基于PCA的人脸识别---Python_第8张图片
图5.7 测试图5结果
基于PCA的人脸识别---Python_第9张图片
图5.8 测试图6结果
基于PCA的人脸识别---Python_第10张图片
图5.9 测试图7结果
基于PCA的人脸识别---Python_第11张图片
[图5.10 测试图8结果
基于PCA的人脸识别---Python_第12张图片
图5.11 测试图9结果
基于PCA的人脸识别---Python_第13张图片
图5.12 测试图10结果
基于PCA的人脸识别---Python_第14张图片
图5.13 训练集图片
六、 实验总结
优点:1.实验结果人脸识别的误差几乎为零,小数据范围内识别成功的概率达到百分百;
2.实现了图形化界面,操作简单;
3.对测试图也进行了中心化,提高了图片识别成功的概率。
缺点:1.图形化界面还存在一个小问题没有解决;
2.在降维的过程中投机取巧,没有严格按照将特征向量按对应特征值从大到小按行排列后进行降维。

你可能感兴趣的:(机器学习)