OpenCv实践-FaceRecognizer使用

来源:互联网 发布:网络超好听伤感歌曲 编辑:程序博客网 时间:2024/06/05 12:43


//#include "stdafx.h"
#include <opencv2\opencv.hpp>
#include <iostream>
#include <fstream>
#include <sstream>
#include <math.h>

using namespace cv;
using namespace std;

//读取image存入Mat中

static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ',') {
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file) {
        string error_message = "No valid input file was given, please check the given filename.";
        CV_Error(CV_StsBadArg, error_message);
    }
    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()));
        }
    }
}


void main()
{
 CascadeClassifier cas("haarcascade_frontalface_default.xml");    //加载人脸分类器

 char str[20];

//at.txt存放在项目目录下
 string fn_csv = "at.txt";
    vector<Mat> images;
vector<int> labels;
try
    {
        read_csv(fn_csv, images, labels);
    }
    catch (cv::Exception& e)
    {
        cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
        // 文件有问题,我们啥也做不了了,退出了
        exit(1);
    }
    // 如果没有读取到足够图片,也退出.
    if (images.size() <= 1) {
        string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
        CV_Error(CV_StsError, error_message);
    }

 // 下面的几行代码仅仅是从你的数据集中移除最后一张图片
    //[gm:自然这里需要根据自己的需要修改,他这里简化了很多问题]
    //Mat testSample = images[images.size() - 1];
    //int testLabel = labels[labels.size() - 1];
    //images.pop_back();
    //labels.pop_back();
 vector<Mat> newImages;
 vector<int> newLabel;
 try
    {
        read_csv("new.txt", newImages, newLabel);
    }
    catch (cv::Exception& e)
    {
        cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;
        // 文件有问题,我们啥也做不了了,退出了
        exit(1);
    }
    // 如果没有读取到足够图片,也退出.
    if (newImages.size() <= 1) {
        string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";
        CV_Error(CV_StsError, error_message);
    }

//测试用图片,同样在项目目录下,大小必须与训练图片一致

 Mat testSample = imread("14/s5.bmp", CV_LOAD_IMAGE_GRAYSCALE);
//读入人脸图片
  //img = cvLoadImage("C:\\Users\\hhh\\Desktop\\face_DB\\yalefaces\\03\\s5.bmp", 1);
 //Mat testSample(img);

//第一个参数:保留多少主要成分,第二个,设置可信度阈值,越小,表明要求越高,两张图片差距越小
 Ptr<FaceRecognizer> fc = createFisherFaceRecognizer(10,500.0);
    fc->train(images, labels);    //训练
 Ptr<FaceRecognizer> model1 = createFisherFaceRecognizer();
    model1->train(images, labels);
    model1->save("MyFaceFisherModel.xml");
 
    Ptr<FaceRecognizer> model2 = createLBPHFaceRecognizer();
    model2->train(images, labels);
    model2->save("MyFaceLBPHModel.xml");

 model2->update(newImages,newLabel);
 int predicted_label = -1;
double predicted_confidence = 0;
int predicted_label1 = -1;
double predicted_confidence1 = 0;
int predicted_label2 = -1;
double predicted_confidence2 = 0;
// Get the prediction and associated confidence from the model
fc->predict(testSample, predicted_label, predicted_confidence);
model1->predict(testSample, predicted_label1, predicted_confidence1);
model2->predict(testSample, predicted_label2, predicted_confidence2);
string result_message = format("Predicted class = %d / Actual class = %d.", predicted_label, predicted_confidence);
string result_message1 = format("Predicted class = %d / Actual class = %d.", predicted_label1, predicted_confidence1);
 cout << result_message<< endl;
 string result_message2 = format("Predicted class = %d / Actual class = %d.", predicted_label2, predicted_confidence2);
 cout << result_message1<< endl;
 cout << result_message2<< endl;


    cout<<"please input a string:";

//这里不设置程序就直接结束了。。


cin>>str; /*你试着输入"hello word"*/
 

//以下暂未验证
VideoCapture cap;
    cap.open(1);
    Mat image;
    vector<Rect> recs;
    Mat test(100, 100, CV_8UC1);
    Mat gray;
    int x = 0, y = 0;

    for (;;)
    {
        cap >> image;
        if (image.empty())
            break;
        cas.detectMultiScale(image, recs,1.2,6,0,Size(50,50));    //先检测人脸
        for (int i = 0; i < recs.size();i++)
        {
            rectangle(image, recs[i], Scalar(0, 0, 255));
            x = recs[i].x + recs[i].width / 2;
            y = recs[i].y + recs[i].height / 2;

            Mat roi = image(recs[i]);       //因为我训练的样本是400*500大小,所以需要把摄像头中的人脸区域改为400*500大小
            cvtColor(roi, gray, CV_BGR2GRAY);
            resize(gray, test, Size(100, 100));
            int result = fc->predict(test);
            switch (result)
            {
            case 0:
                putText(image, "a", Point(recs[i].x, recs[i].y), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2); break;
            case 1:
                putText(image, "b", Point(recs[i].x, recs[i].y), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2); break;
            case 2:
                putText(image, "c", Point(recs[i].x, recs[i].y), FONT_HERSHEY_SIMPLEX, 1.5, Scalar(0, 0, 255), 2); break;
            }
        }
        imshow("Sample", image);
        if (waitKey(30) >= 0)
            break;
    }

}


0 0
原创粉丝点击