低秩近似法與影像壓縮
撰寫時間 : 2021/09/01
大綱
我的報告內容為SVD與資料分析這門課上課內容的整理與延伸 - 低秩近似法。第一部分是數學理論,這是教授在第三天的上課內容;第二部分Matlab實踐是將第一部分的數學理論轉換為Matlab程式碼,在教授提供原文書程式碼的基礎之上,我另外加上奇異值大小分布作圖,相對誤差計算與作圖,與壓縮RGB影像 - 將R、G、B三色分離圖層個別做SVD分解並轉換為秩數較低的矩陣,最後再將合併R、G、B三色圖層即可得到壓縮後的RGB影像。
數學理論
矩陣的Frobenius norm與Spectral norm
在討論低秩近似法前,我們要找到如何代表兩矩陣"長得很像"的衡量標準?直覺來說就是找兩矩陣的"長度","長度"講為較專業的術語就是範數(norm),norm符合兩個性質,一是除了零矩陣的norm等於0,其他矩陣的norm必定大於0,二是符合三角不等式,norm在定義上百百種,這邊只討論2種norm
- Frobenius norm
將矩陣所有的entries平方相加最後開根號。
經推導,在原矩陣右邊或是左邊乘上正交矩陣,不改變Frobenius norm,因此Frobenius norm即為將做SVD分解中所有奇異值平方相加開根號。
- Spectral norm / two norm
線性變換前後向量長度的比例,取其中的最大值。另一種看法,可令就是在單位圓上做線性轉換後得到橢圓等形狀,取其離原點最大的長度。
經推導,Spectral norm為將做SVD分解中最大的奇異值。
SVD的外積展開式與低秩近似法
SVD分解中數值只由前項column vector,前的方陣決定,前項row vector所決定。因此若資料以SVD形式儲存,可進一步簡化為reduced SVD。
由第2天計算SVD步驟可知,欲求正交矩陣,是把單位正交集合(set)擴展到單位正交基底(basis),實際上擴展哪些基底不重要,也不具有唯一性,只是為了要讓的行向量單位正交而形成正交矩陣而已。
如此就可以定義SVD的前項外積展開式,取前將奇異值一一取出展開
其秩數,根據Eckart-Young Theorem,在同一秩數下,最接近原本矩陣的距離就是前項外積展開式,這就是低秩近似法(low-rank approximation)最佳化的問題。
因此在同一秩數下,最靠近的矩陣就是前項外積展開式。
最後就可計算相對誤差的最小值
Matlab程式實踐
給定輸入圖片lycoris_recoil.jpg
。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
首先讀取圖檔,並用指令imfinfo()
查看圖檔資訊為像素,位元深度(bit depth)為24位元,色型為true color,代表有3條通道(channel)分別為紅、綠、藍,每一條通道的位元深度為8位元。而圖片預設儲存的資料型態為無號(unsigned) 8位元整數(uint8
),在計算機運算時,將其轉換為雙精度浮點數運算(double
)。由於指令imshow
要顯示true color影像,若是資料型態是浮點數則數值限制在,因此除上,將映射至。
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
將true color影像的R、G、B通道分解,也就是把3維矩陣降至3個2維矩陣
需要注意灰階影像顯示時,預設數值範圍是,因此在指令imshow
後面要給與要對應灰階的範圍更改為。
分別對矩陣做SVD分解為的形式。
%% plot of sigular value
sigular_value_number = min(size(S1));
x_axis = 1:sigular_value_number;
sigular_value_1 = zeros(1, length(x_axis));
sigular_value_2 = zeros(1, length(x_axis));
sigular_value_3 = zeros(1, length(x_axis));
for i = 1:sigular_value_number % take diagonal entries
sigular_value_1(1,i) = S1(i,i);
sigular_value_2(1,i) = S2(i,i);
sigular_value_3(1,i) = S3(i,i);
end
subplot(3,1,1);
semilogy(x_axis, sigular_value_1, 'LineWidth',2);
title(['sigualr value $\sigma_i$ of $\mathbf{R}$ for i = 1, 2, ...', num2str(sigular_value_number)],'interpreter','latex','FontSize',15);
xlabel('i-axis','FontSize',10);
ylabel('sigualr value \sigma_i','FontSize',10);
grid on
subplot(3,1,2);
semilogy(x_axis, sigular_value_2, 'LineWidth',2);
title(['sigualr value $\sigma_i$ of $\mathbf{G}$ for i = 1, 2, ...', num2str(sigular_value_number)],'interpreter','latex','FontSize',15);
xlabel('i-axis','FontSize',10);
ylabel('sigualr value \sigma_i','FontSize',10);
grid on
subplot(3,1,3);
semilogy(x_axis, sigular_value_3, 'LineWidth',2);
title(['sigualr value $\sigma_i$ of $\mathbf{B}$ for i = 1, 2, ...', num2str(sigular_value_number)],'interpreter','latex','FontSize',15);
xlabel('i-axis','FontSize',10);
ylabel('sigualr value \sigma_i','FontSize',10);
grid on
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
矩陣的奇異值數值對index 作圖,可以發現以此張圖來說,R、G、B圖層的奇異值分布類似;需要注意數值是對數作圖,因此奇異值大小變化量劇烈,代表取足夠前項的SVD的外積展開式,就幾乎可以涵蓋整張圖的所有資訊
%% minimal relative rate of error
subplot(3,1,1);
error_1 = sigular_value_1(2:end) / S1(1,1);
semilogy(x_axis(1:end-1), error_1, 'LineWidth',2);
title('relative rate of error $\frac{\| \mathbf{R} - \mathbf{R}_k \|_2}{\| \mathbf{R} \|_2} = \frac{\sigma_{k + 1}}{\sigma_1}$','interpreter','latex','FontSize',15);
xlabel('k-axis','FontSize',10);
ylabel('A_k error','FontSize',10);
grid on
subplot(3,1,2);
error_2 = sigular_value_2(2:end) / S2(1,1);
semilogy(x_axis(1:end-1), error_2, 'LineWidth',2);
title('relative rate of error $\frac{\| \mathbf{G} - \mathbf{G}_k \|_2}{\| \mathbf{G} \|_2} = \frac{\sigma_{k + 1}}{\sigma_1}$','interpreter','latex','FontSize',15);
xlabel('k-axis','FontSize',10);
ylabel('A_k error','FontSize',10);
grid on
subplot(3,1,3);
error_3 = sigular_value_3(2:end) / S3(1,1);
semilogy(x_axis(1:end-1), error_3, 'LineWidth',2);
title('relative rate of error $\frac{\| \mathbf{B} - \mathbf{B}_k \|_2}{\| \mathbf{B} \|_2} = \frac{\sigma_{k + 1}}{\sigma_1}$','interpreter','latex','FontSize',15);
xlabel('k-axis','FontSize',10);
ylabel('A_k error','FontSize',10);
grid on
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
至於這個項要取多少?根據前面數學理論中矩陣之間的"距離"這個概念,在此使用norm的其中一種定義 - 2-norm來求得相對誤差值。
我選擇把R、G、B的相對誤差都限制在以內,因此選擇,此時R、G、B誤差為

