使用SVD在MATLAB中压缩图像 [英] Using SVD to compress an image in MATLAB

查看:267
本文介绍了使用SVD在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