奇异值分解和图像压缩

from: http://cos.name/2014/02/svd-and-image-compression/
【2.18更新】:楠神写了一个非常gelivable的Shiny应用,用来动态展示图片压缩的效果随k的变化情况。谢大大把这个应用放到了RStudio的服务器上,大家可以点进去玩玩看了。

=====================代表正义的分割线=====================

今天我们来讲讲奇异值分解和它的一些有意思的应用。奇异值分解是一个非常,非常,非常大的话题,它的英文是 Singular Value Decomposition,一般简称为 SVD。下面先给出它大概的意思:

对于任意一个 m×nm×n 的矩阵 MM,不妨假设 m>nm>n,它可以被分解为

M=UDVTM=UDVT

其中

  • UU 是一个 m×nm×n 的矩阵,满足 UTU=InUTU=In,InIn 是 n×nn×n 的单位阵
  • VV 是一个 n×nn×n 的矩阵,满足 VTV=InVTV=In
  • DD 是一个 n×nn×n 的对角矩阵,所有的元素都非负

先别急,我看到这个定义的时候和你一样晕,感觉信息量有点大。事实上,上面这短短的三条可以引发出 SVD 许多重要的性质,而我们今天要介绍的也只是其中的一部分而已。

前面的表达式 M=UDVTM=UDVT 可以用一种更容易理解的方式表达出来。如果我们把矩阵 UU 用它的列向量表示出来,可以写成

U=(u1,u2,…,un)U=(u1,u2,…,un)

其中每一个 uiui 被称为 MM 的左奇异向量。类似地,对于 VV,有

V=(v1,v2,…,vn)V=(v1,v2,…,vn)

它们被称为右奇异向量。再然后,假设矩阵 DD 的对角线元素为 didi (它们被称为 MM的奇异值)并按降序排列,那么 MM 就可以表达为

M=d1u1vT1+d2u2vT2+⋯+dnunvTn=∑i=1ndiuivTi=∑i=1nAiM=d1u1v1T+d2u2v2T+⋯+dnunvnT=∑i=1ndiuiviT=∑i=1nAi

其中 Ai=diuivTiAi=diuiviT 是一个 m×nm×n 的矩阵。换句话说,我们把原来的矩阵 MM 表达成了 nn 个矩阵的和。

这个式子有什么用呢?注意到,我们假定 didi 是按降序排列的,它在某种程度上反映了对应项 AiAi 在 MM 中的“贡献”。didi 越大,说明对应的 AiAi 在 MM 的分解中占据的比重也越大。所以一个很自然的想法是,我们是不是可以提取出 AiAi 中那些对 MM 贡献最大的项,把它们的和作为对 MM 的近似?也就是说,如果令

Mk=∑i=1kAiMk=∑i=1kAi

那么我们是否可以用 MkMk 来对 Mn≡MMn≡M 进行近似?

答案是肯定的,不过等一下,这个想法好像似曾相识?对了,多元统计分析中经典的主成分分析就是这样做的。在主成分分析中,我们把数据整体的变异分解成若干个主成分之和,然后保留方差最大的若干个主成分,而舍弃那些方差较小的。事实上,主成分分析就是对数据的协方差矩阵进行了类似的分解(特征值分解),但这种分解只适用于对称的矩阵,而 SVD 则是对任意大小和形状的矩阵都成立。(SVD 和特征值分解有着非常紧密的联系,此为后话)

我们再回顾一下,主成分分析有什么作用?答曰,降维。换言之,就是用几组低维的主成分来记录原始数据的大部分信息,这也可以认为是一种信息的(有损)压缩。在 SVD 中,我们也可以做类似的事情,也就是用更少项的求和 MkMk 来近似完整的 nn 项求和。为什么要这么做呢?我们用一个图像压缩的例子来说明我们的动机。

我们知道,电脑上的图像(特指位图)都是由像素点组成的,所以存储一张 1000×622 大小的图片,实际上就是存储一个 1000×622 的矩阵,共 622000 个元素。这个矩阵用 SVD 可以分解为 622 个矩阵之和,如果我们选取其中的前 100 个之和作为对图像数据的近似,那么只需要存储 100 个奇异值 didi,100 个 uiui 向量和 100 个 vivi向量,共计 100×(1+1000+622)=162300个 元素,大约只有原始的 26% 大小。

