上一篇我们看到了SVD分解为旋转、缩放、旋转等三个步骤。
https://blog.csdn.net/bashendixie5/article/details/124302156https://blog.csdn.net/bashendixie5/article/details/124302156 在这个例子中,我们将使用 SVD 从图像中提取更重要的特征。可以直观看到SVD对视觉效果的影响。
让我们首先在 python 中加载图像并将其转换为 Numpy 数组。 然后将其转换为灰度,以使每个像素具有一维。 矩阵的形状对应于填充有强度值的图像的尺寸:每个像素 1 个单元。
from PIL import Image
plt.style.use('classic')
img = Image.open('test_svd.jpg')
# convert image to grayscale
imggray = img.convert('LA')
# convert to numpy array
imgmat = np.array(list(imggray.getdata(band=0)), float)
# Reshape according to orginal image dimensions
imgmat.shape = (imggray.size[1], imggray.size[0])
plt.figure(figsize=(9, 6))
plt.imshow(imgmat, cmap='gray')
plt.show()
我们测试 SVD 对图片的影响! 让我们开始提取左奇异向量、奇异值和右奇异向量:
U, D, V = np.linalg.svd(imgmat)
我们看一下得到数据的形状
原图的形状为
(669, 1000)
U.shape
(669, 669)
D.shape
(669,)
V.shape
(1000, 1000)
D是需要放入对角矩阵的奇异值。 另外V 不需要转置。
奇异向量和奇异值按照与解释的更多方差相对应的第一个进行排序。出于这个原因,仅使用前几个奇异向量和奇异值将提供图像主要元素的重建。
我们可以从U、D、V等重建图像,但是数量可以选择。例如,对于 2 个奇异值,我们将有:
在下面这个例子中,我们从两个奇异值重建了 699 x 1000 像素的图像。
reconstimg = np.matrix(U[:, :2]) * np.diag(D[:2]) * np.matrix(V[:2, :])
plt.imshow(reconstimg, cmap='gray')
plt.show()
下面我们将使用不同数量的奇异值绘制重建。
for i in [5, 10, 15, 20, 30, 50]:
reconstimg = np.matrix(U[:, :i]) * np.diag(D[:i]) * np.matrix(V[:i, :])
plt.imshow(reconstimg, cmap='gray')
title = "n = %s" % i
plt.title(title)
plt.show()
n=5
n=10
......
n=50