1. 程式人生 > >基於python 實現對圖片進行SVD

基於python 實現對圖片進行SVD

實現對圖片進行SVD

之前在學習截斷式SVD的時候, 不知道為什麼截斷式SVD後能夠近似原矩陣? 或者說奇異值究竟有什麼含義?
看了以下知乎的答案後, 有了很形象的理解
奇異值的物理意義是什麼? - 鄭寧的回答 - 知乎

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt 
import matplotlib.image as mpimg 

def get_approx_matrix(u, sigma, v, rank): #rank 表示截斷式SVD的保留的奇異值個數
    m = len(u)
    n = len(v)
    a = np.zeros((m, n))
    k = 0
while k < rank: uk = u[:, k].reshape(m, 1) vk = v[k].reshape(1, n) a += sigma[k] * np.dot(uk, vk) k += 1 a[a < 0] = 0 a[a > 255] = 255 return a.astype("uint8") def get_svd_image(file_path): name, suffix = file_path.split(".") img = Image.open(file_path, 'r'
) a = np.array(img) u0, sigma0, v0 = np.linalg.svd(a[:, :, 0]) u1, sigma1, v1 = np.linalg.svd(a[:, :, 1]) u2, sigma2, v2 = np.linalg.svd(a[:, :, 2]) print("origin image \n red rank:",len(sigma0), " green_rank:", len(sigma1)," blue_rank:", len(sigma2)) for rank in np.arange(5
, 50, 5): red_matrix = get_approx_matrix(u0, sigma0, v0, rank) green_matrix = get_approx_matrix(u1, sigma1, v1, rank) blue_matrix = get_approx_matrix(u2, sigma2, v2, rank) I = np.stack((red_matrix, green_matrix, blue_matrix), 2) Image.fromarray(I).save(name + str(rank) + "." +suffix) get_svd_image("gakki.png") plt.figure(figsize=(20,20)) for i in range(1, 10, 1): ax = plt.subplot(3,3,i) img = mpimg.imread("gakki_" + str(i*5) + ".png") ax.imshow(img) ax.set_title("rank:"+str(i*5)) ax.set_axis_off() plt.savefig('gakki_svd_compare.png') plt.show()

下面就是gakki的效果圖啦
這裡寫圖片描述