最後合併壓縮後的矩陣回原來的影像。可以發現原本原本的矩陣,現在只需要取,使矩陣秩數只要,就可以看出原本影像大部分的特徵。

把R、G、B壓縮影像印出來,看個別R、G、B圖層壓縮的效果。
%% comparison of different rank k
sgtitle('SVD application - low rank approximation $\mathbf{A}_k = \mathbf{U}_k\mathbf{\Sigma}_k\mathbf{V}_k^T$','interpreter','latex','FontSize',20);
k = [5,10,50,100, 200]; % number of singlular values
for i = 1:length(k)
S_re_1 = zeros(size_A(1),size_A(2));
S_re_2 = zeros(size_A(1),size_A(2));
S_re_3 = zeros(size_A(1),size_A(2));
for ir = 1:k(i)
S_re_1(ir,ir) = S1(ir,ir); % compress red layer of image
S_re_2(ir,ir) = S2(ir,ir); % compress green layer of image
S_re_3(ir,ir) = S3(ir,ir); % compress blue layer of image
end
A_re_1 = U1*S_re_1*V1';
A_re_2 = U2*S_re_2*V2';
A_re_3 = U3*S_re_3*V3';
A_re = uint8(zeros(size_A(1), size_A(2), size_A(3)));
A_re(:,:,1) = uint8(A_re_1);
A_re(:,:,2) = uint8(A_re_2);
A_re(:,:,3) = uint8(A_re_3);
subplot(2,3,i);
imshow(A_re);
title(['$\mathrm{rank}(\mathbf{A}_k) =$ ',num2str(k(i))],'interpreter','latex','FontSize',15);
end
subplot(2,3,6);
imshow(cal_data/255);
title(['original image with ',num2str(size_A(2)),'$\times$',num2str(size_A(1)),' pixels'],'interpreter','latex','FontSize',15);

最後寫一個for loop
,觀察取不同,也就是不同的秩數下所得到的效果,可以發現在,以目前這種顯示比例,跟原圖比較幾乎看不出有什麼區別,幾乎能保留影像大部分的特徵,而使用秩數較低的矩陣同時又能減少大量資料儲存,這就是low rank approximation在影像壓縮的應用與意義。