Ask Your Question
3

Adding New Method in FaceRecognizer

asked 2012-10-26 04:28:17 -0600

joswaa gravatar image

I would like to list out the all the confidence values in facerecognizer algorithm, So i have tried to create the another predict method with new parameter. Source complied successfully, but I could not access those newly created method from programs. I have modified in contib.hpp and facerec.cpp. Have to do in any other Changes?

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
6

answered 2012-10-27 13:32:17 -0600

updated 2012-10-27 13:36:24 -0600

That's actually a function a lot of people have asked me for and if you think this would be a useful feature, please open up a feature request on code.opencv.org for discussion. It's just, that I don't think every possible FaceRecognizer has something like a distance as classifier output. So I don't think stuff like this belongs to a Generic FaceRecognizer API. The assumption of a distance array may hold for the available models, but not for all models I can think of; I'll come up with another solution as soon as I have some time.

All that said, implementing such a feature is very easy, I'll show you how to do it.

First of all you would need to extend cv::FaceRecognizer::predict (in contrib.hpp) like this:

// Gets a prediction from a FaceRecognizer.
virtual void predict(InputArray src, int &label, double &confidence, OutputArray distances = noArray()) const = 0;

The idea is that distances, if given, holds all the distances for predicting the query in src. Then you need to write the implementation (in facerec.cpp), here is how to do it for the Eigenfaces model (exception handling stripped off for making the snippet easier to read):

void Eigenfaces::predict(InputArray _src, int &minClass, double &minDist, OutputArray distances) const {
    // Get the data:
    Mat src = _src.getMat();
    // Project into PCA subspace:
    Mat q = subspaceProject(_eigenvectors, _mean, src.reshape(1,1));
    // Create the return Matrix:
    if(distances.needed()) {
        distances.create(_projections.size(), 1, CV_64FC1);
    }
    minDist = DBL_MAX;
    minClass = -1;
    for(size_t sampleIdx = 0; sampleIdx < _projections.size(); sampleIdx++) {
        double dist = norm(_projections[sampleIdx], q, NORM_L2);
        // Add to the resulting distance array:
        if(distances.needed()) {
            distances.getMat().at<double>(sampleIdx) = dist;
        }
        if((dist < minDist) && (dist < _threshold)) {
            minDist = dist;
            minClass = _labels.at<int>((int)sampleIdx);
        }
    }
}

So I simply create the matrix for the cv::OutputArray if needed and fill it with the distance between the query and projected training samples.

Calling the function is then as easy as doing:

// Hold the return values of the predict call:
int label;
Mat distances;
// Predict the testSample. Put the threshold to DBL_MAX:
model->predict(testSample, label, DBL_MAX, distances);
// Output the distances:
cout << distances << endl;

And it will yield all the distances for the given sample:

[5319.568259578258; 5146.403381012799; 5162.0278252895; 4997.433648278493; ... ]

Please don't make a Pull Request of this to the OpenCV repository, as I have explained the reasons above.

edit flag offensive delete link more

Comments

I tried out this process using the sample code itself but I keep getting this error saying

"F:\opencv\modules\contrib\src\facerec.cpp:903:65: error: cannot allocate an object of abstract type 'cv::LBPH'F:\opencv\modules\contrib\src\facerec.cpp:219:7: note: because the following virtual functions are pure within 'cv::LBPH':"

and quite a few of these when trying to compile opencv. Could you please help me with this ? Thank you

bestkaranthe gravatar imagebestkaranthe ( 2013-06-04 00:48:13 -0600 )edit

I like the idea of a standard interface to confidence values, even if some recognizers don't have great methods for computing confidence. A recognizer with no idea of confidence can just fill in 1/n as confidence when it has n hits to report.

xaffeine gravatar imagexaffeine ( 2013-09-05 13:18:37 -0600 )edit

i am having the same problem as bestkaranthe....please help me out with this. I need to fetch multiple confidence levels from the model.

Ishmeet gravatar imageIshmeet ( 2014-06-17 08:48:24 -0600 )edit
0

answered 2015-09-03 05:46:21 -0600

lm35 gravatar image

"F:\opencv\modules\contrib\src\facerec.cpp:903:65: error: cannot allocate an object of abstract type 'cv::LBPH'F:\opencv\modules\contrib\src\facerec.cpp:219:7: note: because the following virtual functions are pure within 'cv::LBPH':" This error may be due to using pure virtual function ie. equating to zero which will make the virtual function pure. just keep "const" alone and try.

edit flag offensive delete link more

Comments

since there are 3 implementations of the interface, rather try without the pure virtual call:

First of all you would need to extend cv::FaceRecognizer::predict (in contrib.hpp) like this:

// empty method, preimplemented for all interfaces
// Gets a prediction from a FaceRecognizer.
virtual void predict(InputArray src, int &label, double &confidence, OutputArray distances = noArray()) const {}

hopefully, like this, it won't complain anymore for lbph and eigenfaces.

berak gravatar imageberak ( 2015-09-03 07:09:47 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2012-10-26 04:28:17 -0600

Seen: 2,135 times

Last updated: Sep 03 '15