压缩原理——SVD

   图像在计算机中用矩阵储存,值的大小在0~255,在这里我们令图像的矩阵为A。若图片为灰色图片则颜色通道只有一个,所以A为二维矩阵;若为彩色矩阵则颜色通道由3种,分别B,G,R,分别对应三原色蓝色,绿色,红色,即三原色。

  我们将A分解为U,D两个正交矩阵呵V这个奇异值矩阵,如下图所示。

 在这里我们举例说明一下,A=

 

 在Matlab中我们使用内置函数svd()函数对A进行分解

A = [4 12 8 7

12 5 8 4

3 17 56 21]

[U,V,D] = svd(A);

 V的结果如下图所示:

 U,D结果为正交矩阵,这里不予展示。SVD压缩原理就是保留原矩阵的重要特征,在64.55,13.21,7.42中我们只要保留64.55,13.21这些较大的奇异值,舍弃较小的奇异值,就能保留原矩阵的大部分信息了。当然U,D也要根据奇异值矩阵V进行调整。

我们用matlab编程得到3个程序,后面两个为函数,photo_compress()为压缩函数,调用New_svd()进行奇异值分解。

程序主程序,记得改变图片路径:

%Matlab压缩图片图片

ratio = 0.6;%压缩比例

graycompress = 0;%若为1压缩为灰度图

file_name = 'E:\workplace\wisdom';%文件所在路径

name = 'test.jpg';%图片的名称

photo_address = fullfile(file_name,name);%fullfile()合并制定路径和文件名

save_address = fullfile(file_name,strcat('compress_',name));

tmp=photo_compress(photo_address,save_address,ratio,graycompress);

disp('End')

压缩程序,对应不同的图片给予不同的方法处理:

function [compress_A] = photo_compress(photo_address,save_address,ratio,graycompress)

%图片压缩函数

%参数说明

%photo_address图片所在地址

% save_address压缩图片所在地址

% ration压缩比例

% graycompress默认为0,置彩色图片转成灰色图片再压缩

if nargin == 3%获取函数的参数数量,如果为3个参数则默认读入彩色图片

graycompress = 0;

end

img = double(imread(photo_address));

if size(img,3)==3 && graycompress == 1

img = double(rgb2gray(imread(photo_address)));%将彩色照片转换成灰色照片

end

if size(img,3)==3%判断是否为彩色照片

disp('正在压缩彩色照片');

R = img(:,:,1);

G = img(:,:,2);

B = img(:,:,3);

%调用压缩函数进行压缩

r =new_svd(R,ratio);

g= new_svd(G,ratio);

b =new_svd(B,ratio);

compress_A = cat(3,r,g,b);

else

disp('正在压缩灰色照片');

compress_A = new_svd(img,ratio);

end

imwrite(uint8(compress_A),save_address);

disp('压缩完成');

end

奇异值分解函数,根据压缩比例,动态调整奇异值的数量:

function[A_svd] = new_svd(A,ratio)

%奇异值分解比例函数

[U,V,D] = svd(A);

A_diag = diag(V);%取对角值

S = sum(A_diag)

temp=0;

length_A_diag = length(A_diag);

for i=(1:length_A_diag)

temp = temp + A_diag(i)

if (temp./S) > ratio

break;

end

end

A_svd=U(:,1:i)*V(1:i,1:i)*D(:,1:i)';

svd_ratio = temp./S;

disp(strcat('矩阵压缩比例为',num2str(svd_ratio.*100),'%'));

压缩比例为0.6,结果如下图所示: 

查看原文