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()
運行以上代碼的輸出結果如圖所示。
到這裡這個簡單的實力就完成啦!