• opencv 人脸识别 (二)训练和识别


    上一篇中我们对训练数据做了一些预处理,检测出人脸并保存在piccolorx文件夹下(x=1,2,3,...类别号),本文做训练和识别。为了识别,首先将人脸训练数据 转为灰度、对齐、归一化,再放入分类器(EigenFaceRecognizer),最后用训练出的model进行predict。

    -----------------------------------------

    环境:vs2010+opencv 2.4.6.0

    特征:eigenface

    Input:一个人脸数据库,15个人,每人20个样本(左右)。

    Output:人脸检测,并识别出每张检测到的人脸。

    -----------------------------------------

    1. 为训练数据预处理( 转为灰度、对齐、归一化 )

    • 转为灰度和对齐是后面做训练时EigenFaceRecognizer的要求;
    • 归一化是防止光照带来的影响

    在上一篇的 2.2 Prehelper.cpp文件中加入函数

    void resizeandtogray(char* dir,int k,  vector<Mat> &images, vector<int> &labels,
    vector<Mat> &testimages, vector<int> &testlabels);

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. void resizeandtogray(char* dir,int K, vector<Mat> &images, vector<int> &labels,  
    2.     vector<Mat> &testimages, vector<int> &testlabels)  
    3. {  
    4.     IplImage* standard = cvLoadImage("D:\privacy\picture\photo\2.jpg",CV_LOAD_IMAGE_GRAYSCALE);  
    5.     string cur_dir;  
    6.     char id[5];  
    7.     int i,j;  
    8.     for(int i=1; i<=K; i++)  
    9.     {  
    10.         cur_dir = dir;  
    11.         cur_dir.append("gray\");     
    12.         _itoa(i,id,10);  
    13.         cur_dir.append(id);  
    14.         const char* dd = cur_dir.c_str();  
    15.         CStatDir statdir;  
    16.         if (!statdir.SetInitDir(dd))  
    17.         {  
    18.             puts("Dir not exist");  
    19.             return;  
    20.         }  
    21.         cout<<"Processing samples in Class "<<i<<endl;  
    22.         vector<char*>file_vec = statdir.BeginBrowseFilenames("*.*");  
    23.         for (j=0;j<file_vec.size();j++)  
    24.         {  
    25.             IplImage* cur_img = cvLoadImage(file_vec[j],CV_LOAD_IMAGE_GRAYSCALE);  
    26.             cvResize(cur_img,standard,CV_INTER_AREA);  
    27.             Mat cur_mat = cvarrToMat(standard,true),des_mat;  
    28.             cv::normalize(cur_mat,des_mat,0, 255, NORM_MINMAX, CV_8UC1);  
    29.             cvSaveImage(file_vec[j],cvCloneImage(&(IplImage) des_mat));  
    30.             if(j!=file_vec.size())  
    31.             {  
    32.                     images.push_back(des_mat);  
    33.                     labels.push_back(i);  
    34.             }  
    35.             else  
    36.             {  
    37.                 testimages.push_back(des_mat);  
    38.                 testlabels.push_back(i);  
    39.             }  
    40.         }  
    41.         cout<<file_vec.size()<<" images."<<endl;  
    42.     }  
    43. }  



    并在main中调用:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. int main( )  
    2. {  
    3.     CvCapture* capture = 0;  
    4.     Mat frame, frameCopy, image;  
    5.     string inputName;     
    6.     int mode;  
    7.   
    8.     char dir[256] = "D:\Courses\CV\Face_recognition\pic\";   
    9.     //preprocess_trainingdata(dir,K); //face_detection and extract to file  
    10.     vector<Mat> images,testimages;  
    11.     vector<int> labels,testlabels;  
    12.     resizeandtogray(dir,K,images,labels,testimages,testlabels); //togray, normalize and resize  
    13.       
    14.     system("pause");  
    15.     return 0;  
    16. }  





    2. 训练

    有了vector<Mat> images,testimages; vector<int> labels,testlabels; 可以开始训练了,我们采用EigenFaceRecognizer建模。

    在Prehelper.cpp中加入函数

    Ptr<FaceRecognizer> Recognition(vector<Mat> images, vector<int> labels,vector<Mat> testimages, vector<int> testlabels);

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. Ptr<FaceRecognizer> Recognition(vector<Mat> images, vector<int> labels,  
    2.     vector<Mat> testimages, vector<int> testlabels)  
    3. {  
    4.     Ptr<FaceRecognizer> model = createEigenFaceRecognizer(10);//10 Principal components  
    5.     cout<<"train"<<endl;  
    6.     model->train(images,labels);  
    7.     int i,acc=0,predict_l;  
    8.     for (i=0;i<testimages.size();i++)  
    9.     {  
    10.         predict_l = model->predict(testimages[i]);  
    11.         if(predict_l != testlabels[i])  
    12.         {  
    13.             cout<<"An error in recognition: sample "<<i+1<<", predict "<<  
    14.                 predict_l<<", groundtruth "<<testlabels[i]<<endl;  
    15.             imshow("error 1",testimages[i]);  
    16.             waitKey();  
    17.         }  
    18.         else  
    19.             acc++;  
    20.     }  
    21.     cout<<"Recognition Rate: "<<acc*1.0/testimages.size()<<endl;  
    22.     return model;  
    23. }  




    Recognization()输出分错的样本和正确率,最后返回建模结果Ptr<FaceRecognizer> model

    主函数改为:

    [cpp] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. int main( )  
    2. {  
    3.     CvCapture* capture = 0;  
    4.     Mat frame, frameCopy, image;  
    5.     string inputName;     
    6.     int mode;  
    7.   
    8.     char dir[256] = "D:\Courses\CV\Face_recognition\pic\";   
    9.     //preprocess_trainingdata(dir,K); //face_detection and extract to file  
    10.     vector<Mat> images,testimages;  
    11.     vector<int> labels,testlabels;  
    12.     //togray, normalize and resize; load to images,labels,testimages,testlabels  
    13.     resizeandtogray(dir,K,images,labels,testimages,testlabels);   
    14.     //recognition  
    15.     Ptr<FaceRecognizer> model = Recognition(images,labels,testimages,testlabels);  
    16.     char* dirmodel = new char [256];  
    17.     strcpy(dirmodel,dir); strcat(dirmodel,"model.out");  
    18.     FILE* f = fopen(dirmodel,"w");  
    19.     fwrite(model,sizeof(model),1,f);  
    20.     system("pause");  
    21.     return 0;  
    22. }  



    最终结果:一个错分样本,正确率93.3%

    文章所用代码打包链接:http://download.csdn.net/detail/abcjennifer/7047853

    from: http://blog.csdn.net/abcjennifer/article/details/20446077

  • 相关阅读:
    NOI 2016 区间 解题报告
    有关莫队
    [JSOI2008]最大数 线段树解法
    HDU P3341 Lost's revenge 题解+数据生成器
    BZOJ P1212 [HNOI2004] L语言
    洛谷P3168 [CQOI2015]任务查询系统
    普通平衡树Tyvj1728、luogu P3369 (splay)
    洛谷P3384 树链剖分
    BZOJ P2157 旅游
    【算法导论】第6章,堆排序
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5354736.html
Copyright © 2020-2023  润新知