代码之家  ›  专栏  ›  技术社区  ›  Arnkrishn

基于OpenCV的特征向量计算

  •  13
  • Arnkrishn  · 技术社区  · 16 年前

    10 x 10 形象。在这种情况下,矩阵A是维数的 100 x 100 元素A(i,j)的值在0到1的范围内,表示像素i到j在强度方面的相似性。

    我使用OpenCV进行图像处理,开发环境是Linux上的C。

    目标是计算矩阵A的特征向量,我使用了以下方法:

    static CvMat mat, *eigenVec, *eigenVal;
    static double A[100][100]={}, Ain1D[10000]={};
    int cnt=0;
    
    //Converting matrix A into a one dimensional array
    //Reason: That is how cvMat requires it
    for(i = 0;i < affnDim;i++){
      for(j = 0;j < affnDim;j++){
     Ain1D[cnt++] = A[i][j];
      }
    }
    
    mat = cvMat(100, 100, CV_32FC1, Ain1D); 
    
    cvEigenVV(&mat, eigenVec, eigenVal, 1e-300);
    
    for(i=0;i < 100;i++){
      val1 = cvmGet(eigenVal,i,0); //Fetching Eigen Value
    
      for(j=0;j < 100;j++){   
     matX[i][j] = cvmGet(eigenVec,i,j); //Fetching each component of Eigenvector i    
      }
    }
    

    问题: 执行之后,我得到几乎所有特征向量的所有分量都为零。我尝试了不同的图像,也尝试了用0到1之间的随机值填充A,但结果相同。

    9805401476911479666115491135488.000000  
    -9805401476911479666115491135488.000000  
    -89222871725331592641813413888.000000  
    89222862280598626902522986496.000000  
    5255391142666987110400.000000
    

    我现在正在考虑使用 cvSVD() 它执行实浮点矩阵的奇异值分解,并可能生成特征向量。但在此之前,我想在这里问一下。我目前的做法有什么荒谬之处吗?我是否使用了正确的API,即。 cvEigenVV() 对于正确的输入矩阵(我的矩阵A是浮点矩阵)?

    干杯

    3 回复  |  直到 16 年前
        1
  •  10
  •   Amro    12 年前

    读者注意:这篇文章起初似乎与主题无关,但请参考上面评论中的讨论。

    以下是我在实现 Spectral Clustering MATLAB . 我完全按照计划行事 paper @Andriyev提到:

    在T.Dieterich、S.Becker和Z.Ghahramani(编辑)中, 神经信息处理系统的进展14。麻省理工学院出版社

    守则:

    %# parameters to tune
    SIGMA = 2e-3;       %# controls Gaussian kernel width
    NUM_CLUSTERS = 4;   %# specify number of clusters
    
    %% Loading and preparing a sample image
    %# read RGB image, and make it smaller for fast processing
    I0 = im2double(imread('house.png'));
    I0 = imresize(I0, 0.1);
    [r,c,~] = size(I0);
    
    %# reshape into one row per-pixel: r*c-by-3
    %# (with pixels traversed in columwise-order)
    I = reshape(I0, [r*c 3]);
    
    %% 1) Compute affinity matrix
    %# for each pair of pixels, apply a Gaussian kernel
    %# to obtain a measure of similarity
    A = exp(-SIGMA * squareform(pdist(I,'euclidean')).^2);
    
    %# and we plot the matrix obtained
    imagesc(A)
    axis xy; colorbar; colormap(hot)
    
    %% 2) Compute the Laplacian matrix L
    D = diag( 1 ./ sqrt(sum(A,2)) );
    L = D*A*D;
    
    %% 3) perform an eigen decomposition of the laplacian marix L
    [V,d] = eig(L);
    
    %# Sort the eigenvalues and the eigenvectors in descending order.
    [d,order] = sort(real(diag(d)), 'descend');
    V = V(:,order);
    
    %# kepp only the largest k eigenvectors
    %# In this case 4 vectors are enough to explain 99.999% of the variance
    NUM_VECTORS = sum(cumsum(d)./sum(d) < 0.99999) + 1;
    V = V(:, 1:NUM_VECTORS);
    
    %% 4) renormalize rows of V to unit length
    VV = bsxfun(@rdivide, V, sqrt(sum(V.^2,2)));
    
    %% 5) cluster rows of VV using K-Means
    opts = statset('MaxIter',100, 'Display','iter');
    [clustIDX,clusters] = kmeans(VV, NUM_CLUSTERS, 'options',opts, ...
        'distance','sqEuclidean', 'EmptyAction','singleton');
    
    %% 6) assign pixels to cluster and show the results
    %# assign for each pixel the color of the cluster it belongs to
    clr = lines(NUM_CLUSTERS);
    J = reshape(clr(clustIDX,:), [r c 3]);
    
    %# show results
    figure('Name',sprintf('Clustering into K=%d clusters',NUM_CLUSTERS))
    subplot(121), imshow(I0), title('original image')
    subplot(122), imshow(J), title({'clustered pixels' '(color-coded classes)'})
    

    ... 我用油漆画了一个简单的房子图像,结果是:

    laplacian matrix image clustered

    顺便说一下,使用的前4个特征值是:

    1.0000
    0.0014
    0.0004
    0.0002
    

    以及相应的特征向量[长度为r*c=400的列]:

    -0.0500    0.0572   -0.0112   -0.0200
    -0.0500    0.0553    0.0275    0.0135
    -0.0500    0.0560    0.0130    0.0009
    -0.0500    0.0572   -0.0122   -0.0209
    -0.0500    0.0570   -0.0101   -0.0191
    -0.0500    0.0562   -0.0094   -0.0184
    ......
    

    请注意,您在问题中没有提到上面执行的步骤(拉普拉斯矩阵,并规范化其行)

        2
  •  1
  •   Janusz Daniel Rindt    16 年前

    article . 作者实现了特征脸的人脸识别。在第4页,您可以看到他使用CVCalceiGenoObjects从图像生成特征向量。文中给出了计算所需的整个预处理步骤。

        3
  •  1
  •   High Performance Mark    16 年前

    理论(或涂在纸上的数学)告诉你特征向量应该是什么?大约。

    另一个库告诉你特征向量应该是什么?理想情况下,像Mathematica或Maple这样的系统(可以被说服以任意精度计算)告诉你特征向量应该是什么?如果不是针对生产问题,至少针对测试规模的问题。

    我不是一个图像处理专家,所以我帮不了多少忙,但我花了很多时间和科学家在一起,经验告诉我,通过先做一些数学运算,在想为什么你会得到满地0之前,对应该得到的结果形成预期,可以避免很多眼泪和愤怒。当然,这可能是算法实现中的错误,也可能是精度损失或其他数值问题。但你还不知道,也不应该跟进这些调查。

    当做