算法简介
算法实现
我只是简单处理了一下图像的灰度值,如果要处理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()