奇异值分解(Singular Value Decomposition,SVD)是线性代数中一种重要的矩阵分解。在很多情况下,数据中的一部分携带了数据集中的大部分信息,而剩下的信息则要么是噪声,要么是毫不相关的信息。利用SVD实现,能够用小得多的数据集来表示原始数据集。这样做,实际上是去除了噪声和冗余数据。同样,当我们试图节省空间时,去除信息也是很有用了。可以使用这个思想对图像进行压缩。
在Python中,SVD分解非常简单,可利用np.linalg.svd()函数,比如u,sigma,v=np.linalg.svd(A),则u,v分别返回A的左右奇异向量,而sigma返回的并不是系数矩阵,而是一个奇异值从大到小排列的一个向量。
然后对于图像而言,一般的彩色图像其实就是RGB三个图层上矩阵的叠加,每个元素的值 为0到255之间的整数,在Python中读取图像可以通过plt.imread()函数,这样直接得到了一个ab3的矩阵,然后对三个图层分别处理就行。
利用SVD分解进行图片压缩的基本步骤如下:
1 读取图片,分解成RGB三个矩阵。
2 对三个矩阵分别进行SVD分解,得到对应的奇异值和奇异向量。
3 按照一定标准进行奇异值的筛选(整体数量的一定百分比,或者奇异值和的一定百分比)
4 恢复矩阵,并将RGB三个矩阵叠加起来。
5 保存图像。
实现步骤如下:
由于在python中需要读取图像,因此需要在命令行下安装如下库:
pip install matplotlib pillow
程序首先导入下面两个库:
import numpy as np
from matplotlib import pyplot as plt
然后定义下面函数用于读入图像,并生成数据矩阵:
def svdimage(filename,percent):
original=plt.imread(filename) #读取图像
R0=np.array(original[:,:,0]) #获取第一层矩阵数据
G0=np.array(original[:,:,1]) #获取第二层矩阵数据
B0=np.array(original[:,:,2]) #获取第三层矩阵数据
u0,sigma0,v0=np.linalg.svd(R0) #对第一层数据进行SVD分解
u1,sigma1,v1=np.linalg.svd(G0) #对第二层数据进行SVD分解
u2,sigma2,v2=np.linalg.svd(B0) #对第三层数据进行SVD分解
R1=np.zeros(R0.shape)
G1=np.zeros(G0.shape)
B1=np.zeros(B0.shape)
total0=sum(sigma0)
total1=sum(sigma1)
total2=sum(sigma2)
sd=0
for i,sigma in enumerate(sigma0): #用奇异值总和的百分比来进行筛选。
R1+=sigma*np.dot(u0[:,i].reshape(-1,1),v0[i,:].reshape(1,-1))
sd+=sigma
if sd>=percent*total0:
break
sd=0
for i,sigma in enumerate(sigma1): #用奇异值总和的百分比来进行筛选
G1+=sigma*np.dot(u1[:,i].reshape(-1,1),v1[i,:].reshape(1,-1))
sd+=sigma
if sd>=percent*total1:
break
sd=0
for i,sigma in enumerate(sigma2): #用奇异值总和的百分比来进行筛选
B1+=sigma*np.dot(u2[:,i].reshape(-1,1),v2[i,:].reshape(1,-1))
sd+=sigma
if sd>=percent*total2:
break
final=np.stack((R1,G1,B1),2)
final[final>255]=255
final[final<0]=0
final=np.rint(final).astype('uint8')
return final
最后,可以调用这个函数,调用时指定需要的百分比。如下图所示:
for p in np.arange(.1,1,.1):
after=svdimage(filename,p)
plt.imsave(str(p)+'_1.jpg',after)
原始图像如下:
下图给出了保留奇异值50%的压缩信息的图像。
下图给出了保留奇异值90%的压缩信息的图像。
可以看出在不同的奇异值保留程度下,图像的压缩比例也不一样。
本文部分观点节选自北京大学出版社出版的《Python 3 数据分析与机器学习实战》图书,这本书现在在京东参加春季优惠满100减50的活动,点击阅读原文,即可了解更多。
留言回复你在机器学习方面做过哪些有趣的应用,我们会在留言中随机抽取一位读者免费送出上述图书一本。