2016-12-19 28 views
-1

Я пытаюсь создать код, который находит SVD изображения. Нам не разрешено фактически использовать функцию svd(). Мне удалось получить ответ, близкий, но не точный. Я сравниваю свои ответы с результатом функции SVD, и моя средняя матрица идеальна, но некоторые знаки на левой и правой матрицах перевернуты. Также, если я попытаюсь снова отобразить изображение, используя мой SVD, он выглядит как приближение низкого ранга исходного изображения.Одиночная декомпозиция в Matlab немного отключена

В основном то, что я делаю с помощью EiG() принимать собственные значения и собственные векторы Atranspose и Atranspose А, а затем переназначения их от самых больших до самых маленьких. Насколько я понимаю, eig() ставит их в порядок от самого маленького к самому большому, поэтому я просто использовал функцию fliplr для замены порядка.

Я не страшно переживаю с Matlab, поэтому я могу совершить глупую ошибку. Я попытался удалить функцию fliplr, но я все еще получаю то, что, похоже, является одним и тем же собственным вектором, и изображение все еще выходит неправильно. Вот код, который я использую. Есть ли еще одна ошибка, которую я делаю?

A = imread('picture.jpg'); 
A2 = double(rgb2gray(A)); 
AT = transpose(A2); 
sz = size(A2); 
m = sz(1); 
n = sz(2); 
AAT = A2*AT; 
ATA = AT*A2; 
evalues = eig(AAT); 
evalues = sort(evalues,'descend'); 
S = diag(evalues); 
S(m,n) = 0; 
S=S.^(.5); 

[v1,e1]=eig(AAT); 
e1 = diag(e1); 
[~, ind] = sort(abs(e1), 'descend'); 
v1 = v1(:, ind); 

[v2,e2]=eig(ATA); 
e2 = diag(e2); 
[~, ind] = sort(abs(e2), 'descend'); 
v2 = v2(:, ind); 


final = v1*S*transpose(v2); 
final = uint8(final); 
imshow(final); 

ответ

2

Помните, что собственные значения и собственные векторы не являются уникальными. Если они масштабируются по-разному, они также являются собственным значением/собственным вектором. Тот факт, что знаки перевернуты, не должно быть тревожным. Однако критическая ошибка, которую вы предположили, состоит в том, что eig возвращает собственные значения и собственные векторы от наименьшего до наибольшего. Нигде в документации eig не говорится о заказе. Фактически, порядок полностью случайный, поэтому fliplr на самом деле не совсем то, что нужно сделать. Что вам нужно сделать, это sort на основе величины собственных значений, так что вы на самом деле нужно сделать что-то вроде этого, предполагая, что матрица вы хотите отсортировать является A:

[V, D] = eig(A); 
D = diag(D); 
[~, ind] = sort(abs(D), 'descend'); 
V = V(:, ind); 

Это имеет матрицу собственных векторов и должным образом перестраивает столбцы, так что наибольший собственный вектор самого собственного значения появляется в первом столбце и затем идет в порядке убывания.

В любом случае, левая и правая матрицы в конечном счете являются собственными векторами, которые помещаются в столбцы матрицы. Пока вы видите, что A = U*S*V, тогда вы должны быть в порядке по большей части. Я не могу определить, действительно ли вы реализуете SVD, так как вы не прикрепляли никакого кода, поэтому эту обратную связь я не могу предоставить вам, но из звуков вашего вопроса кажется, что все в порядке.

+0

Я пробовал это точно так же, как вы сказали, но я все еще получаю то же изображение. – Tortellini