2016-12-19 7 views
-1

이미지의 svd를 찾는 코드를 만들려고합니다. 우리는 실제로 svd() 함수를 사용할 수 없습니다. 가깝지만 정확한 대답은 얻을 수 없었습니다. 내 대답을 SVD 함수의 결과와 비교하고 중간 행렬이 완벽하지만 왼쪽 및 오른쪽 행렬에있는 일부 부호가 뒤집혀 있습니다. 또한 SVD를 사용하여 이미지를 다시 표시하려고하면 원래 그림의 낮은 순위 근사처럼 보입니다.Matlab의 단일 값 분해가 약간 흐림

기본적으로 eig()를 사용하여 A 의 Aigenvalues ​​및 Eigenvector를 가져오고 Accranspose 및 Atranspose A를 입력 한 다음 가장 큰 것부터 작은 것으로 순서를 바꿉니다. 지금까지 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