ROS_train.cpp

說明:
這個程序的作用是:
利用opencv的三個訓練模型:
EigenFaceRecognizer,
FisherFaceRecognizer,
LBPHFaceRecognizer
對已有的圖片庫進行訓練, 保存得到的結果(三個model) ,同時利用三個model對待檢測的 人臉做出評估, 主要是爲了得出 訓練的模型,方便後面的人倆識別使用。

#include<ros/ros.h>

#include "opencv2/core.hpp"
#include "opencv2/face.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"

#include<iostream>
#include<fstream>
#include<sstream>
#include<math.h>

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

static Mat norm_0_255(InputArray _src)
{
  Mat src = _src.getMat();
  Mat dst;
  switch(src.channels())
  {
    case 1:
      cv::normalize(_src,dst,0,255,NORM_MINMAX,CV_8UC1);
      break;
    case 3:
      cv::normalize(_src,dst,0,255,NORM_MINMAX,CV_8UC3);
      break;
    default:
      src.copyTo(dst);
      break;
  }
  return dst;
}

//爲了讀進來所有的人的臉的圖片
static void read_csv(const string& filename,vector<Mat>& images,vector<int> &labels,char separator=';')
{
  std::ifstream file(filename.c_str(),ifstream::in); //c++語法,聲明一個對文件只讀的流
  if(!file)
  {
   string err_message = "No valid input file";
   cout<<err_message<<endl;
  }
  string line,path,classlabel;
  
  while(getline(file,line))
  {
    stringstream liness(line);
    getline(liness,path,separator);
    getline(liness,classlabel);
    if(!path.empty() && !classlabel.empty())
    {
       images.push_back(imread(path,0));
       labels.push_back(atoi(classlabel.c_str()));
    }
  }

}

int main(int argc,char *argv[])
{ 
  ros::init(argc,argv,"train");
  string fn_csv; 
  string eigenmodel;
  string fishermodel;
  string lbpmodel;
  vector<Mat> images;
  vector<int> labels;
  ros::NodeHandle n;
  n.getParam("/train/tagpath",fn_csv);       //  預先準備的一些人臉圖像
  n.getParam("/train/ ",eigenmodel);
  n.getParam("/train/fishermodel",fishermodel);
  n.getParam("/train/lbpmodel",lbpmodel);
  try
  {
    read_csv(fn_csv,images,labels);  //讀進來預先準備的所有的照片
  }
  catch(cv::Exception& e)
  {
    //read err
    ROS_INFO("Read at.txt error");
    exit(1);
  }
  
  if(images.size()<=1)
  {
    //too small
    ROS_INFO("too few photos");
  }
  
//先拿最後一個作爲檢驗的人臉,注意這裏不一定是 你的人臉,因爲at.txt不是按順序寫的
  Mat testSample = images[images.size()-1];
  int testLabel = labels[labels.size()-1];

  images.pop_back();   //刪去一個圖片用來檢驗
  labels.pop_back();
  
  //opencv三種訓練 , model 是一堆數,這就是我們的訓練結果 , 我們順便把這個訓練結果保存到 xml 文件
  Ptr<BasicFaceRecognizer> model = EigenFaceRecognizer::create();
  model->train(images,labels);
  model->save(eigenmodel);

  Ptr<BasicFaceRecognizer> model1 = FisherFaceRecognizer::create();
  model1->train(images,labels);
  model1->save(fishermodel);

  Ptr<LBPHFaceRecognizer> model2 = LBPHFaceRecognizer::create();
  model2->train(images,labels);
  model2->save(lbpmodel);
  
  //利用剛纔的模型,對待檢測的照片進行檢測
  int predictedLabel = model->predict(testSample);        
  int predictedLabel1 = model1->predict(testSample);
  int predictedLabel2 = model2->predict(testSample);

  string result_message = format("predicted class = %d / actual class = %d",predictedLabel,testLabel);
  string result_message1 = format("predicted class = %d / actual class = %d",predictedLabel1,testLabel);
  string result_message2 = format("predicted class = %d / actual class = %d",predictedLabel2,testLabel);
  
  cout<<result_message<<endl;
  cout<<result_message1<<endl;
  cout<<result_message2<<endl;

  ros::spinOnce();
  return 0;

}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章