1. 程式人生 > >利用矩陣奇異值分解對影象進行壓縮

利用矩陣奇異值分解對影象進行壓縮

最近學習線性代數的有關東西,在看到奇異值分解(svd)時,發現了一個在影象壓縮上的應用。

奇異值分解:線上性代數中,我們知道對任意一個矩陣都存在奇異值分解,,其中UV是標準正交矩陣,而是一個對角矩陣,每一個對角元是該矩陣的奇異值,奇異值指的是矩陣的特徵值開根號。其具體分解形式如下:

其中

A展開得

A看成一個影象的矩陣,上面和式的每一個分量按大小排序,越大,說明越重要。而後面的權很小,可以捨去,如果只取前面k項,則資料量為(m+n+1)k<<m*n因而達到了壓縮影象的目的。

通過對比發現,當k=1/20 r時,能基本看清影象。當k=1/4r時基本看不出任何區別,對於長寬相等的影象,此時資料量佔原資料量的

2k/n,在測試影象中,這個數值為0.5 。可見影象壓縮的效果是顯著的。

處理結果如下:

原始影象:

k=1:

k=2:

k=3:

k=4:

k=21:

k=50:

k=105:

k=r=420:

matlab測試程式碼:

SNum = 21;

I = imread('img.bmp');

h = size(I,1);

w = size(I,2);

R = I(:,:,1);

G = I(:,:,2);

B = I(:,:,3);

debug = 'RGB disposed'

Rd = im2double(R);

Gd = im2double(G);

Bd = im2double(B);

[Ur,Sr,Vr] = svd(Rd);

[Ug,Sg,Vg] = svd(Gd);

[Ub,Sb,Vb] = svd(Bd);

debug = 'end SVD decomposition'

Rt = zeros(h,w);

Gt = zeros(h,w);

Bt = zeros(h,w);

for i = 1:SNum

    Rt = Rt + Sr(i,i)*Ur(:,i)*Vr(:,i)';

    Gt = Gt + Sg(i,i)*Ug(:,i)*Vg(:,i)';

    Bt = Bt + Sb(i,i)*Ub(:,i)*Vb(:,i)';

end

I2(:,:,1) = im2uint8(Rt);

I2(:,:,2) = im2uint8(Gt);

I2(:,:,3) = im2uint8(Bt);

imshow(I2);