Core Component Analysis (PCA) using python

I am trying to implement face recognition using basic component analysis (PCA) using python. I follow the steps in this tutorial: http://onionesquereality.wordpress.com/2009/02/11/face-recognition-using-eigenfaces-and-distance-classifiers-a-tutorial/

Here is my code:

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) #Step 8: get the normalized image, covariance, eigenvalues and eigenvectors for input image shifted_in = input_image - mean_image cov = np.cov(shifted_in) eigenvalues_in, eigenvectors_in = linalg.eig(cov) 

I get the error message: Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 47, in <module> shifted_in = input_image - mean_image ValueError: operands could not be broadcast together with shapes (90,90) (8100)

I tried to remove .flatten() from step 1, but this generated another error when calculating eigenvalues ​​and eigenvectors: Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 25, in <module> eigenvalues,eigenvectors = linalg.eig(c) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 1016, in eig _assertRank2(a) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 155, in _assertRank2 'two-dimensional' % len(a.shape)) LinAlgError: 4-dimensional array given. Array must be two-dimensional Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 25, in <module> eigenvalues,eigenvectors = linalg.eig(c) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 1016, in eig _assertRank2(a) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 155, in _assertRank2 'two-dimensional' % len(a.shape)) LinAlgError: 4-dimensional array given. Array must be two-dimensional

I also tried adding .flatten() to step 7, but also generated another error when calculating the eigenvalues ​​and eigenvectors of the input image: Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 49, in <module> eigenvalues_in, eigenvectors_in = linalg.eig(cov) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 1016, in eig _assertRank2(a) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 155, in _assertRank2 'two-dimensional' % len(a.shape)) LinAlgError: 0-dimensional array given. Array must be two-dimensional Traceback (most recent call last): File "C:/Users/Karim/Desktop/Bachelor 2/New folder/new3.py", line 49, in <module> eigenvalues_in, eigenvectors_in = linalg.eig(cov) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 1016, in eig _assertRank2(a) File "C:\Python27\lib\site-packages\numpy\linalg\linalg.py", line 155, in _assertRank2 'two-dimensional' % len(a.shape)) LinAlgError: 0-dimensional array given. Array must be two-dimensional

Anyone can help?

+4
source share
1 answer

I finally looked at the tutorial that you provided, and it seems that the author suggests that you smooth the images. At this point, you can continue using flattened arrays, as it better matches this tutorial.

I believe that the place to fix it is in step 7, where you have the covariance of the input image. However, the covariance matrix of the input image will be scalar, and you will not be able to find the eigenvalues ​​and eigenvectors. You can project it as a 2d matrix of size (1,1) , but then your own value will be just covariance, and your own vector will be [[1]] .

That is, for example,

 In [563]: input_image = np.random.rand(90,90).flatten() In [564]: c = np.cov(input_image) In [565]: c Out[565]: array(0.08280644230318886) In [566]: c.shape Out[566]: () In [567]: c.ndim Out[567]: 0 

So, we reformat c as 2d:

 In [568]: cmat = c.reshape(1,1) # equivalent to cmat = c[...,np.newaxis,np.newaxis] In [569]: cmat Out[569]: array([[ 0.08280644]]) In [570]: cmat.shape Out[570]: (1, 1) In [571]: cmat.ndim Out[571]: 2 

So now we can find our own element:

 In [572]: ceigval, ceigvec = linalg.eig(cmat) 

But for a singleton matrix, there is only one eigenvalue and one eigenvector, and the eigenvalue is an element of the matrix, and the eigenvector is a unit vector of length 1, so I'm not sure if this is really what you want to do for face recognition.

 In [573]: ceigval Out[573]: array([ 0.08280644]) In [574]: ceigvec Out[574]: array([[ 1.]]) In [576]: np.isclose(c, ceigval) Out[576]: True 

By the way, so we had to do c 2d:

 In [577]: linalg.eig(c) --------------------------------------------------------------------------- LinAlgError: 0-dimensional array given. Array must be two-dimensional 

On the other hand, you can get covariance of uncompressed image_input, then you will have N eigenvalues ​​and N eigenvectors:

 In [582]: input_image = np.random.rand(90,90) In [583]: c = np.cov(input_image) In [584]: c.shape Out[584]: (90, 90) In [585]: ceigval, ceigvec = linalg.eig(c) In [586]: ceigval.shape Out[586]: (90,) In [587]: ceigvec.shape Out[587]: (90, 90) 
+3
source

All Articles