Eigenfaces procura implementar um sistema capaz, eficiente, simples e com acurácia para reconhecimento facial. O sistema não depende de conhecimento intuitivo da estrutura da face, como por exemplo olhos, nariz e boca. A motivação por trás do Eigenfaces é que trabalhos anteriores ignoram a questão de quais características são importante para a classificação ou não. O Eigenfaces procura essa resposta usando PCA das imangens dos rostos. Essa análise reduz a dimensionalidade do conjunto de teste deixando apenas as carecterísticas que são críticas para o reconhecimento facial.
Esse sistema é inicializado por uma base de treinamento, que idealmente tem que ter um número variado de exemplos com variação de luz e expressões. Eigenvectors e eigenvalues são computados pela matriz de convariância da base de treinamento. Os M maiores eigenvectors são mantidos. Finalmente, os indivíduos conhecidos são projetados dentro de um espaço vetorial, e seus pesos são armazenados.
O Eigenfaces que foi implementado por mim, foi implementado em Java e foi testado com oito imagens. O método mais importante da minha implementação está abaixo:
/** Cálculo do eigenfaces usando uma técnica matemática para facilitar o cálculo do eigenfaces com alta
* dimensionalidade. Ao fim do método os eigenfaces são visualizados em imagens
**/
public void eigenfacesImplementation(ArrayList<double[]> dados){
double[][] auxDados= arrayListToDouble(dados);
Matrix dadosMatrix = new Matrix(auxDados);
Matrix w=new Matrix(dados.get(0).length, dados.size(), 0.0);
double[] average = new double[dados.get(0).length];
for(int i = 0; i < dados.get(0).length; i++){
average[i]=0;
for(int j = 0; j < dados.size(); j++){
average[i] = average[i] + dadosMatrix.get(i,j);
}
average[i]=average[i]/((double)dados.size());
//System.out.println(average[i]);
}
for(int i=0;i<dados.get(0).length;i++){
for(int j=0;j<dados.size();j++){
w.set(i, j, dadosMatrix.get(i,j) - average[i]);
}
}
Matrix auxMat = w.transpose().times(w); // = w'*w
SingularValueDecomposition SVD = new SingularValueDecomposition(auxMat);
double[] mu = SVD.getSingularValues(); // Eigenvalues of w'w
Matrix d=SVD.getU(); // LeftSingularVectors of w'w => Each column is an eigenvector
Matrix e=w.times(d); // Eigenvector of ww'
Matrix eigenfaces = new Matrix(w.getRowDimension(), w.getColumnDimension(), 0.0);
double[] auxArray=new double[w.getRowDimension()];
for(int i = 0; i < w.getColumnDimension(); i++){
for(int j = 0; j < w.getRowDimension(); j++) auxArray[j] = e.get(j, i);
Matrix eNormalized = normalize(e);
for(int j = 0;j < w.getRowDimension(); j++) eigenfaces.set(j,i, eNormalized.get(j, i)); // eigenfaces are the normalized eigenvectors of ww'
}
/** SALVANDO EIGENFACES COMO IMAGENS **/
double[][] teste = eigenfaces.getArray();
double[] min = new double[teste[0].length];
double[] max = new double[teste[0].length];
for(int i = 0; i < min.length; i++){
min[i] = Double.MAX_VALUE;
max[i] = 0;
}
for(int i = 0; i < teste[0].length; i++){
for(int j = 0; j < teste.length; j++){
if(min[i] > teste[j][i])
min[i] = teste[j][i];
if(max[i] < teste[j][i])
max[i] = teste[j][i];
}
}
for(int i = 0; i < teste[0].length; i++){
for(int j = 0; j < teste.length; j++){
teste[j][i] = ((teste[j][i] - min[i])/(max[i] - min[i])) * 255;
}
}
int[][][] imagem = new int[teste[0].length][width][height];
for(int i = 0; i < teste[0].length; i++){
int index = 0;
for(int j = 0; j < width; j++){
for(int k = 0; k < height; k++){
imagem[i][j][k] = (int) teste[index][i]; //olhar isso
index++;
}
}
}
salvarImagem(imagem[0], "extra/imagem_final_1.png");
salvarImagem(imagem[1], "extra/imagem_final_2.png");
salvarImagem(imagem[2], "extra/imagem_final_3.png");
salvarImagem(imagem[3], "extra/imagem_final_4.png");
salvarImagem(imagem[4], "extra/imagem_final_5.png");
salvarImagem(imagem[0], "extra/imagem_final_6.png");
salvarImagem(imagem[1], "extra/imagem_final_7.png");
salvarImagem(imagem[2], "extra/imagem_final_8.png");
salvarImagem(imagem[3], "extra/imagem_final_9.png");
}
e as imagens obtidas por esse método são:






















