使用FisherFace进行人脸识别总能预测一个人。如果没有受过训练的人面对镜头,如何返回-1(未知的人)?

时间:2016-12-06 18:20:28

标签: c++ opencv image-processing face-recognition

我有一个由2个人组成的数据集(PERSON APERSON B)。

PERSON APERSON B转到相机(实时)时,我的代码可以正常工作。但是当PERSON C进入相机时,我再次使用PERSON C(.csv文件中没有PERSON C的训练图像)进行测试;程序再次预测AB

我想要返回-1(未知的人)。这该怎么做?我使用这段代码;

#include <opencv2/core/core.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>

using namespace cv;
using namespace std;

string person_name_1, person_name_2;
string haar_cascade_file = "C:\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_default.xml";
CascadeClassifier detectFace;
string filename;
int filenumber;
VideoCapture video;

static void csvFile_read(const string& filename, vector<Mat>& images, vector<int>& labels, char seperator = ';'){
    std::ifstream file(filename.c_str(), ifstream::in);
    if (!file){
        string error_message = "File not found";
        CV_Error(CV_StsBadArg, error_message);
    }
    string line, file_path, file_label;
    while (getline(file, line)){
        stringstream lines(line);
        getline(lines, file_path, seperator);
        getline(lines, file_label);
        if (!file_path.empty() && !file_label.empty()){
            images.push_back(imread(file_path, 0));
            labels.push_back(atoi(file_label.c_str()));
        }

    }


}
int main(int argc, const char *argv[]){

    double const threshold = DBL_MAX;
    string csv_file = "C:\\Users\\user\\Desktop\\Tutorialss\\important books\\final year\\DetectsAndRecognizeFaces\\DetectsAndRecognizeFaces\\DetectsAndRecognizeFaces\\csv.ext";
    int cameraNo = 0;

    vector<Mat> images; 
    vector<int> labels; 

    try{
        csvFile_read(csv_file, images, labels);
    }
    catch (cv::Exception& e){
        cerr << "Error " << csv_file << "\..." << " Reason: " << e.msg << endl;
        exit(1);
    }


    int image_width = images[0].cols;
    int image_height = images[0].rows;



    Ptr<FaceRecognizer> face_recog_model = createFisherFaceRecognizer(0,DBL_MAX);
    face_recog_model->train(images, labels);




    detectFace.load(haar_cascade_file);

    VideoCapture video(cameraNo); 


    if (!video.isOpened()){
        cerr << cameraNo << " camera error" << endl;
        return -1;
    }

    string person_list[] =
    {
        "PERSON A",
        "PERSON B"
    };


    Mat live_video;
    while (1){
        video >> live_video;
        Mat original = live_video.clone();
        Mat grey;
        cvtColor(original,grey, CV_BGR2GRAY); 

        vector< Rect_<int> > faces;
        detectFace.detectMultiScale(grey, faces);



        for (int i = 0; i < faces.size(); i++){

            Rect face_i = faces[i];
            Mat face = grey(face_i);

            Mat face_resize;
            resize(face, face_resize, Size(image_width, image_height), 1.0, 1.0, INTER_CUBIC);

            int predict = face_recog_model->predict(face_resize);
            rectangle(original, face_i, CV_RGB(0, 255, 0), 1);
            string text_box;
            text_box = format("Predict= ");
            if ( predict >= 0 && predict <= 1){

                text_box.append(person_list[predict]);
            }
            else{
                text_box.append("Unknown...");
            }


            int horizontal = std::max(face_i.tl().x - 10, 0);
            int vertical = std::max(face_i.tl().y - 10, 0);
            putText(original, text_box, Point(horizontal, vertical), FONT_HERSHEY_PLAIN, 1.0, CV_RGB(0, 255, 0), 2.0);


        }
        imshow("Face Detector", original);
        char key = (char)waitKey(20);
        if (key == 27)
            break;
    }
    return 0;

}

和我的csv文件:

path\personA_01.jpg;0
path\personA_02.jpg;0
path\personA_03.jpg;0
path\personA_04.jpg;0
path\personA_05.jpg;0
path\personA_06.jpg;0
path\personA_07.jpg;0
path\personA_08.jpg;0
path\personA_09.jpg;0
path\personA_10.jpg;0
path\personB_01.jpg;1
path\personB_02.jpg;1
path\personB_03.jpg;1
path\personB_04.jpg;1
path\personB_05.jpg;1
path\personB_06.jpg;1
path\personB_07.jpg;1
path\personB_08.jpg;1
path\personB_09.jpg;1
path\personB_10.jpg;1

如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您正在进行二进制分类。您正在寻找的是多类别分类,分类为人员A,人员B和未知人员。您需要一个多类分类器或多个二元分类器和类别为Unknown Person的训练数据。

答案 1 :(得分:0)

您需要设置您正在执行的阈值,但是我没有在任何地方看到您的定义:

double const threshold = DBL_MAX;

如果超过置信度阈值,则返回-1。