• 图像处理项目——人脸检测—训练


    训练模型

    *开发环境为visual studio2010
    *使用的数据集是face.txt
    *用到Facerecognizer类。opencv中所有的人脸识别模型都是来源于这个类。

    一:主要步骤
    1.创建了一个特征脸模型用于人脸识别
    2.通过CSV文件face.txt读取的图像和标签训练它 
    3.创建一个PCA人脸分类器,T这里是一个完整的PCA变换
    4.调用其中的成员函数train()来完成分类器的训练

    二:代码
      1 #include <opencv2/opencv.hpp>
      2 #include <opencv2/core/core.hpp>
      3 #include "opencv2/face/facerec.hpp"
      4 #include "opencv2/face.hpp"
      5 #include "opencv2/core.hpp"
      6 #include "opencv2/highgui.hpp"
      7 #include "opencv2/imgproc.hpp"
      8 #include <iostream>
      9 #include <fstream>                    
     10 #include <sstream>                    
     11 #include <math.h>                     
     12 using namespace cv;
     13 using namespace cv::face;
     14 using namespace std;
     15 
     16 static Mat norm_0_255(InputArray _src)
     17 {
     18    Mat src = _src.getMat();                
     19    // 创建和返回一个归一化后的图像矩阵: 
     20    Mat dst;
     21    switch (src.channels())
     22    {
     23      case 1:
     24        cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1);
     25        break;
     26      case 3:
     27        cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3);
     28        break;
     29      default:
     30        src.copyTo(dst);
     31        break;
     32    }
     33    return dst;
     34 }
     35 
     36 //使用CSV文件去读图像和标签,主要使用stringstream和getline方法  
     37 static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';')
     38 {
     39     std::ifstream file(filename.c_str(), ifstream::in);//c_str()函数可用可不用,无需返回一个标准C类型的字符串
     40     if(!file)
     41     {
     42       string error_message = "No valid input file was given, please check the given filename.";
     43       CV_Error(CV_StsBadArg, error_message);
     44     }
     45     string line, path, classlabel;
     46     while(getline(file,line))                   //从文本文件中读取一行字符,未指定限定符默认限定符为“/n”�
     47     {
     48        stringstream liness(line);
     49        getline(liness, path, separator);      //这里采用stringstream主要作用是做字符串的分割
     50        getline(liness,classlabel);             //读入图片文件路径以分好作为限定符
     51        if (!path.empty() && !classlabel.empty())
     52        {
     53           images.push_back(imread(path,0));
     54           labels.push_back(atoi(classlabel.c_str()));///如果读取成功,则将图片和对应标签压入对应容器中
     55 
     56        }
     57 
     58     }
     59 }
     60 
     61 int main()
     62 {
     63  //读取你的CSV文件路径. 
     64   string fn_csv = "face.txt";
     65   
     66   // 2个容器来存放图像数据和对应的标签
     67   vector<Mat> images;
     68   vector<int> labels;
     69 
     70   // 读取数据. 如果文件不合法就会出错  
     71 
     72   try 
     73   {
     74     read_csv(fn_csv, images, labels);
     75   }
     76   catch (cv::Exception& e)
     77   {
     78     cerr << "Error opening file "" << fn_csv << "".Reason: " << e.msg << endl;
     79     exit(1);
     80   }
     81   // 如果没有读取到足够图片,也退出.  
     82   if(images.size() <= 1)
     83   {
     84     string error_message = " Please add more images to your data set!";
     85     CV_Error(CV_StsError, error_message);
     86   }
     87   
     88   for (int i = 0; i < images.size(); i++)
     89   {
     90        if(images[i].size() != Size(92, 112))
     91        {
     92            cout << i << endl;
     93            cout << images[i].size() << endl;
     94        }
     95   }
     96   // 下面的几行代码仅仅是从你的数据集中移除最后一张图片,作为测试图片  
     97   //[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]  
     98   Mat testSample = images[images.size() - 1];
     99   int testLabel = labels[labels.size() - 1];
    100   images.pop_back();    //删除最后一张照片,此照片作为测试图片
    101   labels.pop_back();    //删除最有一张照片的labels
    102 
    103     // 创建了一个特征脸模型用于人脸识别,  
    104     // 通过CSV文件读取的图像和标签训练它。  
    105     // T这里是一个完整的PCA变换  
    106     //创建一个PCA人脸分类器,
    107     //调用其中的成员函数train()来完成分类器的训练
    108   Ptr<BasicFaceRecognizer> model0 = createEigenFaceRecognizer();
    109   model0->train(images,labels);
    110 
    111   //save the model to .xml
    112   model0->save("MyEigenFaces.xml");
    113 
    114   Ptr<BasicFaceRecognizer> model1 = createFisherFaceRecognizer();
    115   model1->train(images,labels);
    116   model1->save("MyFaceModel.xml");
    117 
    118     // 还有一种调用方式,可以获取结果同时得到阈值:  
    119     // int predictedLabel = -1;  
    120     // double confidence = 0.0;  
    121     //  model->predict(testSample, predictedLabel, confidence); 
    122     
    123   int predictedLabel0 = model0->predict(testSample);
    124   int predictedLabel1 = model1->predict(testSample);
    125   int predictedLabel2 = model2->predict(testSample);
    126  
    127   string result_message0 = format("Predicted class = %d / Actual class = %d.",predictedLabel0, testLabel);
    128   string result_message1 = format("Predicted class = %d / Actual class = %d.",predictedLabel1, testLabel);
    129   string result_message2 = format("Predicted class = %d / Actual class = %d.",predictedLabel2, testLabel);
    130 
    131   cout << result_message0 << endl;
    132   cout << result_message1 << endl;
    133   cout << result_message2 << endl;
    134 
    135   waitKey(0);
    136   return 0;
    137 }

    三:训练结果

    生成了MyFaceModel.xml文件,可以直接使用进行人脸识别

     

     
    萍水相逢逢萍水,浮萍之水水浮萍!
  • 相关阅读:
    php中的高危函数
    PHP 站点相对包含,路径的问题解决方法(include,require)
    PHP中::、-&gt;、self、$this操作符的区别
    C#常用类库(100多个)
    Android滑动菜单特效实现,仿人人客户端侧滑效果,史上最简单的侧滑实现
    转载:Android调用相册、拍照实现缩放、切割图片
    在浏览器上直接输入url 时,中文传参乱码问题
    一个asp采集程序
    c#微信开发 转
    如何使用JS来检测游览器是什么类型,或android是什么版本号- 转载
  • 原文地址:https://www.cnblogs.com/AIBigTruth/p/10550305.html
Copyright © 2020-2023  润新知