Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

Eigenfaces implementation

Project: thesis_thingy
Views: 871
Kernel: Python 3 (Ubuntu Linux)

Eigenfaces

We used the faces94 dataset for this implementation: https://cswww.essex.ac.uk/mv/allfaces/faces94.zip

import numpy as np import matplotlib.pyplot as plt from PIL import Image %matplotlib inline

Enrollment Process

ids = ['9336923','9338535','anpage','asamma','asewil','astefa','drbost','ekavaz','elduns', 'kaknig','klclar','ksunth','lfso','mbutle','phughe','sbains','slbirc','vstros','yfhsie', 'anonym','anonym1','anonym2','cwang','doraj','fordj','hartb','hensm','ieorf','lyond','macci', 'martin','michael','moors','obeidn','robin','sandm','spacl','tony','voudcx' ]
f94 = {'female': ['9336923','9338535','anpage','asamma','asewil','astefa','drbost','ekavaz','elduns', 'kaknig','klclar','ksunth','lfso','mbutle','phughe','sbains','slbirc','vstros','yfhsie'], 'malestaff': ['anonym','anonym1','anonym2','cwang','doraj','fordj','hartb','hensm','ieorf','lyond','macci', 'martin','michael','moors','obeidn','robin','sandm','spacl','tony','voudcx']}

For each set of faces, we take the first one and add it to the training set.

base = [Image.open(f'faces94/faces94/{cat}/{p}/{p}.1.jpg').convert('L') for cat in f94 for p in f94[cat]]
M = len(base)
X = np.array([base[i].getdata() for i in range(M)])
mean = np.mean(X, 0)
phi = X - mean

We compute for the eigenvalues and eigenvectors using singular value decomposition.

e_faces, sigma, v = np.linalg.svd(phi.transpose(), full_matrices=False)
weights = [np.dot(X[i]-mean, e_faces) for i in range(M)]
np.shape(weights)
(39, 39)

This is what the first eigenface looks like.

display(plt.matshow(np.reshape(e_faces.T[0], (200,180)), cmap='gray'))
<matplotlib.image.AxesImage at 0x7f2bd78e5c18>
Image in a Jupyter notebook

Face Recognition

input_img = Image.open(f'faces94/faces94/malestaff/spacl/spacl.19.jpg').convert('L') input_img
Image in a Jupyter notebook

Projection

gamma = np.array(input_img.getdata())
test_phi = gamma - mean
test_weights = np.dot(test_phi, e_faces)

Distance computation

dist = [np.linalg.norm(phi[i] - test_phi) for i in range(M)] d_min = np.min(dist)

Match finding

threshold = 7000
if d_min < threshold: name = ids[np.argmin(dist)] print(f'{name}\ndist={d_min}') else: print('No match found.')
spacl dist=6604.41185875018

Visualization of the face space

We plot the projections of each training image onto the face space spanned by the first two eigenfaces. The projected input image is represented in the plot as a square.

def identify(img): gamma = np.array(img.getdata()) test_phi = gamma - mean test_weights = np.dot(test_phi, e_faces) return test_weights[0:2]
plt.style.use('fivethirtyeight')
plt.figure(figsize=(15,10)) i = 0 for faceclass in ['malestaff','female']: for setname in f94[faceclass]: iset = [Image.open(f'faces94/faces94/{faceclass}/{setname}/{setname}.{i}.jpg').convert('L') for i in range(1,2)] x, y = np.array([identify(pic) for pic in iset]).T plt.scatter(x,y, s=50) plt.text(x * (1 + 0.02), y * (1 + 0.02), setname) i += 1 plt.scatter(*identify(input_img), label='Input image', marker=',', c='k', s=100) plt.xlabel('Eigenface 1') plt.ylabel('Eigenface 2') plt.title('Face Space') plt.legend(frameon=True)
<matplotlib.legend.Legend at 0x7f2bd77a8dd8>
Image in a Jupyter notebook