用于图像压缩的SVD图像需要更多的磁盘大小,嗯..?

时间:2011-04-12 15:11:33

标签: matlab svd

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,丢弃较小的奇异值(尽管它们非常大)然后再次将矩阵相乘以获得压缩图像。压缩图像为黑白,比原始图像大。我在哪里失败了?

3 个答案:

答案 0 :(得分:2)

我不确定你最终的结果是3倍,因为类之间的转换比例为2.我能想到的唯一解释是原始图像im可能是{{{} 1}}有3个颜色通道。转换为灰度和uint8后,这将变为double倍。但是,除非你没有在这里发布这部分代码,否则看起来你不会从3个dims变为1。

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

答案 1 :(得分:0)

原始问题是 A = U S V * ,尺寸为(mxn) = (mxm) (mxn) (nxn)

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

压缩将等级从p = min(m,n)降低到rho。作为上午注意到压缩图像的尺寸是相同的(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%。

增加三倍的因素是MATLAB问题,其中r.m。已准确诊断出来。

答案 2 :(得分:0)

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

例如,使用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));