SVD,奇异值分解。和矩阵的特征值差不多。
在这里可以使用 SVD 进行压缩:取得图片的奇异值后,舍去部分数值比较小的值。这样就是一个有损压缩。
不过,原来一个值就好了,现在变成了三个值,再存储…… 真的能压缩么?我真的不知道工业上是如何存储以达到压缩目的的。
下面只是个 Demo…… 只是个 Demo…… 只是个 Demo……
代码
close all
clear all
clc
% 读入图片
image_filename = 'onion.png';
image_raw = rgb2gray(imread(image_filename));
image_double = double(image_raw);
% 做奇异值分解
[U,S,V] = svd(image_double);
% 使用不同数量的奇异值,对图片做压缩和重建
errors = [];
n_used = [];
for i = 1:12
N = 25 * i - 20;
C = S;
% 舍去部分奇异值,只保留左上角的那些
C(N+1:end,:)=0;
C(:,N+1:end)=0;
% 重建图片
image_reconstruct=U*C*V';
% 显示图片,计算与原图的差值
subplot(4,3,i),imshow(uint8(image_reconstruct));
title(sprintf('使用 %i 个奇异值', N));
error=sum(sum((image_double-image_reconstruct).^2));
% store vals for display
errors = [errors; error];
n_used = [n_used; N];
end
% 与原图的差
figure;
title('与原图的差');
plot(n_used, errors);
grid on
xlabel('取多少个奇异值');
ylabel('与原图的差值');
最后
本来想拿 Python 写的,无奈一 import skimage.io
之后,就无法用 gui 显示图片了,只能用 imsave
来做输出…… 好忧伤。
发表回复