Reputation: 1559
I am trying to make face recognition by Principal component analysis (PCA) using python (matplotlib). I am trying to do it as described in this image:
Here is my code:
import os
from PIL import Image
import numpy as np
import glob
from matplotlib.mlab import PCA
#Step1: put database images into a 3D array
filenames = glob.glob('C:\\Users\\Karim\\Downloads\\att_faces\\New folder/*.pgm')
filenames.sort()
img = [Image.open(fn).convert('L') for fn in filenames]
images = np.dstack([np.array(im) for im in img])
# Step2: create 2D flattened version of 3D input array
d1,d2,d3 = images.shape
b = np.zeros([d1,d2*d3])
for i in range(len(images)):
b[i] = images[i].flatten()
#Step 3: database PCA
results = PCA(b.T)
x = results.Wt
#Step 4: input image
input_image = Image.open('C:\\Users\\Karim\\Downloads\\att_faces\\1.pgm').convert('L')
input_image = np.array(input_image)
input_image = input_image.flatten()
#Step 5: input PCA
in_results = PCA(input_image.T)
y = in_results.Wt
#Step 6: get shortest distance
But I am getting an error from in_results = PCA(input_image.T)
saying:
Traceback (most recent call last):
File "C:\Users\Karim\Desktop\Bachelor 2\New folder\new2.py", line 29, in <module>
in_results = PCA(input_image.T)
File "C:\Python27\lib\site-packages\matplotlib\mlab.py", line 846, in __init__
n, m = a.shape
ValueError: need more than 1 value to unpack
Anyone can help??
Upvotes: 0
Views: 7981
Reputation: 365767
The problem is that the PCA
constructor requires a 2D array, and assumes that you're going to pass it one. You can see that from the traceback:
in __init__
n, m = a.shape
ValueError: need more than 1 value to unpack
Obviously if a
is a 0D or 1D array, a.shape
will not have two members, and therefore this will fail. You can try printing out input_image.T.shape
yourself to see what it is.
But you have at least one problem with your code, possibly two.
First, even if you had a 2D array at some point, you do this:
input_image = input_image.flatten()
After that, of course, you've got a 1D array.
Second, I don't think you ever had a 2D array. This:
input_image = np.array(input_image)
… should create a "scalar" (0D) array with one object, based on what the numpy
and PIL
docs say. Testing it on various different setups, I seem to get a 0D array sometimes, a 2D array others, so maybe you're not having this problem—but if you aren't, you may get it as soon as you run on a different machine.
You probably wanted this:
input_image = np.asarray(input_image)
This will either give you a 2D array, or raise an exception. (Well, unless you accidentally open a multi-channel image, in which case it'll give you a 3D array, of course.)
Upvotes: 3