【Python】基于SVD的特征脸(Eigenface)方法

前言
  最近在写关于特征脸的作业,参考了网络上的众多资料后,终于弄出来了,由于作业只要求了打印平均脸和特征脸,因此在图像匹配和识别方面我没有实现。
  网络上有许多的文章对特征脸方法的原理讲得很透彻,本文就不对其进行解释了。

参考资料
深度学习笔记系列(二):特征值,特征向量与SVD奇异值分解
新手入门eigenface以及python实现
人脸识别算法一:特征脸方法(Eigenface)


一、人脸图片

图片我选的是耶鲁大学的YaleFace人脸数据集,这个数据集非常经典,很适合用于人脸识别方面。部分图片如下所示:
【Python】基于SVD的特征脸(Eigenface)方法_第1张图片
为了让结果更好看,我程序使用的是经过预处理后的图片,所谓预处理是对人脸部分裁剪成100*100的图片,再选取了标签为“normal”的人脸图像。最终使用的数据集如下所示:
【Python】基于SVD的特征脸(Eigenface)方法_第2张图片

二、程序源代码部分

在源码方面我加了很多的注释,就不拆开讲了

import cv2
import os
import numpy as np
from matplotlib import pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 读取图像,进行预处理,返回拉平后的图像数据
def ProcessImage(src):
    faces = []  # 人脸图像集
    files = os.listdir(src)
    # 读取图片文件,并加入图像集
    for filename in files:
        img = cv2.imread(os.path.join(src, filename), 0)
        faces.append(img)
    # 将图像转为数组
    image_array = np.array(faces)
    number = image_array.shape[0:1]
    # 设置图片大小
    global img_Size
    img_Size = image_array.shape[1:3]
    new_image_array = []
    # 将单个图像数组拉平成一维数组
    for i in range(number[0]):
        new_image_array.append(image_array[i].flatten())
    return np.array(new_image_array)


# 计算每一行平均值,形成一个新的行矩阵
def GetAverage(flattened_images):
    return np.mean(flattened_images, axis=0).astype(np.uint8)


# 将拉平后的数据还原
def GetBack(array):
    global img_Size
    array_ = np.array(array)
    img = array_.reshape(img_Size)
    return img


# 显示平均脸
def ShowAverageFace(arr):
    image = GetBack(arr)
    plt.imshow(image, cmap='gray')
    plt.axis('off')
    plt.show()


# 显示特征值前15的特征脸
def ShowEigenFace(eigenvalues, eigenvectors):
    # 获得降序排列特征值的序号
    orderly_id = np.argsort(-eigenvalues)
    # 输出特征值前15对应的特征脸
    for face_id in range(15):
        temp = eigenvectors[orderly_id[face_id]]
        eigen_face_data = np.array(temp)
        # 还原数据
        eigen_face = GetBack(eigen_face_data)
        # 输出特征脸
        plt.subplot(3, 5, face_id + 1)  # 三排五个
        plt.imshow(eigen_face)
        plt.axis('off')
        plt.imshow(eigen_face, cmap='gray')
    plt.show()


if __name__ == '__main__':
    # 人脸图像相对路径
    img_src = "./Images/"
    # 图像大小
    global img_Size
    # 1、数据预处理,得到拉平数据
    flattened_images = ProcessImage(img_src)
    # 2、计算平均脸
    average_face = GetAverage(flattened_images)
    # 3、显示平均脸
    ShowAverageFace(average_face)
    # 4、通过SVD奇异值分解得到矩阵的特征值和特征向量
    U, eigen_values, eigen_vectors = np.linalg.svd(flattened_images, full_matrices=False, compute_uv=True)
    # 5、显示特征值前15的特征脸
    ShowEigenFace(eigen_values, eigen_vectors)

三、程序结果

平均脸:
【Python】基于SVD的特征脸(Eigenface)方法_第3张图片
特征值排前十五的特征脸:
【Python】基于SVD的特征脸(Eigenface)方法_第4张图片

本文的源代码和使用的图片资源我上传到了CSDN,下载所需积分都设置为了0积分,可免费下载。
源码: 基于SVD的特征脸(Eigenface)方法源码
图片资源: YaleFace人脸数据集

你可能感兴趣的:(Python,python,opencv,图像处理)