Python机器学习案例:梵高的《星空》图片压缩
本案例将奇异值分解用于处理图像压缩任务。要压缩的图片如图所示,是梵高的作品《星空》。
Python实现代码如下所示:
from PIL import Image
import os
from numpy import *
import matplotlib as mpl
import matplotlib.pyplot as plt
if __name__ == '__main__':
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False
A = Image.open('starry_night.jpg')
a = array(A) #转换成矩阵
#由于是彩色图像,所以3通道。a的最内层数组为三个数,分别表示RGB,用来表示一个像素
u_r, sigma_r, v_r = linalg.svd(a[:, :, 0])
u_g, sigma_g, v_g = linalg.svd(a[:, :, 1])
u_b, sigma_b, v_b = linalg.svd(a[:, :, 2])
def restore1(u, sigma, v, k):
m = len(u)
n = len(v)
a = zeros((m, n))
#重构图像
a = dot(u[:, :k], diag(sigma[:k])).dot(v[:k, :])
#上述语句等价于如下形式
#for i in range(k):
# ui = u[:, i].reshape(m, 1)
# vi = v[i].reshape(1, n)
# a += sigma[i] * dot(ui, vi)
a[a < 0] = 0
a[a > 255] = 255
return rint(a).astype('uint8')
plt.figure(facecolor = 'w', figsize = (10, 10))
#保留的奇异值个数依次为:1,2,...,12
K = 12
for k in range(1, K + 1):
print(k)
R = restore1(u_r, sigma_r, v_r, k)
G = restore1(u_g, sigma_g, v_g, k)
B = restore1(u_b, sigma_b, v_b, k)
I = stack((R, G, B), axis = 2)
#现实重构后的图片
plt.subplot(3, 4, k)
plt.imshow(I)
plt.axis('off')
plt.title(u'奇异值个数:%d' % k)
plt.suptitle(u'SVD与图像分解', fontsize = 20)
plt.tight_layout(0.1, rect = (0, 0, 1, 0.92))
plt.show()
运行以上代码的输出结果如图所示。
到这里这个简单的实力就完成啦!