使用SVD在MATLAB中压缩图像 [英] Using SVD to compress an image in MATLAB
问题描述
我是MATLAB的新手,但我正在尝试为灰度图像做一些图像压缩代码。
问题
如何使用SVD修剪低值特征值来重建压缩图像?
工作/尝试所以远
到目前为止我的代码是:
B = imread( 'images1.jpeg');
B = rgb2gray(B);
doubleB = double(B);
%读取图像并将其存储为矩阵B,将图像转换为灰度
照片,并将矩阵转换为类'double',值为0-255
[U,S, V] = SVD(doubleB);
这使我能够使用存储在变量S中的特征值成功分解图像矩阵。
如何截断S(167x301,类double)?让我们说一下167个特征值,我只想要前100个(或任何n个),我该怎么做并重建压缩图像?
更新的代码/想法
这不是在评论部分放置一堆代码,而是我当前的草案。我已经能够通过手动更改N来成功创建压缩图像,但我还想做两件事:
1-显示各种压缩的图像范围(i / e,运行N = 5,10,25等循环)
2-以某种方式计算每个图像与原始图像之间的差异(误差)理解循环和输出我觉得很糟糕,但这就是我的尝试:
B = imread( 'images1.jpeg');
B = rgb2gray(B);
doubleB = im2double(B);%
%读取图像并将其存储为矩阵B,将图像转换为灰度
%照片并将图像转换为类'double'
[U,S,V] = svd(doubleB);
C = S;
代表N = [5,10,25,50,100]
C(N + 1:结束,:) = 0;
C(:,N + 1:结束)= 0;
D = U * C * V';
%在图像doubleB上使用奇异值分解,创建一个新矩阵
%C(对于压缩对角线)并将所有条目归零N,(在
%这个案例中为100) 。然后使用新的
%对角矩阵C构造一个新图像D.
imshow(D);
错误= C-D;
结束
显然有一些错误,因为我没有得到多张图片或知道如何图形化错误矩阵
刚开始,我假设你知道SVD真的不是最好的用于去除单个图像中的像素的工具。但这是一个好习惯。
好的,所以我们知道 B = U * S * V'
。我们知道S是对角线的,按大小排序。因此,通过仅使用S的前几个值,您将获得图像的近似值。假设 C = U * S2 * V'
,其中S2是你修改过的S.U和V的大小没有改变,所以现在最容易做的事情是将您不想使用的S元素归零,然后运行重建。 (最简单的方法: S2 = S; S2(N + 1:结束,:) = 0; S2(:,N + 1:结束)= 0;
)。
现在是压缩部分。 U
已满, V
也是如此,所以无论 S2发生了什么
,您的数据量不会改变。但是看看 U * S2
会发生什么。 (绘制图像)。如果您在 S2
中保留了N个奇异值,那么只有 S2
的前N行非零。压缩!除了你还需要处理 V
。在完成(U * S2)
后,你不能使用相同的技巧,因为更多 U * S2
不是 S2
本身。我们怎样才能在双方使用S2?好吧,它是对角线,所以使用 D = sqrt(S2)
,现在 C = U * D * D * V'
。所以现在 U * D
只有N个非零行, D * V'
只有N个非零列。只传输那些数量,你可以重建C,大致类似于B.
I am brand new to MATLAB but am trying to do some image compression code for grayscale images.
Questions
How can I use SVD to trim off low-valued eigenvalues to reconstruct a compressed image?
Work/Attempts so far
My code so far is:
B=imread('images1.jpeg');
B=rgb2gray(B);
doubleB=double(B);
%read the image and store it as matrix B, convert the image to a grayscale
photo and convert the matrix to a class 'double' for values 0-255
[U,S,V]=svd(doubleB);
This allows me to successfully decompose the image matrix with eigenvalues stored in variable S.
How do I truncate S (which is 167x301, class double)? Let's say of the 167 eigenvalues I want to take only the top 100 (or any n really), how do I do that and reconstruct the compressed image?
Updated code/thoughts
Instead of putting a bunch of code in the comments section, this is the current draft I have. I have been able to successfully create the compressed image by manually changing N, but I would like to do 2 additional things:
1- Show a pannel of images for various compressions (i/e, run a loop for N = 5,10,25, etc.)
2- Somehow calculate the difference (error) between each image and the original and graph it.
I am horrible with understanding loops and output, but this is what I have tried:
B=imread('images1.jpeg');
B=rgb2gray(B);
doubleB=im2double(B);%
%read the image and store it as matrix B, convert the image to a grayscale
%photo and convert the image to a class 'double'
[U,S,V]=svd(doubleB);
C=S;
for N=[5,10,25,50,100]
C(N+1:end,:)=0;
C(:,N+1:end)=0;
D=U*C*V';
%Use singular value decomposition on the image doubleB, create a new matrix
%C (for Compression diagonal) and zero out all entries above N, (which in
%this case is 100). Then construct a new image, D, by using the new
%diagonal matrix C.
imshow(D);
error=C-D;
end
Obviously there are some errors because I don't get multiple pictures or know how to "graph" the error matrix
Just to start, I assume you're aware that the SVD is really not the best tool to decorrelate the pixels in a single image. But it is good practice.
OK, so we know that B = U*S*V'
. And we know S is diagonal, and sorted by magnitude. So by using only the top few values of S, you'll get an approximation of your image. Let's say C=U*S2*V'
, where S2 is your modified S. The sizes of U and V haven't changed, so the easiest thing to do for now is to zero the elements of S that you don't want to use, and run the reconstruction. (Easiest way to do this: S2=S; S2(N+1:end, :) = 0; S2(:, N+1:end) = 0;
).
Now for the compression part. U
is full, and so is V
, so no matter what happens to S2
, your data volume doesn't change. But look at what happens to U*S2
. (Plot the image). If you kept N singular values in S2
, then only the first N rows of S2
are nonzero. Compression! Except you still have to deal with V
. You can't use the same trick after you've already done (U*S2)
, since more of U*S2
is nonzero than S2
was by itself. How can we use S2 on both sides? Well, it's diagonal, so use D=sqrt(S2)
, and now C=U*D*D*V'
. So now U*D
has only N nonzero rows, and D*V'
has only N nonzero columns. Transmit only those quantities, and you can reconstruct C, which is approximately like B.
这篇关于使用SVD在MATLAB中压缩图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!