segunda-feira, 4 de abril de 2016

Eigenfaces - Implementação Final

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:










Nenhum comentário:

Postar um comentário