說明:
這個程序的作用是:
利用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;
}