使用低秩 SVD 的图像压缩
此示例说明如何使用 svdsketch
压缩图像。svdsketch
使用低秩矩阵逼近来保留图像的重要特征,同时滤除不太重要的特征。随着 svdsketch
使用的容差量级的增大,更多特征将被滤除,从而改变图像中的详细程度。
加载图像
加载图像 street1.jpg
,这是一幅城市街道图。形成此图像的三维矩阵是 uint8
,因此将图像转换为灰度矩阵。查看具有原始矩阵秩注释的图像。
A = imread('street1.jpg'); A = rgb2gray(A); imshow(A) title(['Original (',sprintf('Rank %d)',rank(double(A)))])
压缩图像
使用 svdsketch
计算低秩矩阵,该矩阵在 1e-2
的容差范围内逼近 A
。通过将返回的 SVD 因子乘以 svdsketch
形成低秩矩阵,将结果转换为 uint8
,并查看生成的图像。
[U1,S1,V1] = svdsketch(double(A),1e-2);
Anew1 = uint8(U1*S1*V1');
imshow(uint8(Anew1))
title(sprintf('Rank %d approximation',size(S1,1)))
svdsketch
产生秩为 288 的逼近,这导致图像的部分边界线中出现一些微小颗粒。
现在,使用容差 1e-1
再次压缩图像。随着容差量级的增大,由 svdsketch
产生的逼近的秩通常会减小。
[U2,S2,V2] = svdsketch(double(A),1e-1);
Anew2 = uint8(U2*S2*V2');
imshow(Anew2)
title(sprintf('Rank %d approximation',size(S2,1)))
这一次,svdsketch
产生了秩为 48 的逼近。图像大体上仍算清晰可见,但额外的压缩增加了模糊性。
限制子空间大小
svdsketch
根据指定的容差,以自适应方式确定矩阵草图的秩。但是,您可以使用 MaxSubspaceDimension
名称-值对组来指定应该用于形成矩阵草图的最大子空间大小。此选项会产生不满足容差的矩阵,因为您指定的子空间可能太小。在这些情况下,svdsketch
返回具有最大允许子空间大小的矩阵草图。
使用容差为 1e-1
、最大子空间大小为 15 的 svdsketch
。指定第四个输出以返回相对逼近误差。
[U3,S3,V3,apxErr] = svdsketch(double(A),1e-1,'MaxSubspaceDimension',15);
将结果的相对逼近误差与指定的容差进行比较。apxErr
包含一个元素,因为 svdsketch
只需一次迭代来计算解。
apxErr <= 1e-1
ans = logical
0
结果表明,矩阵草图不满足指定的容差。
查看高度压缩的秩为 15 的图像。
Anew3 = uint8(U3*S3*V3');
imshow(Anew3)
title(sprintf('Rank %d approximation',size(S3,1)))
比较结果
最后,并排查看所有图像进行比较。
tiledlayout(2,2,'TileSpacing','Compact') nexttile imshow(A) title('Original') nexttile imshow(Anew1) title(sprintf('Rank %d approximation',size(S1,1))) nexttile imshow(Anew2) title(sprintf('Rank %d approximation',size(S2,1))) nexttile imshow(Anew3) title(sprintf('Rank %d approximation',size(S3,1)))