压缩原理——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,结果如下图所示: