2
d=50;
im = imread('H:\matlab\bildanalys\terminator.gif');
M2 = double(im);
[U S V] = svd(M2);
U2 = U(:,1:d);
S2 = S(1:d,1:d);
V2 = V(:,1:d);
compressed=U2*S2*V2';
imwrite(compressed,'H:\matlab\bildanalys\compressedterminator.gif','gif')
S2

压缩后的图像大了 3 倍...

我对图像进行 svd,丢弃较小的奇异值(尽管它们很大),然后再次将矩阵相乘以获得压缩图像。压缩后的图像是黑白的,并且比原始图像大。我在哪里失败?

4

3 回答 3

2

我不确定你最终是如何得到 3 倍大的,因为类之间的转换以 2 的幂为单位。我能想到的唯一解释是原始图像im可能是uint8具有 3 个颜色通道的图像。这在转换为灰度 和double后,变为原来8/3~2.67的倍。但是,除非您没有在此处发布该部分代码,否则您似乎不会从 3 个暗淡变为 1 个。

至于使用 SVD 来减少存储,如果你重新乘以你的矩阵,你将回到一个完整的矩阵,它的元素数量与你开始时完全相同,因此你将获得相同大小的图像。

于 2011-04-12T15:38:49.250 回答
0

最初的问题是A = U S V*,尺寸为(mxn) = (mxm) (mxn) (nxn)

中心思想是使用瘦 SVD,在丢弃与 SVD 中新的零值对应的零空间分量后,用分解产物USV*替换图像。例如,深空探测器可能具有很大的计算能力和很小的传输带宽。卫星记录图像、分解、压缩和传输分解产物,而不是图像。图像稍后重新组合。

压缩将秩从 p = min( m, n ) 降低到 rho。正如 rm 所指出的,压缩图像的尺寸是相同的(mxn) = (mx rho) (mx rho) (rho xn)

原始秩p可能为数千,而 rho 低至 10。输入矩阵有mn个元素;压缩数据需要rho( m + n + rho)元素。

示例:m = n = 2048,rho = 10。图像需要 4,194,304 个元素;压缩分解中的元素总和为 41,060,不到原始数据量的 1%。

三个增加的因素是 rm 准确诊断的一个 MATLAB 问题。

于 2014-08-17T01:23:50.760 回答
0

您可能正在保存多余的列和行。在截断对角线的奇异值之后——当然,你将其存储为一维数组——你还应该分别将矩阵的列和行截断UV^tmacth。否则,您将存储一堆在重建期间将乘以 0 的值M = U * S * Vt

例如,使用 Java 的Apache Commons库(因为我对 MatLab 不太熟悉,抱歉):

// compute your SVD from some input matrix
final SingularValueDecomposition svd = new SingularValueDecomposition(matrix);

// only store necessary matrix portions in memory required to compute compressed matrix
final RealMatrix u = svd.getU().getSubMatrix(0, svd.getU().getRowDimension()-1, 0, (svd.getU().getColumnDimension()-1)-compression);

// grab singular values
final RealMatrix s = svd.getS().getSubMatrix(0, (size-compression)-1, 0, (size-compression)-1);

// grab V transpose
final RealMatrix vt = svd.getVT().getSubMatrix(0, (svd.getVT().getRowDimension()-1)-compression, 0, svd.getVT().getColumnDimension()-1);

// compute compressed matrix
return new Array2DRowRealMatrix(u)
     .multiply(new Array2DRowRealMatrix(s))
     .multiply(new Array2DRowRealMatrix(vt));
于 2016-06-25T07:54:33.067 回答