如何在对图像应用SVD后检查图像是否被压缩(关于磁盘上压缩图像的大小)

4
I=imread('cameraman.tif');
figure(1),imshow(I)
I1=im2double(I);
[U,S,V]=svd(I1);
figure(2),imshow(I1)
for j=1:90
    I2=U(:,1:j)*S(1:j,1:j)*V(:,1:j)';
end
figure(3),imshow(I2)
I3=U*S*V';
figure(4),imshow(I3)

这是我为SVD分解编写的代码,我得到了正确的输出。但是压缩后的图像大小比原始图像还要大,因此如何计算是否经过svd压缩图像,即我得到的应用svd迭代后图像在磁盘上的大小大于原始图像。


1
您是说I3的像素大小> I1的像素大小,还是指图像在磁盘上的大小以字节为单位更大? - BlessedKey
2个回答

4
这是一个说明性的例子:
I = imread('cameraman.tif');
X = im2double(I);

%# SVD
[U S V] = svd(X);

%# variance explained by each eigenvector
variances = abs(diag(S).^2);
plot(cumsum(variances)./sum(variances), 'b.-'), ylim([0 1])
title('SVD'), xlabel('i^{th} Component'), ylabel('Variance explained')

%# iterate over number of components to keep
figure
subplot(121), imshow(X), title( sprintf('size=%d',numel(X)) )
subplot(122)
for p = 1:(size(U,2)/2-1)
    %# truncated SVD
    Up = U(:,1:p);
    Vp = V(:,1:p);
    Sp = diag(S(1:p,1:p));

    %# reconstruct/compress
    XHat = Up * diag(Sp) * Vp';                %'# approximation
    err = mean( abs(X(:)-XHat(:)) );           %# mean absolute error
    sz = (numel(Up) + numel(Vp) + numel(Sp));  %# new size

    %# show
    imshow(XHat)
    title( sprintf('p=%d, size=%d, err=%g', p, sz, err) )

    %# flush output
    drawnow
end

var svd_approx


1

我觉得你没有理解SVD分解的重点。重建图像的大小将保持相同,即像素数量不变。而SVD的作用是允许你存储/传输更少的信息...换句话说,在你的情况下,你可以传输256^2个double或(256*j)+j+(256*j)。对于j为90,它是46170(与65536相比)。


实际上是(256*j)+j+(256*j),因为我们只考虑S(奇异值,其余都是零)的对角线。 - Amro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接