计算机视觉之PCA和特征脸

计算机视觉之PCA和特征脸

主成分分析(PCA)是一种统计/非监督机器学习方法,它使用一个正交变换将一组可能相关的变量的观测值转化为一组线性不相关的变量的值(称为主成分),从而在数据集中发现最大方向的方差(沿着主成分)。这可以用于(线性)降维(只有几个突出的主成分在大多数情况下捕获数据集中的几乎所有方差)和具有多个维度的数据集的可视化(在二维空间中)。PCA 的一个应用是特征脸,找到一组可以(从理论上)表示任意脸(作为这些特征脸的线性组合)的特征脸。

1.用 PCA 降维及可视化

我们将使用 scikit-learn 的数字数据集,其中包含 1797 张手写数字图像(每张图像大小为 8×8)。每一行表示数据矩阵中的一幅图像。用下面的代码加载并显示数据集中的前 25 位数字:

import numpy as np
import matplotlib.pylab as plt
from  matplotlib  import pylab
from sklearn.datasets import load_digits
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
digits = load_digits()

print(digits.data.shape)
j = 1
np.random.seed(2)
fig = plt.figure(figsize=(3,3))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05,wspace=0.05)

for i in np.random.choice(digits.data.shape[0], 25):
     plt.subplot(5,5,j), plt.imshow(np.reshape(digits.data[i,:], (8,8)),cmap='binary'), plt.axis('off')
     j += 1
plt.show()

运行上述代码,输出数据集中的前 25 位手写数字,如图:

计算机视觉之PCA和特征脸

2.二维投影和可视化

从加载的数据集可以看出,它是一个 64 维的数据集。现在,首先利用scikit-learn 的 PCA()函数来找到这个数据集的两个主成分并将数据集沿着两个维度进行投影;其次利用 matplotlib 和表示图像(数字)的每个数据点,对投影数据进行散点绘图,数字标签用一种独特的颜色表示,如下面的代码所示:

plt.show()
pca_digits=PCA(2)
digits.data_proj = pca_digits.fit_transform(digits.data)
print(np.sum(pca_digits.explained_variance_ratio_))

plt.figure(figsize=(15,10))
plt.scatter(digits.data_proj[:, 0], digits.data_proj[:, 1], lw=0.25, c=digits.target, edgecolor='k', s=100, cmap=plt.cm.get_cmap('cubehelix',10))
plt.xlabel('PC1', size=20), plt.ylabel('PC2', size=20), plt.title('2D Projection of handwritten digits with PCA', size=25)
plt.colorbar(ticks=range(10), label='digit value')
plt.clim(-0.5, 9.5)

计算机视觉之PCA和特征脸

3.基于 PCA 的特征脸

加载 scikit-learn 包的 olivetti 人脸数据集,其中包含 400 张人脸图像,每
张图像大小为 64×64。如下代码显示了数据集中的一些随机人脸:


from sklearn.datasets import fetch_olivetti_faces
faces = fetch_olivetti_faces().data
print(faces.shape)
fig = plt.figure(figsize=(5,5))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05, wspace=0.05)

j = 1
np.random.seed(0)
for i in np.random.choice(range(faces.shape[0]), 25):
     ax = fig.add_subplot(5, 5, j, xticks=[], yticks=[])
     ax.imshow(np.reshape(faces[i,:],(64,64)), cmap=plt.cm.bone,interpolation='nearest')
     j += 1
plt.show()

计算机视觉之PCA和特征脸
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.pipeline import Pipeline
n_comp =64
pipeline = Pipeline([('scaling', StandardScaler()), ('pca',PCA(n_components=n_comp))])
faces_proj = pipeline.fit_transform(faces)
print(faces_proj.shape)

