基于ORL人脸数据库和PCA特征降维算法的人脸识别matlab仿真

Posted 51matlab

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于ORL人脸数据库和PCA特征降维算法的人脸识别matlab仿真相关的知识,希望对你有一定的参考价值。

1.算法仿真效果

matlab2022a仿真结果如下:

 

2.算法涉及理论知识概要

        人脸识别系统的研究始于20世纪60年代,80年代后随着计算机技术和光学成像技术的发展得到提高,而真正进入初级的应用阶段则在90年后期,并且以美国、德国和日本的技术实现为主;人脸识别系统成功的关键在于是否拥有尖端的核心算法,并使识别结果具有实用化的识别率和识别速度;“人脸识别系统”集成了人工智能、机器识别、机器学习、模型理论、专家系统、视频图像处理等多种专业技术,同时需结合中间值处理的理论与实现,是生物特征识别的最新应用,其核心技术的实现,展现了弱人工智能向强人工智能的转化。

 

      人脸识别 技术是指利用分析比较的计算机技术识别人脸。人脸识别是一项热门的计算机技术研究领域,其中包括人脸追踪侦测,自动调整影像放大,夜间红外侦测,自动调整曝光强度等技术。

人脸识别技术属于生物特征识别技术,是对生物体(一般特指人)本身的生物特征来区分生物体个体。人脸识别技术是基于人的脸部特征,对输入的人脸图像或者视频流,首先判断其是否存在人脸,如果存在人脸,则进一步的给出每个脸的位置、大小和各个主要面部器官的位置信息。并依据这些信息,进一步提取每个人脸中所蕴涵的身份特征,并将其与已知的人脸进行对比,从而识别每个人脸的身份。广义的人脸识别实际包括构建人脸识别系统的一系列相关技术,包括人脸图像采集、人脸定位、人脸识别预处理、身份确认以及身份查找等;而狭义的人脸识别特指通过人脸进行身份确认或者身份查找的技术或系统。生物特征识别技术所研究的生物特征包括脸、指纹、手掌纹、虹膜、视网膜、声音(语音)、体形、个人习惯(例如敲击键盘的力度和频率、签字)等,相应的识别技术就有人脸识别、指纹识别、掌纹识别、虹膜识别、视网膜识别、语音识别(用语音识别可以进行身份识别,也可以进行语音内容的识别,只有前者属于生物特征识别技术)、体形识别、键盘敲击识别、签字识别等。

 

        人脸识别训练集的人脸图像验选取剑桥大学ORL人脸数据库。一共40个人,每人10张人脸图像,随机选取7张用作训练,图像分辨率为112*92.将原始图像的每一行的像素串联在一起,产生一个具有112*92个元素的列向量,每个图像被视为一个向量。人脸原图片的尺寸是112 x 92,并横向的进行翻转、平移等-系列的操作来拓展数据集大小。0RL人脸数据库的样例如图3所示。

 

 

 

       然后,使所有的训练集的图像(一共40张)存储在一个单一的矩阵T中,矩阵的每一列是一个图像。减去均值向量. 均值向量a要首先计算,并且T中的每一个图像都要减掉均值向量。计算协方差矩阵S的特征值和特征向量。每一个特征向量的维数与原始图像的一致,因此可以被看作是一个图像。因此这些向量被称作特征脸。选择主成分。

 

       主成分分析(Principal Component AnalysisPCA), 是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。在实际课题中,为了全面分析问题,往往提出很多与此有关的变量(或因素),因为每个变量都在不同程度上反映这个课题的某些信息。主成分分析首先是由K.皮尔森(Karl Pearson)对非随机变量引入的,尔后H.霍特林将此方法推广到随机向量的情形。信息的大小通常用离差平方和或方差来衡量。

 

      一般选择最大的k个特征值,保留对应的特征向量。对每个训练图像的向量,投影到特征空间后得到一组坐标。对测试图像,也作同样的投影运算,得到坐标,与训练图像的坐标进行二范数最小匹配。

 

3.MATLAB核心程序

 

