python人脸识别算法_利用Python实现基于PCA算法的人脸识别

前面的文章中提到,利用opencv+python的组合可以方便的提取出图像中的人脸。当然,opencv自带的提取算法还是有很大缺陷的,不过并不妨碍我们的应用。接下来,利用python对已经获许的人脸图片进行训练,从而可以识别出人脸。本文利用的PCA算法,实现起来较为容易,利用了numpy库。程序还只是一个算法实现,界面和交互都还不太友好,以后我会对其进行改进,并把它扩展为一个可应用的程序。

详细看代码和注释。

#coding=gbk

"""基于PCA算法的人脸识别

@author: [email protected]

@time: 2012.10

"""

from PIL import Image, ImageDraw

import numpy

import cv

import os

import sys

IMAGE_SIZE = (40,40)

def createDatabase(path, number):

"""从指定的路径path中处理number个按照顺序命名的人脸图片,成为一个矩阵"""

imageMatrix = []

for i in range(1,number+1):

image = Image.open(path+'\\'+str(i)+'.jpg')

image = image.resize(IMAGE_SIZE) #缩小图片

grayImage = image.convert('L')

imageArray = list(grayImage.getdata())#转换为一个一维数组,按照行排列

imageMatrix.append(imageArray)

imageMatrix = numpy.array(imageMatrix) #转换为二维矩阵,行为图像像素值按行排列,没列为一幅图

#print imageMatix

return imageMatrix

def eigenfaceCore(Matrix):

"""通过得到的图像矩阵训练特征脸"""

trainNumber, perTotal = numpy.shape(Matrix) #返回图像的个数,和每个图像的大小

"""按照列计算平均向量"""

meanArray = Matrix.mean(0) #0按照列计算平均,1按照行计算平均

"""计算每个向量与平均向量的差"""

diffMatrix = Matrix - meanArray

"""计算协方差矩阵C的替代L"""

#diffMatrixTranspose = numpy.transpose(diffMatrix) #矩阵转置

diffMatrix = numpy.mat(diffMatrix)#创建矩阵类型的数据

L = diffMatrix * diffMatrix.T #使乘得的矩阵较小

eigenvalues, eigenvectors = numpy.linalg.eig(L) #特征向量v[:,i]对应特征值w[i]

"""这里得到的特征值和特征向量并无顺序,

下一部按照特征值大于1来提取特征向量"""

eigenvectors = list(eigenvectors.T) #因为特征向量矩阵的每列是一个特征向量,

#所以需要转置后,变为一个list,然后通过pop方法,

#删除其中的一行,再逆变换转回去

for i in range(0,trainNumber):

if eigenvalues[i] < 1:

eigenvectors.pop(i)

eigenvectors = numpy.array(eigenvectors) #由于无法直接创建一维的矩阵,所以需要一个数组过度

eigenvectors = numpy.mat(eigenvectors).T

"""最后计算特征脸,也就是计算出C

这种变换减少了计算次数"""

#print numpy.shape(diffMatrix)

#print numpy.shape(eigenvectors)

eigenfaces = diffMatrix.T * eigenvectors

return eigenfaces

def recognize(testIamge, Matrix, eigenface):

"""testIamge,为进行识别的测试图片

Matrix为所有图片构成的矩阵

eigenface为特征脸

返回识别出的文件的行号"""

"""按照列计算平均向量"""

meanArray = Matrix.mean(0) #0按照列计算平均,1按照行计算平均

"""计算每个向量与平均向量的差"""

diffMatrix = Matrix - meanArray

"""确定经过过滤后的图片数目"""

perTotal, trainNumber = numpy.shape(eigenface)

"""将每个样本投影到特征空间"""

projectedImage = eigenface.T * diffMatrix.T

#print numpy.shape(projectedImage)

"""预处理测试图片,将其映射到特征空间上"""

testimage = Image.open(testIamge)

testimage = testimage.resize(IMAGE_SIZE)

grayTestImage = testimage.convert('L')

testImageArray = list(grayTestImage.getdata())#转换为一个一维数组,按照行排列

testImageArray = numpy.array(testImageArray)

differenceTestImage = testImageArray - meanArray

#转换为矩阵便于接下来的乘法操作

differenceTestImage = numpy.array(differenceTestImage)

differenceTestImage = numpy.mat(differenceTestImage)

projectedTestImage = eigenface.T * differenceTestImage.T

#print numpy.shape(projectedImage)

#print numpy.shape(projectedTestImage)

"""按照欧式距离计算最匹配的人脸"""

distance = []

for i in range(0, trainNumber):

q = projectedImage[:,i]

temp = numpy.linalg.norm(projectedTestImage - q) #计算范数

distance.append(temp)

minDistance = min(distance)

index = distance.index(minDistance)

return index+1 #数组index是从0开始的

if __name__ == "__main__":

TrainNumber = 22

Matrix = createDatabase('D:\FaceRecognition\matlab\PCA_based Face Recognition\PCA_based+Face+Recognition\PCA_based Face Recognition System\TrainDatabase', TrainNumber)

eigenface = eigenfaceCore(Matrix)

unkown = 11

testimage = 'D:\FaceRecognition\matlab\PCA_based Face Recognition\PCA_based+Face+Recognition\PCA_based Face Recognition System\TestDatabase\\' + str(unkown) +'.jpg'

print recognize(testimage, Matrix, eigenface)

程序可以正确识别出训练集合中的人脸。不过对于更大范围的训练库,还有更进一步的实验还未做。

接下来,我会在人脸识别方面进一步的做算法研究,欢迎有相同兴趣的童鞋一起交流。@Sea_Smile_

转载请注明出处!

你可能感兴趣的:(python人脸识别算法)