0

我正在学习http://jeremykun.com/2011/07/27/eigenfaces/上的教程。我正在尝试使用 Jama Linear Algebra 包在 Java 中实现此解决方案。

我一直在计算协方差矩阵。我计算了所有的差异向量并将它们分别存储在一个“矩阵”中。但是,我看不到如何将这些转换为协方差矩阵。

我如何最好地在 Java 中做到这一点?

4

3 回答 3

1

你缺少的是

在此处输入图像描述

计算如下:

在此处输入图像描述

这意味着您现在只需要两件事:

  • 将差分向量矩阵相乘(与平均值的偏差)

  • 将结果乘以 1 / (N - 1),注意:N - 1 从样本中获得无偏估计


我已经创建了这个电子表格示例来展示如何一步一步地做到这一点。

于 2014-03-14T11:38:58.857 回答
0

Alternatively, you can use, after removing the average, the SVD function, which is also contained in Jama.

The eigen decomposition computes W'*W=V*D*V', while the SVD computes W=U*S*V', U, V orthogonal, S and D diagonal, with the diagonal non-negative and descending order. Comparing both, one gets

W'*W=(USV')'*USV'=VSU'*USV'=VS²V'

so one can recover the eigen decomposition from the SVD via D=S².

于 2014-03-14T11:34:56.447 回答
0

你可以做这样的事情(处理我正在导入 jama 的矩阵)。实际上特征脸是在下面实现的,因为这个函数对于java有问题。

private static void evaluateEigenface(int M,int N,Matrix x,double[] average,double[] eigenvalues,Matrix eigenfaces){

        // x is (widthProcessedImage*heightProcessedImage)X(numberProcessedImages);

        Matrix w=new Matrix(M,N,0.0);

        for(int i=0;i<M;i++){
            average[i]=0;
            for(int j=0;j<N;j++){
                average[i]=average[i]+x.get(i,j);
            }
            average[i]=average[i]/((double)N);
            //System.out.println(average[i]);
        }


        for(int i=0;i<M;i++){
            for(int j=0;j<N;j++){
                w.set(i, j, x.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'

        for(int i=0;i<N;i++)eigenvalues[i]=mu[i];

        double theNorm;
        double[] auxArray=new double[M];
        for(int i=0;i<N;i++){
            for(int j=0;j<M;j++)auxArray[j]=e.get(j,i);
            theNorm=norma2(M,auxArray);
            for(int j=0;j<M;j++)eigenfaces.set(j,i, e.get(j, i)/theNorm); // eigenfaces are the normalized eigenvectors of ww'
        }

    }
于 2014-03-14T10:39:31.900 回答