谱聚类,图像分割和特征向量

时间:2011-07-23 08:02:17

标签: python image-processing linear-algebra image-segmentation

基于“计算机视觉与现代方法”一书第425页,我尝试使用特征向量进行图像分割。

http://dl.dropbox.com/u/1570604/tmp/comp-vis-modern-segment.pdf

作者提到图像像素亲缘关系可以在矩阵A中捕获。然后我们可以最大化w ^ T A w产品,其中w是权重。在一些代数得到Aw = \ lambda w之后,找到w就像找到特征向量一样。然后找到最佳聚类是找到具有最大特征向量的特征值,该特征向量内的值是聚类成员资格值。我写了这段代码

import matplotlib.pyplot as plt
import numpy as np

Img = plt.imread("twoObj.jpg")
(n,dummy) = Img.shape
Img2 = Img.flatten()
(nn,) = Img2.shape

A = np.zeros((nn,nn))

for i in range(nn):
    for j in range(nn):
        N=Img2[i]-Img2[j];
        A[i,j]=np.exp(-(N**2))

V,D = np.linalg.eig(A)
V = np.real(V)
a = np.real(D[1])

threshold = 1e-10 # filter
a = np.reshape(a, (n,n))
Img[a<threshold] = 255
plt.imshow(Img)
plt.show()

图片

enter image description here

我可以从中获得的最佳结果如下。我有一种感觉,结果会更好。

特征值在Numpy中从大到小排序,我尝试了第一个,但没有用,然后我尝试了第二个用于下面看到的结果。通过反复试验选择阈值。关于如何改进这种算法的任何想法?

enter image description here

1 个答案:

答案 0 :(得分:2)

我刚刚在Mathematica中尝试过该算法,它在您的图像上运行良好,因此您的代码中必定存在一个微妙的错误。

这部分:

V,D = np.linalg.eig(A)
V = np.real(V)
res = n_max(V,1) # take largest 
idx = res[0][1][0] 
a = np.real(D[idx]) # look at corresp eigv

看起来很奇怪:我知道的所有线性代数包都会返回排序的特征值/特征向量,所以你只需要在列表中取第一个特征向量。这是对应于最高特征值的那个。尝试绘制特征值列表以确认。

另外,你从哪里获得固定门槛?您是否尝试过将图像标准化以显示它?

对于它的价值,我得到的前3个特征向量的结果是:

Eigenvector1 Eigenvector2 Eigenvector3

这是我使用的Mathematica代码:

pixels = Flatten[image];
weights = Table[N[Exp[-(pixels[[i]] - pixels[[j]])^2]], {i, 1, 900}, {j, 1, 900}];
eigenVectors = Eigenvectors[weights];
ImageAdjust[Image[Partition[eigenVectors[[1]], 30]]]