Main Content

使用低秩 SVD 的图像压缩

此示例说明如何使用 svdsketch 压缩图像。svdsketch 使用低秩矩阵逼近来保留图像的重要特征,同时滤除不太重要的特征。随着 svdsketch 使用的容差量级的增大,更多特征将被滤除,从而改变图像中的详细程度。

加载图像

加载图像 street1.jpg,这是一幅城市街道图。形成此图像的三维矩阵是 uint8,因此将图像转换为灰度矩阵。查看具有原始矩阵秩注释的图像。

A = imread('street1.jpg');
A = rgb2gray(A);
imshow(A)
title(['Original (',sprintf('Rank %d)',rank(double(A)))])

Figure contains an axes object. The axes object with title Original (Rank 480) contains an object of type image.

压缩图像

使用 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)))

Figure contains an axes object. The axes object with title Rank 288 approximation contains an object of type image.

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)))

Figure contains an axes object. The axes object with title Rank 48 approximation contains an object of type image.

这一次,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)))

Figure contains an axes object. The axes object with title Rank 15 approximation contains an object of type image.

比较结果

最后,并排查看所有图像进行比较。

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)))

Figure contains 4 axes objects. Axes object 1 with title Original contains an object of type image. Axes object 2 with title Rank 288 approximation contains an object of type image. Axes object 3 with title Rank 48 approximation contains an object of type image. Axes object 4 with title Rank 15 approximation contains an object of type image.

另请参阅

| |

相关主题