Main Content

낮은 랭크 SVD를 사용하여 이미지 압축하기

이 예제에서는 svdsketch를 사용하여 이미지를 압축하는 방법을 보여줍니다. svdsketch는 낮은 랭크 행렬 근삿값을 사용하여 이미지의 중요한 특징은 유지하고 덜 중요한 특징은 필터링합니다. svdsketch와 함께 사용된 허용오차의 크기가 증가할수록 더 많은 특징이 필터링되고 이미지의 세부 수준이 변경됩니다.

이미지 불러오기

도시 도로 사진인 street1.jpg 이미지를 불러옵니다. 이 이미지를 구성하는 3차원 행렬은 uint8형이므로 이미지를 회색조 행렬로 변환합니다. 원본 행렬의 랭크에 대한 주석을 포함해서 이미지를 봅니다.

A = imread('street1.jpg');
A = rgb2gray(A);
imshow(A)
title(['Original (',sprintf('Rank %d)',rank(double(A)))])

Figure contains an axes object. The axes object with title Original (Rank 480) contains an object of type image.

이미지 압축하기

svdsketch를 사용하여 허용오차 1e-2 내에서 A를 근사하는 낮은 랭크 행렬을 계산합니다. svdsketch에 의해 반환된 SVD 인수를 곱하여 낮은 랭크 행렬을 구성하고 결과를 uint8로 변환하고 결과 이미지를 봅니다.

[U1,S1,V1] = svdsketch(double(A),1e-2);
Anew1 = uint8(U1*S1*V1');
imshow(uint8(Anew1))
title(sprintf('Rank %d approximation',size(S1,1)))

Figure contains an axes object. The axes object with title Rank 288 approximation contains an object of type image.

svdsketch는 랭크 288 근사를 생성하며, 그 결과로 생성된 이미지의 경계선 일부가 다소 거칠어 보입니다.

이제 1e-1의 허용오차를 사용하여 이미지를 한 번 더 압축합니다. 허용오차의 크기가 증가할수록 svdsketch에 의해 생성된 근사의 랭크는 일반적으로 감소합니다.

[U2,S2,V2] = svdsketch(double(A),1e-1);
Anew2 = uint8(U2*S2*V2');
imshow(Anew2)
title(sprintf('Rank %d approximation',size(S2,1)))

Figure contains an axes object. The axes object with title Rank 48 approximation contains an object of type image.

이번에는 svdsketch가 랭크 48 근사를 생성합니다. 대부분의 이미지 특성은 여전히 표시되지만, 추가 압축으로 인해 흐릿함이 증가합니다.

부분공간 크기 제한하기

svdsketch는 지정된 허용오차를 기반으로 행렬 스케치에 사용할 랭크를 적응 방식으로 결정합니다. 그러나 MaxSubspaceDimension 이름-값 쌍을 사용하여 행렬 스케치를 형성하는 데 사용해야 할 최대 부분공간 크기를 지정할 수 있습니다. 이 옵션을 사용하면 허용오차를 충족하지 않는 행렬이 만들어질 수 있는데, 지정한 부분공간이 너무 작을 수도 있기 때문입니다. 이 경우 svdsketch는 허용되는 최대 부분공간 크기를 가진 행렬 스케치를 반환합니다.

허용오차가 1e-1이고 최대 부분공간 크기가 15인 svdsketch를 사용합니다. 상대 근사오차를 반환하도록 네 번째 출력을 지정합니다.

[U3,S3,V3,apxErr] = svdsketch(double(A),1e-1,'MaxSubspaceDimension',15);

결과의 상대 근사오차와 지정된 허용오차를 비교합니다. svdsketch는 답을 계산하는 데 1회 반복만 필요하므로 apxErr에는 하나의 요소가 포함되어 있습니다.

apxErr <= 1e-1
ans = logical
   0

결과를 보면 행렬 스케치가 지정된 허용오차를 충족하지 않음을 알 수 있습니다.

심하게 압축된 랭크 15 이미지를 봅니다.

Anew3 = uint8(U3*S3*V3');
imshow(Anew3)
title(sprintf('Rank %d approximation',size(S3,1)))

Figure contains an axes object. The axes object with title Rank 15 approximation contains an object of type image.

결과 비교하기

마지막으로, 비교를 위해 모든 이미지를 나란히 봅니다.

tiledlayout(2,2,'TileSpacing','Compact')
nexttile
imshow(A)
title('Original')
nexttile
imshow(Anew1)
title(sprintf('Rank %d approximation',size(S1,1)))
nexttile
imshow(Anew2)
title(sprintf('Rank %d approximation',size(S2,1)))
nexttile
imshow(Anew3)
title(sprintf('Rank %d approximation',size(S3,1)))

Figure contains 4 axes objects. Axes object 1 with title Original contains an object of type image. Axes object 2 with title Rank 288 approximation contains an object of type image. Axes object 3 with title Rank 48 approximation contains an object of type image. Axes object 4 with title Rank 15 approximation contains an object of type image.

참고 항목

| |

관련 항목