for i=1:40
    sub_dir = strcat(\'s\', num2str(i));
    images = cell(10);
    for j=1:10
        filename = fullfile(input_dir, sub_dir, strcat(num2str(j), \'.pgm\'));
        imagesj = imread(filename); 
    end
   
    images = images(randperm(10));
    
    img = zeros(image_dims);
    
    for j=1:7
        img = img + double(imagesj);
    end
    
    img = img / 7;
    train_images(:, i) = img(:);
    
    for j=8:10
        test_imagesi,j-7=imagesj;
    end
end
 
% steps 1: mean-shifted
mean_face = mean(train_images, 2);
shifted_images = train_images - repmat(mean_face, 1, num_images);
 
% steps 2: ordered eigenvectors and eigenvalues
[full_evectors, score, evalues] = pca(train_images\');
 
result = zeros(39, 2);
for num_eigenfaces = 1:39
    evectors = full_evectors(:, 1:num_eigenfaces);
    features = evectors\' * shifted_images;
 
    cnt = 0;
 
    for i=1:40
        for j=1:3
            input_image = double(test_imagesi,j);
...................................................................
            if match_ix == i
                cnt = cnt + 1;
            else
 
            end
        end
    end
    result(num_eigenfaces, 1) = cnt;
    result(num_eigenfaces, 2) = cnt / 120;
end
 
figure, plot(result(:, 2),\'-bs\',...
    \'LineWidth\',2,...
    \'MarkerSize\',8,...
    \'MarkerEdgeColor\',\'k\',...
    \'MarkerFaceColor\',[0.0,0.9,0.0]);
 
xlabel(\'特征维度\')
ylabel(\'识别率\')
xlim([1 39]), ylim([0 1]), grid on;

 

  

 

opencv学习之路(40)人脸识别算法——EigenFaceFisherFaceLBPH

一、人脸识别算法之特征脸方法(Eigenface)

1、原理介绍及数据收集

特征脸方法主要是基于PCA降维实现。

详细介绍和主要思想可以参考

http://blog.csdn.net/u010006643/article/details/46417127

上述博客的人脸数据库打不开了,大家可以去下面这个博客下载ORL人脸数据库

http://blog.csdn.net/xdzzju/article/details/50445160

下载后,ORL人脸数据库有40个人,每人10张照片。

2、流程

3、相关图示

 

4、代码

  1 #include <opencv2/opencv.hpp>
  2 #include <opencv2/face.hpp>
  3 
  4 using namespace cv;
  5 using namespace cv::face;
  6 using namespace std;
  7 
  8 //对原图归一化
  9 Mat normal(Mat src, Mat dst) {
 10     if (src.channels() == 1)//若原图单通道
 11         normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
 12     else //否则,原图三通道
 13         normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
 14     return dst;
 15 }
 16 
 17 void main() {
 18     //读取文件,转换为数据流
 19     string filename = string("at.txt");
 20     ifstream file(filename.c_str(), ifstream::in);
 21     if (!file)
 22         cout << "error" << endl;
 23 
 24     string line, path, classlabel;
 25     vector<Mat>image;
 26     vector<int>labels;
 27     char separator = \';\';
 28     while (getline(file,line))
 29     {
 30         stringstream liness(line);
 31         getline(liness, path, separator);
 32         getline(liness, classlabel);
 33         if (!path.empty()&&!classlabel.empty())
 34         {
 35             //cout << "path:" << path<< endl;
 36             image.push_back(imread(path, 0));
 37             labels.push_back(atoi(classlabel.c_str()));
 38         }
 39     }
 40 
 41     if (image.size() < 1 || labels.size() < 1)
 42         cout << "invalid image path..." << endl;
 43 
 44     int height = image[0].rows;
 45     int width = image[0].cols;
 46     //cout << "height:" << height << ",width:" << width<<endl;
 47 
 48     //最后一个人为测试样本
 49     Mat testSample = image[image.size() - 1];
 50     int testLabel = labels[labels.size() - 1];
 51     image.pop_back();
 52     labels.pop_back();
 53 
 54     //训练
 55     Ptr<BasicFaceRecognizer>model = createEigenFaceRecognizer();
 56     model->train(image, labels);
 57 
 58     //识别
 59     int predictLabel = model->predict(testSample);
 60     cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;
 61 
 62     //获得特征值,特征向量,均值    平均脸
 63     Mat eigenvalues = model->getEigenValues();
 64     Mat eigenvectors = model->getEigenVectors();
 65     Mat mean = model->getMean();
 66     Mat meanFace = mean.reshape(1,height);
 67     Mat dst;
 68     dst= normal(meanFace,dst);
 69     imshow("Mean Face", dst);
 70     
 71     //特征脸
 72     for (int i = 0; i < min(10,eigenvectors.cols); i++)
 73     {
 74         Mat ev = eigenvectors.col(i).clone();
 75         Mat eigenFace = ev.reshape(1, height);
 76         Mat grayscale;
 77         grayscale = normal(eigenFace, grayscale);
 78         Mat colorface;
 79         applyColorMap(grayscale, colorface, COLORMAP_BONE);
 80         char* winTitle = new char[128];
 81         sprintf(winTitle, "eigenface_%d", i);
 82         imshow(winTitle, colorface);
 83     }
 84 
 85     //重建人脸
 86     for (int num = min(10, eigenvectors.cols); num < min(300, eigenvectors.cols); num+=15)
 87     {
 88         Mat evs = Mat(eigenvectors, Range::all(), Range(0, num));
 89         Mat projection = LDA::subspaceProject(evs, mean, image[0].reshape(1, 1));
 90         Mat reconstruction= LDA::subspaceReconstruct(evs, mean, projection);
 91 
 92         Mat result = reconstruction.reshape(1, height);
 93         reconstruction = normal(result, reconstruction);
 94         char* winTitle = new char[128];
 95         sprintf(winTitle, "recon_face_%d", num);
 96         imshow(winTitle, reconstruction);
 97     }
 98     
 99     waitKey(0);
100 }

二、FisherFace(LDA线性判别分析)

1、理论介绍

http://blog.csdn.net/feirose/article/details/39552997

 

2、流程

3、PCA和LDA的对比

 

4、代码(与特征脸代码几乎一致)

此处只列出修改部分

55行模型训练    Ptr<BasicFaceRecognizer>model = createFisherFaceRecognizer();

72行显示特征脸  for (int i = 0; i < min(16,eigenvectors.cols); i++)
                   Mat ev = eigenvectors.col(i).clone();

86行重建人脸    for (int num = 0; num < min(16, eigenvectors.cols); num++)

三、LBPH

 1、原理介绍

大家可以参考http://blog.csdn.net/xiaomaishiwoa/article/details/46640377

二、流程

3、代码

#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>

using namespace cv;
using namespace cv::face;
using namespace std;

//对原图归一化
Mat normal(Mat src, Mat dst) {
    if (src.channels() == 1)//若原图单通道
        normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
    else //否则,原图三通道
        normalize(src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
    return dst;
}

void main() {
    //读取文件,转换为数据流
    string filename = string("at.txt");
    ifstream file(filename.c_str(), ifstream::in);
    if (!file)
        cout << "error" << endl;

    string line, path, classlabel;
    vector<Mat>image;
    vector<int>labels;
    char separator = \';\';
    while (getline(file,line))
    {
        stringstream liness(line);
        getline(liness, path, separator);
        getline(liness, classlabel);
        if (!path.empty()&&!classlabel.empty())
        {
            //cout << "path:" << path<< endl;
            image.push_back(imread(path, 0));
            labels.push_back(atoi(classlabel.c_str()));
        }
    }

    if (image.size() < 1 || labels.size() < 1)
        cout << "invalid image path..." << endl;

    int height = image[0].rows;
    int width = image[0].cols;
    //cout << "height:" << height << ",width:" << width<<endl;

    //最后一个人为测试样本
    Mat testSample = image[image.size() - 1];
    int testLabel = labels[labels.size() - 1];
    image.pop_back();
    labels.pop_back();

    //训练
    Ptr<LBPHFaceRecognizer>model = createLBPHFaceRecognizer();
    model->train(image, labels);

    //识别
    int predictLabel = model->predict(testSample);
    cout << "actual label:" << testLabel << ",predict label:" << predictLabel << endl;

    //打印参数
    int radius = model->getRadius();    //中心像素点到周围像素点的距离
    int neibs = model->getNeighbors();    //周围像素点的个数
    int grad_x = model->getGridX();        //将一张图片在x方向分成几块
    int grad_y = model->getGridY();        //将一张图片在y方向分成几块
    double t = model->getThreshold();    //相似度阈值    
    cout << "radius:" << radius << endl;
    cout << "neibs:" << neibs << endl;
    cout << "grad_x:" << grad_x << endl;
    cout << "grad_y:" << grad_y << endl;
    cout << "threshold:" << t<<endl;
    
    waitKey(0);
}

 

以上是关于基于ORL人脸数据库和PCA特征降维算法的人脸识别matlab仿真的主要内容,如果未能解决你的问题,请参考以下文章

opencv学习之路(40)人脸识别算法——EigenFaceFisherFaceLBPH

人脸识别---基于深度学习和稀疏表达的人脸识别算法

人脸识别---基于深度学习和稀疏表达的人脸识别算法

人脸识别基于PCA+SVM人脸识别(准确率)matlab源码含GUI

人脸识别基于matlab GUI PCA人脸识别(识别率)含Matlab源码 802期

人脸识别基于matlab GUI PCA人脸二维码识别含Matlab源码 754期