基于SVD的图像压缩

算法简介

算法实现

我只是简单处理了一下图像的灰度值,如果要处理RGB值的话,就需要分别进行SVD分解,最后再合起来即可。

 1 import numpy as np
 2 from PIL import Image
 3 import matplotlib.pyplot as plt
 4 
 5 
 6 def picture_processing(file):  # 图像处理,返回灰度值
 7     im = Image.open(file)
 8     im = im.convert('L')   # 转换为灰度图
 9     #im.save('original_' + file)  # 保存图片
10     w, h = im.size
11     data = np.zeros((h, w))
12     for i in range(w):     # 得到灰度值矩阵
13         for j in range(h):
14             data[j][i] = im.getpixel((i, j))
15     return data
16 
17 
18 def picture_restore(U, Sigma, VT, k):   # 图像恢复,k为选取的奇异值个数
19     sig = np.eye(k) * Sigma[:k]
20     new_pic = U[:, :k].dot(sig).dot(VT[:k, :])   # 重构图片
21     new_size = U.shape[0] * k + sig.size + k * VT.shape[1]  # 计算SVD图片所需大小
22     #new_im = Image.fromarray(new_pic.astype(np.uint8))  # 保存图片
23     #new_im.save('pic_' + str(k) + '.jpeg')
24     return new_pic, new_size
25 
26 
27 if __name__ == '__main__':
28     file = 'pic.jpeg'
29     data = picture_processing(file)
30     U, Sigma, VT = np.linalg.svd(data)
31 
32     pic_list, size_list = [], []   #图片列表,图片大小列表
33     k_list = [1, 10, 50, 100, 300]
34     for k in k_list:
35         new_pic, new_size = picture_restore(U, Sigma, VT, k)
36         pic_list.append(new_pic)
37         size_list.append(new_size)
38 
39     fig, ax = plt.subplots(2, 3)   # 展示
40     ax[0][0].imshow(data)
41     ax[0][0].set_title('original picture——size:%d' % data.size)
42     for i in range(len(k_list)):
43         ax[int((i+1) / 3)][int((i+1) % 3)].imshow(pic_list[i])
44         ax[int((i+1) / 3)][int((i+1) % 3)].set_title('k = %d——size:%d' % (k_list[i], size_list[i]))
45     plt.show()

运行结果

原文地址:https://www.cnblogs.com/zyb993963526/p/10647639.html