mean_face = np.reshape(pipeline.named_steps['scaling'].mean_, (64,64))
sd_face = np.reshape(np.sqrt(pipeline.named_steps['scaling'].var_),(64,64))
pylab.figure(figsize=(8, 6))
pylab.plot(np.cumsum(pipeline.named_steps['pca'].explained_variance_ratio_) , linewidth=2)
pylab.grid(), pylab.axis('tight'), pylab.xlabel('n_components'),
pylab.ylabel('cumulative explained_variance_ratio_')
pylab.show()
pylab.figure(figsize=(10,5))
pylab.subplot(121), pylab.imshow(mean_face, cmap=pylab.cm.bone),
pylab.axis('off'), pylab.title('Mean face')
pylab.subplot(122), pylab.imshow(sd_face, cmap=pylab.cm.bone),
pylab.axis('off'), pylab.title('SD face')
pylab.show()

计算机视觉之PCA和特征脸

计算机视觉之PCA和特征脸

(1)特征脸

在主成分分析的基础上,计算得到的两 PC 方向相互正交,每个 PC 包
含 4096 个像素,并且可以重建成 64×64 像素的图像。称这些主成分为特征脸(因为它们也是特征向量)。可以看出,特征脸代表了人脸的某些属性。如下代码用于显示一些计算出来的特征脸:

fig = plt.figure(figsize=(5,2))
fig.subplots_adjust(left=0, right=2, bottom=0, top=5, hspace=0.07,wspace=0.005)

for i in range(25):
     ax = fig.add_subplot(5, 5, i+1, xticks=[], yticks=[])
     ax.imshow(np.reshape(pipeline.named_steps['pca'].components_[i,:],(64,64)), cmap=plt.cm.bone, interpolation='nearest')
     plt.savefig("C:/Users/zhuyupeng/Desktop/新建文件夹/hsdh.png",bbox_inches = 'tight')

计算机视觉之PCA和特征脸
运行上述代码,输出前 25 张特征脸,如图所示

(2)重建。

如下代码演示了如何将每张人脸近似地表示成这 64 张主要特征脸的线性
组合。使用 scikit-learn 中的 inverse_transform()函数变换回到原空间,但是只基于这 64 张主要特征脸,而抛弃所有其他特征脸。


faces_inv_proj = pipeline.named_steps['pca'].inverse_transform(faces_proj)

fig = plt.figure(figsize=(5,5))
fig.subplots_adjust(left=0, right=1, bottom=0, top=1, hspace=0.05,wspace=0.05)

j = 1
np.random.seed(0)
for i in np.random.choice(range(faces.shape[0]), 25):
     ax = fig.add_subplot(5, 5, j, xticks=[], yticks=[])
     ax.imshow(mean_face + sd_face*np.reshape(faces_inv_proj,(400,64,64))[i,:], cmap=plt.cm.bone, interpolation='nearest')
     j += 1

计算机视觉之PCA和特征脸
运行上述代码,从 64 张特征脸中随机选择 25 张重建的人脸图像,如图 上 所示。可以看到,它们看起来很像原始的人脸(没有很多明显的错误)。如下代码有助于更近距离地观察原始人脸,并将其与重建后的人脸进行对比,代码的输出结果如下图所示。可以看到,重建后的人脸与原始人脸近似,但存在某种程度的失真。
orig_face = np.reshape(faces[0,:], (64,64))
reconst_face =np.reshape(faces_proj[0,:]@pipeline.named_steps['pca'].components_, (64,64))
reconst_face = mean_face + sd_face*reconst_face
plt.figure(figsize=(10,5))
plt.subplot(121), plt.imshow(orig_face, cmap=plt.cm.bone, interpolation='nearest'), plt.axis('off'), plt.title('original', size=20)
plt.subplot(122), plt.imshow(reconst_face, cmap=plt.cm.bone, interpolation='nearest'), plt.axis('off'), plt.title('reconstructed', size=20)
plt.show()

计算机视觉之PCA和特征脸

Original: https://blog.csdn.net/weixin_53339428/article/details/126668489
Author: 表型组学
Title: 计算机视觉之PCA和特征脸

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/623628/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球