1 回答

TA貢獻1860條經驗 獲得超9個贊
如果您繪制s
奇異值,您可以看到一條非常陡峭的下降曲線,如果您對 y 軸使用對數刻度則更好:
plt.semilogy(s, 'k-')
如您所見,前 50 個奇異值是最重要的:幾乎每個奇異值都超過 1000。從 ~50 到 ~250 的值低一個數量級,并且它們的值緩慢下降:包含曲線的斜率(記住對數 y 標度)。那個蜜蜂說我會用前 50 個元素來重塑你的形象。
關于動畫:當動畫逐幀更新時,計數器i
增加 1。在您的代碼中,您錯誤地使用了i
切片s
和定義S
;你應該重命名柜臺。
此外,隨著動畫的進行,您需要采用越來越多的奇異值,這是n
逐幀保持不變的設置。您需要n
在每個循環中更新,因此您可以將其用作計數器。
此外,您需要擦除之前繪制的圖像,因此您需要plt.gca().cla()
在函數的開頭添加一個update
。
檢查下面的代碼以供參考:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
img = Image.open('steve.jpg')
img = np.mean(img, 2)
U,s,V = np.linalg.svd(img)
fig, ax = plt.subplots(1, 2, figsize = (4, 4))
ax[0].imshow(img)
ax[0].axis('off')
ax[0].set_title('Original')
def init():
ax[1].cla()
ax[1].imshow(np.zeros(np.shape(img)))
ax[1].axis('off')
ax[1].set_title('Reconstructed\nn = 00')
def update(n):
ax[1].cla()
S = np.zeros(np.shape(img))
for i in range(0, n):
S[i, i] = s[i]
recon_img = U@S@V
ax[1].imshow(recon_img)
ax[1].axis('off')
ax[1].set_title(f'Reconstructed\nn = {n:02}')
ani = FuncAnimation(fig = fig, func = update, frames = 50, init_func = init, interval = 10)
ani.save('ani.gif', writer = 'imagemagick')
plt.show()
這給了這個動畫:
https://i.stack.imgur.com/6loY5.gif
如您所見,前 50 個元素足以很好地重建圖像。其余元素增加了一些噪音并稍微改變了背景。
添加回答
舉報