详情请参考附件,站内搜索 每天进步一点点《SVD用于压缩》
今天给大家分享一个 SVD 用于数据压缩的例子。
还是以图片作为距离,图片是有 M*N 个像素点组成的,在县线性代数中可以将其当做是一个矩阵进行处理和运算。由上一章节我们学习到了,经过SVD分解后,提取前几个主要的特征向量即可大约组成原始图像。
Img = UΣVT
下面我们将给出一个例子。使用的是 Octave 软件(别慌,语法都是兼容Matlab的),准备了一图像(315 x 485 x 3 = 152775 x 3)的彩色图像,灰度图像都是而且的,加上RGB三原色后,按照比例既可混合成彩色图像。
思路:原始图像,先按照RGB分解出三个二维灰度图像,对一个灰度图像进行SVD分解,最后提取不同的特征值数量,组成图像,看看组成的图像效果。先拜上男神!
% 获取原始彩色图像,并多复制几份做备用
img = imread(‘D:/software/octave/data/wuenda_master.jpg’);
img_tmp = img;
img_tmp_1 = img;
img_tmp_2 = img;
img_tmp_3 = img;
img_tmp_4 = img;
img_tmp_5 = img;
img_tmp_6 = img;
img_tmp_7 = img;
img_tmp_8 = img;
% 按照RGB,分解出三个灰度图像
img_1 = img(:,:,1);
img_2 = img(:,:,2);
img_3 = img(:,:,3);
size(img_1)
subplot(1,3,1);imshow(img_1,‘InitialMagnification’,‘fit’);
title(‘R image’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
size(img_2)
subplot(1,3,2);imshow(img_2,‘InitialMagnification’,‘fit’);
title(‘G image’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
size(img_3)
subplot(1,3,3);imshow(img_3,‘InitialMagnification’,‘fit’);
title(‘B image’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
% 分别获得灰度图像的 SVD 分解值
figure(1);
[img_1_u, img_1_s, img_1_v] = svd(img_1);
img_1_tmp = round(img_1_u * img_1_s * img_1_v');
subplot(1,4,1);imshow(img_1_tmp,'InitialMagnification','fit');
title('R image','fontname','Times New Roman','Color','k','FontSize',24);
size(img_1_u)
size(img_1_s)
size(img_1_v)
[img_2_u, img_2_s, img_2_v] = svd(img_2);
img_2_tmp = round(img_2_u * img_2_s * img_2_v');
subplot(1,4,2);imshow(img_2_tmp,'InitialMagnification','fit');
title('G image','fontname','Times New Roman','Color','k','FontSize',24);
size(img_2_u)
size(img_2_s)
size(img_2_v)
[img_3_u, img_3_s, img_3_v] = svd(img_3);
img_3_tmp = round(img_3_u * img_3_s * img_3_v');
subplot(1,4,3);imshow(img_3_tmp,'InitialMagnification','fit');
title('B image','fontname','Times New Roman','Color','k','FontSize',24);
size(img_3_u)
size(img_3_s)
size(img_3_v)
% 验证一下,在全部取全部特征的时候,是否能重新组合成原图像
img_tmp(:,:,1) = img_1_tmp;
img_tmp(:,:,2) = img_2_tmp;
img_tmp(:,:,3) = img_3_tmp;
subplot(1,4,4);imshow(img_tmp,'InitialMagnification','fit');
title('Original image','fontname','Times New Roman','Color','k','FontSize',24);
% 如果diff 的每一个值都是0,那么就是组成了原图像,没有丝毫差异。
diff = img_tmp - img;
sumVal = sum(diff(: ))
% 确认是0,因此经过SVD分解后,加入全部提取特征值,保持不变,重新计算回矩阵,和原始矩阵无差异。
% 以下是按照,抽取不同个数的主要特征值和特征向量,重新进行计算。
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 300;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)');
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)');
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)');
% 验证一下,在选取300个主要特征的时候,是否能重新组合成原图像
img_tmp_1(:,:,1) = img_1_tmp_new;
img_tmp_1(:,:,2) = img_2_tmp_new;
img_tmp_1(:,:,3) = img_3_tmp_new;
imshow(img_tmp_1);
diff = img_tmp_1 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 100;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取100个主要特征的时候,是否能重新组合成原图像
img_tmp_2(:,:,1) = img_1_tmp_new;
img_tmp_2(:,:,2) = img_2_tmp_new;
img_tmp_2(:,:,3) = img_3_tmp_new;
imshow(img_tmp_2);
diff = img_tmp_2 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 70;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取70个主要特征的时候,是否能重新组合成原图像
img_tmp_3(:,:,1) = img_1_tmp_new;
img_tmp_3(:,:,2) = img_2_tmp_new;
img_tmp_3(:,:,3) = img_3_tmp_new;
imshow(img_tmp_3);
diff = img_tmp_3 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 50;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取50个主要特征的时候,是否能重新组合成原图像
img_tmp_4(:,:,1) = img_1_tmp_new;
img_tmp_4(:,:,2) = img_2_tmp_new;
img_tmp_4(:,:,3) = img_3_tmp_new;
imshow(img_tmp_4);
diff = img_tmp_4 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 30;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取30个主要特征的时候,是否能重新组合成原图像
img_tmp_5(:,:,1) = img_1_tmp_new;
img_tmp_5(:,:,2) = img_2_tmp_new;
img_tmp_5(:,:,3) = img_3_tmp_new;
imshow(img_tmp_5);
diff = img_tmp_5 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 20;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取20个主要特征的时候,是否能重新组合成原图像
img_tmp_6(:,:,1) = img_1_tmp_new;
img_tmp_6(:,:,2) = img_2_tmp_new;
img_tmp_6(:,:,3) = img_3_tmp_new;
imshow(img_tmp_6);
diff = img_tmp_6 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 10;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取10个主要特征的时候,是否能重新组合成原图像
img_tmp_7(:,:,1) = img_1_tmp_new;
img_tmp_7(:,:,2) = img_2_tmp_new;
img_tmp_7(:,:,3) = img_3_tmp_new;
imshow(img_tmp_7);
diff = img_tmp_7 - img;
sumVal = sum(diff(: ))
% -------------------------------------------------------------------------------
% -------------------------------------------------------------------------------
main_features = 5;
img_1_tmp_new = round(img_1_u(:,1:main_features) * img_1_s(1:main_features,1:main_features) * img_1_v(:,1:main_features)’);
img_2_tmp_new = round(img_2_u(:,1:main_features) * img_2_s(1:main_features,1:main_features) * img_2_v(:,1:main_features)’);
img_3_tmp_new = round(img_3_u(:,1:main_features) * img_3_s(1:main_features,1:main_features) * img_3_v(:,1:main_features)’);
% 验证一下,在选取5个主要特征的时候,是否能重新组合成原图像
img_tmp_8(:,:,1) = img_1_tmp_new;
img_tmp_8(:,:,2) = img_2_tmp_new;
img_tmp_8(:,:,3) = img_3_tmp_new;
imshow(img_tmp_8);
diff = img_tmp_8 - img;
sumVal = sum(diff(: ))
figure(1);
subplot(3,3,1);imshow(img_tmp,‘InitialMagnification’,‘fit’);
title(‘SVD original image’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,2);imshow(img_tmp_1,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 300’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,3);imshow(img_tmp_2,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 100’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,4);imshow(img_tmp_3,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 70’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,5);imshow(img_tmp_4,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 50’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,6);imshow(img_tmp_5,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 30’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,7);imshow(img_tmp_6,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 20’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,8);imshow(img_tmp_7,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 10’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
subplot(3,3,9);imshow(img_tmp_8,‘InitialMagnification’,‘fit’);
title(‘SVD main features: 5’,‘fontname’,‘Times New Roman’,‘Color’,‘k’,‘FontSize’,24);
hold on;
可见,其中很小一部分的特征向量是保留了绝大部分的信息,特征值和特征向量留的越多,图像越接近原始图像,反之则越模糊,在这个图像上,特征是20个的时候,我们依稀可见图片的清晰内容。很多不必要的特征向量,作用微乎其微,因此可以忽略不计。
此时:图像只有 (315 x20 + 20x20 + 20 x 485) x 3 = 16400 x 3 个像素。压缩了百分之90%的像素。因此这就是一个完整的利用SVD进行图像压缩的例子。