2013-04-15 62 views
2

我将尝试使用python主成分分析(PCA)来实现面部识别。我下面这个教程中的步骤:http://onionesquereality.wordpress.com/2009/02/11/face-recognition-using-eigenfaces-and-distance-classifiers-a-tutorial/错误 - 计算为PCA欧氏距离在Python

这里是我的代码:

import os 
from PIL import Image 
import numpy as np 
import glob 
import numpy.linalg as linalg 


#Step1: put database images into a 2D array 
filenames = glob.glob('C:\\Users\\Karim\\Downloads\\att_faces\\New folder/*.pgm') 
filenames.sort() 
img = [Image.open(fn).convert('L').resize((90, 90)) for fn in filenames] 
images = np.asarray([np.array(im).flatten() for im in img]) 


#Step 2: find the mean image and the mean-shifted input images 
mean_image = images.mean(axis=0) 
shifted_images = images - mean_image 


#Step 3: Covariance 
c = np.cov(shifted_images) 


#Step 4: Sorted eigenvalues and eigenvectors 
eigenvalues,eigenvectors = linalg.eig(c) 
idx = np.argsort(-eigenvalues) 
eigenvalues = eigenvalues[idx] 
eigenvectors = eigenvectors[:, idx] 


#Step 5: Only keep the top 'num_eigenfaces' eigenvectors 
num_components = 20 
eigenvalues = eigenvalues[0:num_components].copy() 
eigenvectors = eigenvectors[:, 0:num_components].copy() 


#Step 6: Finding weights 
w = eigenvectors.T * np.asmatrix(shifted_images) 


#Step 7: Input image 
input_image = Image.open('C:\\Users\\Karim\\Downloads\\att_faces\\1.pgm').convert('L').resize((90, 90)) 
input_image = np.asarray(input_image).flatten() 


#Step 8: get the normalized image, covariance, eigenvalues and eigenvectors for input image 
shifted_in = input_image - mean_image 
c = np.cov(input_image) 
cmat = c.reshape(1,1) 
eigenvalues_in, eigenvectors_in = linalg.eig(cmat) 


#Step 9: Fing weights of input image 
w_in = eigenvectors_in.T * np.asmatrix(shifted_in) 
print w_in 
print w_in.shape 

#Step 10: Euclidean distance 
d = np.sqrt(np.sum((w - w_in)**2)) 
idx = np.argmin(d) 
match = images[idx] 

我在第10步就吃一个问题,因为我得到这个错误: Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 59, in <module> d = np.sqrt(np.sum((w - w_in)**2)) File "C:\Python27\lib\site-packages\numpy\matrixlib\defmatrix.py", line 343, in __pow__ return matrix_power(self, other) File "C:\Python27\lib\site-packages\numpy\matrixlib\defmatrix.py", line 160, in matrix_power raise ValueError("input must be a square array") ValueError: input must be a square array

任何人都可以帮助??

+1

我看到你决定采取本征的,从1x1的协方差矩阵。你应该确保这真的是你想要做的。协方差是找出两组或多组数据是如何相关的,并且当你在训练图像上运行时,你发现它们彼此之间的相关性很好。当你在输入图像上运行它时,你会得到它的自相关值,这可能不是你想要的。我不得不更仔细地看看这个教程并思考它,但我想警告你,以免我以前的答案误导你。 – askewchan

+0

@askewchan感谢您的建议。我想知道我可以使用'matplotlib'内置的''PCA'类来完成我的工作。你知道它是如何工作的吗? – user2229953

+0

不,不幸的是,我没有经验,但如果你尝试学习它,你总是可以在这里发布你的问题:) – askewchan

回答

2

我想你想改变,你计算d到像这样的线路:

#Step 10: Euclidean distance 
d = np.sqrt(np.sum(np.asarray(w - w_in)**2, axis=1) 

这给你长M名单平方,总结,扎根距离(训练图像的数量)每个图像像素之间。我相信你不想矩阵产品,你希望每个值的平方的elementwise,因此np.asarray使其的矩阵。这使您w_in,并且每个w矩阵之间的“欧氏”的区别。

1

当你去(w - w_in),结果不是一个方阵。为了乘一个矩阵本身,它必须是方形的(这只是矩阵乘法的一个属性)。因此,无论你已经构建了您的ww_in矩阵错了,还是你真正的意思做的是方形矩阵(w - w_in)这是一个不同的操作每个元素。搜索元素相乘来查找numpy语法。

+1

我想要的是'(W - W_in)'不是矩阵中的每个元素,所以也许问题在于构造'W'和'W_in' – user2229953