前两个主要组成部分是相反的

时间:2017-12-14 19:10:34

标签: python image-processing geometry pca

我正在尝试在python中计算图像的PCA using this code by Alyssa

# Read the image into palmFingers_mask:  
# we use PCA and otain 2 principal components
y, x = np.nonzero(palmFingers_mask)
# Subtract mean from each dimension
x = x - np.mean(x)
y = y - np.mean(y)
coords = np.vstack([x, y]) 
# Covariance matrix and its eigenvectors and eigenvalues
cov = np.cov(coords)
evals[:,frm_cnt], evecs = np.linalg.eig(cov)
# Sort eigenvalues in decreasing order
sort_indices = np.argsort(evals[:,frm_cnt])[::-1]
evec1[:,frm_cnt], evec2[:,frm_cnt] = evecs[:, sort_indices]
x_v1, y_v1 = evec1[:,frm_cnt]  # Eigenvector with largest eigenvalue
x_v2, y_v2 = evec2[:,frm_cnt]
# Plot the principal components
scale = 20
plt.figure(1)
plt.plot(x, y, 'y.')
plt.plot([x_v1*-scale*2, x_v1*scale*2],
                 [y_v1*-scale*2, y_v1*scale*2], color='red')
plt.plot([x_v2*-scale, x_v2*scale],
                 [y_v2*-scale, y_v2*scale], color='blue')
plt.axis('equal')
plt.gca().invert_yaxis()  # Match the image system with origin at top left
plt.show()

我用红线和蓝线标记两个轴(红色是较大的组件,线的长度不表示任何东西)。

在这样做时,我遇到了一个错误的案例,如下所示:

enter image description here

怎么可能?这描绘了红色特征向量更大,但直观地说,不应该是这种情况。轴(沿蓝线)应该是较大的轴,对吗?对于我数据库中的所有其他图像,我看到轴是正确的。仅对于此图像,它是互换的;我附上了输入图像(Img 209.png)

我的理解有什么不对吗?

这就是我的期望:

enter image description here

例如,我已经附加了BinImg_20.png,但它的工作原理。

Attached files are on Dropbox

1 个答案:

答案 0 :(得分:2)

我想问题就在这里:

evec1, evec2 = evecs[:, sort_indices]

此时你有

evecs = [[ 0.70926191  0.70494507]
         [-0.70494507  0.70926191]]
evec1 = [ 0.70926191  0.70494507]
evec2 = [-0.70494507  0.70926191]

sort_indices编制索引可正确排序。但是解包分配然后通过解包,导致你观察到的错误。

另见the documentation for numpy.linalg.eig,其中说明:

  

v :( ...,M,M)数组 - 标准化(单位“长度”)特征向量,使得列v[:,i]是对应于特征值{{1}的特征向量}。

tutorial写道:

  多维数组的

迭代是针对第一轴完成的

我在R中做了一些交叉检查,以确保这样的计算是理智的,并且特征向量就像你期望的那样。如果您感兴趣,这里是输入和输出,中心偏离1,因为R执行基于1的索引。

w[i]

此处,> install.packages("pixmap") > library(pixmap) > pix <- read.pnm("BinImg_209.pbm") > mask = which(pix@grey != 0, arr.ind=T) > mask = data.frame(x=mask[,"col"], y=mask[,"row"]) > prcomp(mask) # single step principal component analysis Standard deviations (1, .., p=2): [1] 117.84952 44.23114 Rotation (n x k) = (2 x 2): PC1 PC2 x 0.7092619 0.7049451 y -0.7049451 0.7092619 > cov <- cov.wt(mask) # manual covariance computation > cov # show computed data $cov x y x 7958.874 -5965.947 y -5965.947 7886.030 $center x y 593.1907 519.1019 $n.obs [1] 47909 > eigen(cov$cov) # manual computation of eigenvectors eigen() decomposition $values [1] 13888.510 1956.394 $vectors [,1] [,2] [1,] -0.7092619 -0.7049451 [2,] 0.7049451 -0.7092619 矩阵的也是特征向量。 vectors中的旋转矩阵标记更清晰:列是主要成分,行是原始坐标。