SVD在图像压缩中的应用

下面的代码运行环境为python3.6+jupyter5.4

'''利用SVD对图片进行重构,对比重构后的图片'''
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
'''加载图片'''
img_eg = mpimg.imread("./image/image1.jpg")
print(img_eg.shape)#图片的大小是600×400×3
img_temp = img_eg.reshape(640, 640*3)
print(img_temp.shape)
U, Sigma, VT = np.linalg.svd(img_temp)#奇异值分解
# print(Sigma)
#我们先将图片变成600×1200,再做奇异值分解。从svd函数中得到的奇异值sigma它是从大到小排列的
'''取前60个奇异值然后重构图片'''
sval_nums = 60
img_restruct1 = U[:, 0:sval_nums]@np.diag(Sigma[0:sval_nums])@VT[0:sval_nums, :]
print(img_restruct1.shape)

'''取前120个奇异值'''
sval_nums = 120
img_restruct2 = U[:, 0:sval_nums]@np.diag(Sigma[0:sval_nums])@VT[0:sval_nums, :]
print(img_restruct2.shape)


'''重构图片'''
img_restruct1 = img_restruct1.reshape(640, 640, 3)
img_restruct2 = img_restruct2.reshape(640, 640, 3)

#将图片显示出来看一下,对比下效果
fig, ax = plt.subplots(1, 3, figsize=(50, 32))
ax[0].imshow(img_eg)
ax[0].set(title="src")
ax[1].imshow(img_restruct1.astype(np.uint8))
ax[1].set(title="nums of sigma = 10")
ax[2].imshow(img_restruct2.astype(np.uint8))
ax[2].set(title="nums of sigma = 120")
fig1, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].plot(Sigma)
axes[1].plot(Sigma.cumsum())
plt.show()

可以看到,当我们取到前面120个奇异值来重构图片时,基本上已经看不出与原图片有多大的差别

奇异值可以看作是一个矩阵的代表值,奇异值越多越大时,代表信息越多,奇异值排列后,可以取前面若干大的的奇异值可以基本还原数据本身。

奇异值下降很快,取前面几个大的奇异值,可以基本还原矩阵信息。

参考文章:SVD(奇异值分解)小结 - EndlessCoding - 博客园 (cnblogs.com)

SVD(奇异值分解)小结 - 知乎 

猜你喜欢

转载自blog.csdn.net/weixin_44345862/article/details/128123665