Ask Your Question

FisherFace detect me even if my image is note in database

asked 2016-10-28 15:53:46 -0500

CLeBeR gravatar image

updated 2016-11-02 15:02:35 -0500

System information (version) - OpenCV => - Operating System / Platform => Linux Ubuntu 64 Bit - Compiler => CMake 3.5.1

Detailed description

I use imgshow to prompt the webcam capture and add a rectangle and the subject found with FisherFace algorithm AT&T orl_face photo base. The problem is FisherFace algorithm detect me even if I am not in the database, it confuses me with 2 subjects... I changed the minNeighbours parameter but it doesn't change anything.

Thanks to the FaceRecognizer() Thresholds documentation, I updated the code :

// Create a FaceRecognizer and train it on the given images:
Ptr<FaceRecognizer> model = createFisherFaceRecognizer(10,0.0);
model->train(images, labels);
// The following line reads the threshold from the Eigenfaces model:
double current_threshold = model->getDouble("threshold");
// And this line sets the threshold to 0.0:
model->set("threshold", 0.0);
haar_cascade.detectMultiScale(gray, faces, 1.1, 5,0, cvSize(30,30), cvSize(30,30));
Mat face_resized;
cv::resize(face, face_resized, Size(im_width, im_height), 1.0, 1.0, INTER_CUBIC);
// Now perform the prediction, see how easy that is:
int prediction = model->predict(face_resized);
// And finally write all we've found out to the original image!
// First of all draw a green rectangle around the detected face:
cout << prediction << endl;

(See full code just below)

Steps to reproduce

#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>

using namespace cv;
using namespace std;

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()) {
            Mat m = imread(path, 1);
            if (m.empty())
                cerr << path << " could not be read." << endl;
            Mat m2;
    cout << endl << "Read finish";

int main(int argc, const char *argv[]) {
    if (argc != 4) {
        cout << "usage: " << argv[0] << " </path/to/haar_cascade> </path/to/csv.ext> </path/to/device id>" << endl;
        cout << "\t </path/to/haar_cascade> -- Path to the Haar Cascade for face detection." << endl;
        cout << "\t </path/to/csv.ext> -- Path to the CSV file with the face database." << endl;
        cout << "\t <device id> -- The webcam device id to grab frames from." << endl;
    string fn_haar = string(argv[1]);
    string fn_csv = string(argv[2]);
    int deviceId = atoi(argv[3]);
    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;
        // nothing more we can do
    int im_width = images[0].cols;
    int im_height = images[0].rows;
    Ptr<FaceRecognizer> model = createFisherFaceRecognizer(10,0.0);
    model->train(images, labels);
    double current_threshold = model->getDouble("threshold");
    model->set("threshold", 0.0);
    CascadeClassifier haar_cascade;
    haar_cascade.load(fn_haar ...
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted

answered 2016-10-28 20:48:56 -0500

berak gravatar image

updated 2016-10-28 20:50:03 -0500

it seems, you simply misunderstood, how the prediction works (all it can do is returrn the closest item from the db)

your current setup does not allow to handle this, you might want a few additional steps:

  • look up the createFisherFaceRecognizer() signature, you can give it a threshold value for the prediction distance , so any distance value larger than X will result in returning a -1 value, start with something like 500, and improve, doing a lot of tests

  • make printing out the prediction value (and maybe even drawing the rectangle) depend on this.

edit flag offensive delete link more

Question Tools

1 follower


Asked: 2016-10-28 15:53:46 -0500

Seen: 122 times

Last updated: Nov 02 '16