2013-03-13 88 views
1

我正在使用奇异值分解技术进行图像压缩。 我在Matlab中为它编写代码。我压缩了一个文件大小为8.15KB的图像(255 * 255 * 3)。当我保存压缩图像(以jpg格式)时,其文件大小超过原始图像文件大小。如何在MATLAB中保存压缩图像

B=imread('lena.jpg'); 

figure, 
imshow(B), title(sprintf('size=%d',numel(B))) // displaying the original image 


A=im2double(B); 

A1=A(:,:,1); 

A2=A(:,:,2); 

A3=A(:,:,3); 

tic; 


// applying svd for each layer 

[U1,S1,V1]=svd(A1); 

[U2,S2,V2]=svd(A2); 

[U3,S3,V3]=svd(A3); 

// reconstuctin compressed image 


p=100; 

U1p=U1(:,1:p); 

V1p=V1(:,1:p); 

S1p=diag(S1(1:p,1:p)); 

C1=U1p * diag(S1p) * V1p'; 

C1=255*C1; 

C1=uint8(C1); 

U2p=U2(:,1:p); 

V2p=V2(:,1:p); 

S2p=diag(S2(1:p,1:p)); 

C2=U2p * diag(S2p) * V2p'; 

C2=255*C2; 

C2=uint8(C2); 

U3p=U3(:,1:p); 

V3p=V3(:,1:p); 

S3p=diag(S3(1:p,1:p)); 

C3=U3p * diag(S3p) * V3p'; 

C3=255*C3; 

C3=uint8(C3); 

Q(:,:,1)=C1; 

Q(:,:,2)=C2; 

Q(:,:,3)=C3; 


// finding size and error of the compressed image 

sz = (3*(numel(U1p) + numel(V1p) + numel(S1p))); 

err = mean(abs(B(:)-Q(:))); 

toc; 
t=toc; 

// displying the compressed image 

figure, 
imshow(Q) 

title(sprintf('p=%d, size=%d,err=%d', p, sz,err)); 

请帮助我如何保存压缩文件。

+4

如果您使用SVD减少文件大小,只保留保留的奇异值和左右特征向量。不要重建图像并保存,这是毫无意义的。 – abcd 2013-03-13 05:06:03

+0

我想我只是在我的代码中建议的。 – user59489 2013-03-13 05:53:52

+0

仍然没有区别。压缩文件的大小超过了文件的原始大小。 – user59489 2013-03-13 08:44:29

回答

1

正如Lorem Ipsum所说,你不是在保存压缩图像,而是在保存重建图像本身(Q是重建图像)。所以你的文件将会和一个8位的.bmp文件一样大......

即使只保存相关的奇异值和相应的矢量,它也不应小于.jpg格式文件。 Jpeg已经被严重压缩,比SVD更好的技术...

+0

好。但我还有一个疑问。那就是,在代码中,我使用了图像(225 * 225 * 3,即151875位)进行压缩,并且我用p = 100进行了压缩,因此我获得了135300位的图像大小。意味着我压缩图像的尺寸较小吗? – user59489 2013-03-13 10:40:50

+0

否,225 * 225 * 3是您必须保存的数量。如果将它保存在24位BMP中,那么在8位BMP中将是225 * 225 * 3 * 24,即225 * 225 * 3 * 8 ...现在您创建一个矩阵Q,即225 * 225 * 3并将它保存在uint8中,这样就是225 * 225 * 3 * 8位的数据。如果你只在uint8中保存奇异值和相应的矢量,你可以保存(100 + 225 * 100 * 2)* 3 * 8(= 135300 * 8),然后像解压缩图像一样计算Q 。但是如果你保存的Q仍然是225 * 225 * 3整数你必须保存。 – 2013-03-13 12:10:32

+0

非常感谢。 – user59489 2013-03-13 15:43:49