利用PCA对人脸图像进行降维与重建
1.引言
人脸识别是计算机视觉中的经典问题,图像数据维度往往很高,直接处理不仅计算量大,还可能包含大量冗余信息。主成分分析(PCA)是一种经典的降维方法,通过找到数据中的主要变化方向,将高维数据映射到低维空间,同时保留大部分信息。
2. PCA的核心原理
PCA,全称Principal Component Analysis,中文名“主成分分析”,其核心思想是:
通过线性变换,将原始高维数据投影到一个新的坐标系;
这个新坐标系的轴(主成分)是按照数据方差大小排序的,第一主成分代表最大方差方向;
通过选取前几个主成分,达到压缩数据维度的目的,同时最大限度保留数据的特征信息。
简单来说,PCA帮我们找到了数据“最重要的几个方向”,扔掉噪声和冗余,降低计算复杂度。
3. 实现细节
数据准备
我们有40个人脸,每人12张 .pgm 格式灰度图像,存放在 face_dataset/s1 到 face_dataset/s40 文件夹内。
每张图像大小相同,转换成一维向量后,构成我们的样本数据。
代码流程
- 读取数据:遍历所有文件夹,加载 .pgm 图像,转成向量。
- 划分数据集:用 train_test_split 按8:2划分训练集和测试集。
- PCA降维:对训练集进行PCA降维,抽取20个主成分。
- 重建图像:用降维后的数据恢复图像,观察降维损失。
- 可视化:展示原始图像和PCA重建图像对比。
4. 代码展示
import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
def load_images(dataset_path):
X, y = [], []
for label in range(1, 41):
folder = os.path.join(dataset_path, f"s{label}")
for img_file in os.listdir(folder):
if img_file.endswith('.pgm'):
img = cv2.imread(os.path.join(folder, img_file), cv2.IMREAD_GRAYSCALE)
X.append(img.flatten())
y.append(label)
return np.array(X), np.array(y), img.shape
def apply_pca(X, n_components=20):
pca = PCA(n_components=n_components)
X_pca = pca.fit_transform(X)
return X_pca, pca
def visualize_multiple_pca_reconstructions(X, X_pca, pca, shape, n=5):
reconstructed = pca.inverse_transform(X_pca[:n])
fig, axes = plt.subplots(n, 2, figsize=(6, 2*n))
for i in range(n):
axes[i,0].imshow(X[i].reshape(shape), cmap='gray')
axes[i,0].set_title(f"原始图像 {i+1}")
axes[i,0].axis('off')
axes[i,1].imshow(reconstructed[i].reshape(shape), cmap='gray')
axes[i,1].set_title(f"PCA重建图像 {i+1}")
axes[i,1].axis('off')
plt.tight_layout()
plt.show()
def main():
dataset_path = 'face_dataset'
X, y, shape = load_images(dataset_path)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, stratify=y, random_state=42)
X_train_pca, pca = apply_pca(X_train, n_components=20)
X_test_pca = pca.transform(X_test)
visualize_multiple_pca_reconstructions(X_test, X_test_pca, pca, shape, n=5)
print("主成分数:", X_train_pca.shape[1])
print("方差解释率:", np.round(pca.explained_variance_ratio_, 4))
if __name__ == "__main__":
main()
5. 运行结果与总结
执行后,程序会展示测试集前5张图像的原始和PCA重建效果。
可以发现:
- 20个主成分已经足够保留图像的主要特征;
- 重建图像虽有细节丢失,但整体轮廓清晰;
- PCA有效降低了数据维度,方便后续的机器学习任务。