# -*- coding: utf-8 -*- """ Created on Thu Nov 9 11:11:04 2017 @author: Shiro """ import numpy as np import cv2 class Face_Recognition(): def __init__(self): self.width = 0 self.height = 0 def load_data_from_file(self, file): f = open(file, 'r') data = [line.split() for line in f] Y = np.zeros((len(data), ), dtype=int) X = np.empty(shape=(10304, len(data)), dtype='float64') print('Shape Y test : ', Y.shape) for i, ldata in enumerate(data): Y[i] = int(data[i][1]) img = cv2.imread(data[i][0], 0) X[:,i] = img.flatten()[:] # cv2.imshow('image', cv2.convertScaleAbs(X[:,i].reshape(112,92 )) ) # cv2.waitKey(0) # cv2.destroyAllWindows() print('X shape', X.shape) return X, Y def ACP(self, X, Y): ''' X : dim N² x M , N² dim image, M number of images Y : dim M mean : dim N² x 1 A dim : N² x M u : dim N² x M, ui dim N² x 1 w : vecteur caractéristique d'une image, dim : K x 1 W : dim K x M ''' self.y = Y # -- Average vector -- # mean = X.sum(axis=1)/X.shape[1] print('mean dim :', mean.shape) # -- Substract mean to image -- # mean3D = np.repeat(mean[:, np.newaxis], X.shape[1], axis=1) print(mean3D[0:5,:]) phi = X - mean3D # -- Compute EigenValue and EigenVectors for A.T A-- # A = phi D = np.dot(np.transpose(A), A) print('A dim :', A.shape) eigenValues, eigenVectors = np.linalg.eigh(D) print('EigenValues : ', eigenValues.shape) print('EigenVectors : ', eigenVectors.shape) idx = eigenValues.argsort()[::-1] eigenValues = eigenValues[idx].reshape(-1,1) eigenVectors = eigenVectors[:,idx] print('EigenValues :', eigenValues) # -- Compute EigenValue and EigenVectors for C -- # u = np.dot(A, eigenVectors) print('u shape : ', u.shape) print('u ', u.sum(axis=0)) u_norm = u/u.sum(axis=0) # -- transformation dans l'espace -- # w = np.dot(np.transpose(u_norm), A) print(' w shape : ', w.shape) # ligne = wi, colonne numero image # -- Save variables -- # self.W = w self.U = u_norm self.average = mean print(' W shape : ', w.shape) def compute_weights_test(self, x, K): ## for one image ''' Alpha = [image, w] w _tes dim : K x 1 ''' w_test = np.dot(np.transpose(self.U[:, 0:K]), (x-self.average)) return w_test def predict(self, X, K): ''' X : data image 1 x N² return argminx ''' wtest = self.compute_weights_test(X, K) #print('wtest :', wtest.shape) preds = self.distance_euclideane(wtest, self.W, K) #print('preds shape:', preds.shape) label = self.y[np.argmin(preds)] #print(label) # img_pred = np.reshape(self.x_train[label], (self.height, self.width)) # print(img_pred) # cv2.imshow('prediction', img_pred) # cv2.waitKey(0) # cv2.imshow('original', np.reshape(X, (self.height, self.width))) # cv2.waitKey(0) # cv2.destroyAllWindows() return label def evaluate(self, x, y, K=10): good = 0.0 tot = len(y) for i in range(0, tot): pred = self.predict(x[:,i], K) if pred == y[i]: good = good + 1 return good/tot def distance_euclideane(self, a, b,K): #print('shape', a.shape, b.shape) return np.sum(np.square(np.repeat(a[:, np.newaxis], b.shape[1], axis=1)-b[0:K,:]), axis=0) def display_images(self, number_images, K): print(self.U[0,0:K], '\n', self.W[0:K,0]) img = np.dot(self.U[:,0:K], self.W[0:K,number_images].reshape(-1,1)).sum(axis=1) + self.average #print('img shape:', img.shape) print('img :', img[0:20]) cv2.imshow('image', cv2.convertScaleAbs(img.reshape(112,92))) cv2.waitKey(0) cv2.destroyAllWindows() def __main__(): mod = Face_Recognition() X_train, Y_train = mod.load_data_from_file('train10.txt') X_test, Y_test = mod.load_data_from_file('test10.txt') mod.ACP(X_train, Y_train) print(mod.evaluate(X_test, Y_test, K = 9)) mod.display_images(0,10) __main__()