【注:本文只是为了用图像压缩来介绍 SVD 的性质,实际使用中常见的图片格式(png,jpeg等)其压缩原理更复杂,且效果往往更好】

为了直观地来看看 SVD 压缩图像的效果,我们拿一幅 1000×622 的图片来做实验(图片来源:http://www.bjcaca.com/bisai/show.php?pid=33844&bid=40)

SVD演示图片,原图SVD演示图片,k=1SVD演示图片,k=5SVD演示图片,k=20SVD演示图片,k=50SVD演示图片,k=100

可以看出,当取一个成分时,景物完全不可分辨,但还是可以看出原始图片的整体色调。取 5 个成分时,已经依稀可以看出景物的轮廓。而继续增加 kk 的取值,会让图片的细节更加清晰;当增加到 100 时,已经几乎与原图看不出区别。

接下来我们要考虑的问题是,AkAk 是否是一个好的近似?对此,我们首先需要定义近似好坏的一个指标。在此我们用 BB 与 MM 之差的 Frobenius 范数 ||M–B||F||M–B||F 来衡量 BB 对MM 的近似效果(越小越好),其中矩阵的 Frobenius 范数是矩阵所有元素平方和的开方,当其为 0 时,说明两个矩阵严格相等。

此外,我们还需要限定 AkAk 的“维度”(否则 MM 就是它对自己最好的近似),在这里我们指的是矩阵的秩。对于通过 SVD 得到的矩阵 MkMk,我们有如下的结论:

在所有秩为 kk 的矩阵中,MkMk 能够最小化与 MM 之间的 Frobenius 范数距离。

这意味着,如果我们以 Frobenius 范数作为衡量的准则,那么在给定矩阵秩的情况下,SVD 能够给出最佳的近似效果。万万没想到啊。

在R中,可以使用 svd() 函数来对矩阵进行 SVD 分解,但考虑到 SVD 是一项计算量较大的工作,我们使用了 rARPACK 包中的 svds() 函数,它可以只计算前 kk 项的分解结果。完整的 R 代码如下:

library(rARPACK);
library(jpeg);factorize = function(m, k)
{r = svds(m[, , 1], k);g = svds(m[, , 2], k);b = svds(m[, , 3], k);return(list(r = r, g = g, b = b));
}recoverimg = function(lst, k)
{recover0 = function(fac, k){dmat = diag(k);diag(dmat) = fac$d[1:k];m = fac$u[, 1:k] %*% dmat %*% t(fac$v[, 1:k]);m[m < 0] = 0;m[m > 1] = 1;return(m);}r = recover0(lst$r, k);g = recover0(lst$g, k);b = recover0(lst$b, k);m = array(0, c(nrow(r), ncol(r), 3));m[, , 1] = r;m[, , 2] = g;m[, , 3] = b;return(m);
}rawimg = readJPEG("pic2.jpg");
lst = factorize(rawimg, 100);
neig = c(1, 5, 20, 50, 100);
for(i in neig)
{m = recoverimg(lst, i);writeJPEG(m, sprintf("svd_%d.jpg", i), 0.95);
}

参考文献

  1. Image Compression with the SVD in R
  2. Foundations of Data Science
  3. SVD维基页面

奇异值分解和图像压缩相关推荐

  1. 基于奇异值分解的图像压缩和信息隐藏

    基于奇异值分解的图像压缩和信息隐藏 将图像进行奇异值分解后,通过对对角矩阵进行一系列操作,可以达到压缩图像以及信息隐藏的目的.不仅如此,随着计算机网络和网络技术的不断发展,数字图像.音频和视频产品越来 ...

  2. 图像的高频信息和低频信息代表的含义(以奇异值分解实现图像压缩为例附实验说明)

    图像高频信息和低频信息区别,博主讲的很好,借用下,后面附上自己的实验说明. 图像的频率:灰度值变化剧烈程度的指标,是灰度在平面空间上的梯度. (1)什么是低频?       低频就是颜色缓慢地变化,也 ...

  3. 基于奇异值分解的图像压缩与除噪

    一.本报告所用的一些基本原理 第一,虑噪过程. 巴特沃斯滤波器的特点是通频带内的频率响应曲线最大限度平坦,没有起伏,而在阻频带则逐渐下降为零.在振幅的对数对角频率的波得图上,从某一边界角频率开始,振幅 ...

  4. 【PCA与LDA】特征值分解与奇异值分解以及图像压缩处理原理

    前言:     上一次写了关于 PCA与LDA 的文章,PCA的实现一般有两种,一种是用特征值分解去实现的,一种是用奇异值分解去实现的.在上篇文章中便是基于特征值分解的一种解释.特征值和奇异值在大部分 ...

  5. 基于奇异值分解的图像压缩matlab

    话不多说上才艺 文章目录 嘛是图像压缩

  6. 图像压缩之奇异值分解(SVD)

    最近有点时间把之前研究的图像压缩相关内容做以下记录和总结,包括一些经典方法代码实现以及原理介绍. 首先直接上Lena女神原图照片. 对于SVD分解来说,选取不同的奇异值数量压缩倍数也不一样,简单理解就 ...

  7. 机器学习-降维之奇异值分解SVD算法原理及实战

    奇异值分解 简介 PCA是通过特征值分解来进行特征提取的,但它要求矩阵必须是方阵,但在实际应用场景中,经常遇到的矩阵都不是方阵,如N个学生,每个学生有M门课程,其中N!=M, 这就组成了一个M*N的非 ...

  8. PCA与图像压缩与去噪

    使用PCA对一幅图像进行处理,并提取和显示该图像经过PCA的变换后的各主成分. 奇异值分解在图像压缩处理中有着重要的应用.假定一副图像有 n×n个像素,如果将这 n*n个数据一起传送,往往会显得数据量 ...

  9. SVD应用--电影推荐系统+图像压缩

    目录 推荐系统 协同过滤推荐 相似度计算 图像压缩 一.推荐系统 推荐系统如电影推荐系统的作用其实就是先对用户未评分的电影做预测评分,使数据完整,然后降序排序评分,为用户推荐评分前几名的物品. 如下图 ...

最新文章

  1. 如何更快速加载你的JS页面
  2. 查询XML节点 value
  3. DOS系统里,分屏显示目录的命令是什么??
  4. 【动态规划】大厅安排 (ssl 1212)
  5. 加载一张照片,可选择是否另存为
  6. es6 next()、throw()、return() 的共同点
  7. Dijkstra算法图文详解和C++代码
  8. GIMP用Path作画了解一下
  9. 学习: 导航器添加修饰符
  10. ArcGIS制图表达Representation-制图表达原理
  11. Tomcat 8默认工具manager管理页面访问配置
  12. 用JNDI连接数据库
  13. 数据--第32课 -二叉树的定义
  14. python测试之道电子书_python测试开发面试之深浅拷贝
  15. JUNIT5 + Mockito
  16. 龙果支付 mysql_龙果学院 基于电商业务的企业级大中台从设计到实现(第一阶段) 百度云 百度网盘...
  17. 单目 3D 目标检测——SMOKE
  18. 硬盘安装Win7全攻略(图解)
  19. css之sticky定位
  20. 或且非 java_Java且或非的符号

热门文章

  1. 在moss页面出错时,显示详细的错误信息.
  2. 图像识别中距离变换的原理及作用详解,并附用OpenCV中的distanceTransform实现距离变换的代码
  3. JQuery 中有用的方法
  4. Calendar.clear(int field)的陷阱
  5. linux内核kfifo(一)
  6. python捷豹_图像处理基本工具——Python 环境下的 Pillow( PIL )
  7. 数据库PHP绘制柱形图,php使用Jpgraph绘制柱形图的方法
  8. 初识WordPress数据库
  9. Scrum项目5.0
  10. git版本管理工具push失败解决方案参考