Спектральная кластеризация, сегментация изображения и собственные векторы - PullRequest
4 голосов
/ 23 июля 2011

Основываясь на книге «Компьютерное видение современного подхода», стр. 425, я попытался использовать собственные векторы для сегментации изображения.

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

Автор упоминает, что аффиниты пикселей изображения могут быть захвачены в матрице А. Тогда мы можем максимизировать произведение 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 Ответ

2 голосов
/ 23 июля 2011

Я только что попробовал алгоритм в 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]]]
...