天天看点

基于PCA简单的人脸识别opencv实现-图像处理学习笔记

思路简述

PCA即主成分分析。计算主成分的目的是将高维数据投影到较低维空间。给定 n 个变量的 m 个观察值,形成一个 n ′ m 的数据矩阵, n 通常比较大。

按自己的理解就是,将一个空间的数据投影到一个子空间里,实现降维,并且变换到特定的子空间,会使相似的数据聚合在一起,不同类的数据图像分开的远些(所以就用到变换空间),在这个子空间里实现数据的比较分析更容易些。

基于PCA简单的人脸识别opencv实现-图像处理学习笔记

实现步骤

1。读取训练样本

将人脸数据库加载到内存中,每幅图像用一个行向量表示,将所有数据库中图像用一个矩阵来表示。

for (int i = ;i <= ;i++)
    {
        data = imread(path +to_string(i)+"\\1.png", CV_LOAD_IMAGE_GRAYSCALE);
        data.reshape(1, 1).row(0).convertTo(row_tmp, CV_32FC1);
        row_copy(row_tmp, database, i *  - );

        data = imread(path + to_string(i) + "\\2.png", CV_LOAD_IMAGE_GRAYSCALE);
        data.reshape(1,1).row(0).convertTo(row_tmp, CV_32FC1);
        row_copy(row_tmp, database, i *  - );
    }
           

注意一定要读取灰度图,并且转换成CV_32FC1

求特征向量(特征脸)

int number_principal_compent = ;//保留最大的主成分数(特征向量数)(为对应特征值(贡献度)最大前十的特征向量)
                                      //构造pca数据结构
    PCA pca(database, Mat(), CV_PCA_DATA_AS_ROW, number_principal_compent);//Mat为掩码 对象为整个矩阵不用操作
    Mat eigenvectors = pca.eigenvectors.clone();
           

求出每个训练样本和测试样本在子空间中的投影系数

Mat cv=pca.project(database);

Mat test = pca.project(testimage);
           

计算每个训练样本和测试样本的欧式距离,取其中最小的为识别图片

vector< double > distance

for (int i = ;i < cv.rows;i++)
    {
        distance[i]=norm(test,cv.row(i));
    }
auto smallest = min_element(begin(distance), end(distance));
    cout << "min element is " << *smallest << " at position " << std::distance(std::begin(distance), smallest) << std::endl;