基于奇异值分解的图像压缩及实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于奇异值分解的图像压缩及实现
本文利用奇异值分解方法,来对图片进行压缩,过程中我们
利用Matlab 编程来达到这个目的。
一:实验方法及原理
奇异值:矩阵A 的奇异值定义如下:设n
*m r
C A ∍(r>0),且A A T 的特征值分别为
0n 1r r 21==⋯⋯=≥≥⋯⋯≥+λλλλλ (1)
则称i i λσ=
(i=1,2,…,n )为A 的奇异值。
奇异值分解定理:设Σ=diag(r 21...σσσ,,
,),由式(1)可知,i σ(i=1,2,…,r )为A 的非零奇异值。U 为m 阶酉矩阵(n 阶复
方阵U 的n 个列向量是U 空间的一个标准正交基,则U 是酉矩阵),V 为n 阶酉矩阵,若满足矩阵等式
(2)
则称式(2)为A 的奇异值分解。若U 写成U =[m 21u ......u u ,,
,]的形式,V 写成V=[n 21v ......v v ,,
,]的形式,则式(2)可写成如下形式:
(3)
由于大的奇异值对图像的贡献大,小的奇异值对图像的贡献小,所以可以从r 个奇异值生成矩阵中选取前k 个(k (4) 近似表示图像A。 存储图像A需要mn个数值,存储图像k A需(m+n+1)k个数值,若取 (5) 则可达到压缩图像的目的,比率 (6) 称为压缩率 二:实验过程 1.实验数据来源: 本实验所需要的实验原图片是lena.bmp,处理后的图片设置为lena2.bmp。并获取图片的描述矩阵,为512*512阶8位的方阵。 设为A,同时也是原始矩阵,本实验主要是对A进行奇异值分解,用一个更小阶的矩阵来描述A,从而达到实验目的。 2.实验过程: 提取图像lena.bmp数据,将图片读入Matlab中,存储的是数据矩阵并且设置为512*512的矩阵A,将矩阵A中的数据转换为double型,以适应svd函数的要求,运用函数[U,S,V]=svd(A)进行图像的奇异值分解,分别得到对角奇异值矩阵S为512*1阶,以 及U 左奇异值矩阵为512*512阶,V 右奇异值矩阵为512*512阶。将S 对角化后,显示的奇异值见图1: 0100200300400500600 1 2 3 4 5 6 7 4 图1.奇异值分布图 然后利用分解后的矩阵重构原矩阵A ,并进行数据格式转换,设置压缩数k ,分别令k=40、80、120、160、200五个数据,利用svds 函数将选择k 之后的新矩阵进行A 的重构,即运用U*S*V ’进行重构,其中S 为40*40的对角矩阵,U 为512*40的左奇异值矩阵,V 为512*40的右奇异值矩阵,重构时需将重构的矩阵进行字型转换为uint8类,将重构后的矩阵放置在outfile 中,最后显示重构后的图像。Matlab 实现代码见附录1. (1)图片压缩流程如图2所示: 图2.图像压缩程序流程 图3.图像解压流程 (2)图像重构流程图见图3. 三.实验结论 由式(5)、(6)可知,如果从分解后的对角矩阵中选择k 个大奇异值以及这些奇异值相对应的左右奇异向量逼近原图像,便可以使用k (n+1)个数值代替原来的n*n 个图像数据,显然要到达图像压缩的效果,就一定要求k (n+1)<2n ,在发送图像时,只需要k (n+1)个有关奇异值和奇异值向量的数据即可,接收到数据时就利用这些数据进行重构出原图像。 k 值越小,需要保存的数据就越少,k 月接近n ,重构出来的 图像就越和源图像相似。所以在图像压缩时,只要选择合适的奇异值个数,解压缩后的图像就可以满足视觉要求,一般情况下,对于256≤n≤2048的图像,选取25≤k≤100时,都有较满意的视觉效果。实验结果图如图4所示,其中a代表原图,b为k=40时的效果图,c、d、e、f分别为k=80、120、160、200时的效果图: (a)(b) (c) (d) (e) (f) 附录1 >> infile='D:\lena.bmp'; >> outfile='lena2.bmp'; >> A=imread(infile); >> A=double(A); >> [U,S,V]=svd(A); >> S=diag(S); >> plot(S) >> k=40; >> [U,S,V]=svds(A,k); >> im=uint8(U*S*V'); >> imwrite(im,outfile); >> imshow(im) >> k=80; >> [U,S,V]=svds(A,k); >> im=uint8(U*S*V'); >> imwrite(im,outfile); >> imshow(im) >> k=120; >> [U,S,V]=svds(A,k); >> im=uint8(U*S*V'); >> imwrite(im,outfile); >> imshow(im) >> k=160; >> [U,S,V]=svds(A,k); >> im=uint8(U*S*V'); >> imwrite(im,outfile); >> imshow(im) >> k=200; >> [U,S,V]=svds(A,k); >> im=uint8(U*S*V'); >> imwrite(im,outfile); >> imshow(im)