OpenCV Contrib Face module with Java wrapper - returning multiple predictions

asked 2016-05-30 06:43:44 -0500

patryk.beza gravatar image

updated 2016-06-26 09:36:47 -0500

I'm using OpenCV Contrib Face module in Java. Java wrapper is automatically generated from C++ source code based on CV_WRAP tag. So far so good, but unfortunately not all methods I need have wrappers. :-(

I'm using FaceRecognizer.predict method which returns label of face that is most similar (in terms of eigenfaces) to given face. What I desperately need is to get N>1 (for example N=5) best matches, ie. N images with minimal PredictResult.distance.

This is automatically generated Java's wrapper for predict method:

//
// C++:  void predict(Mat src, int& label, double& confidence)
//

//javadoc: FaceRecognizer::predict(src, label, confidence)
public  void predict(Mat src, int[] label, double[] confidence)
{
    double[] label_out = new double[1];
    double[] confidence_out = new double[1];
    predict_1(nativeObj, src.nativeObj, label_out, confidence_out);
    if(label!=null) label[0] = (int)label_out[0];
    if(confidence!=null) confidence[0] = (double)confidence_out[0];
    return;
}

As you can see, it uses two arrays (label_out and confidence_out) of length equal 1. I need more generalized version which is available in C++ source code as a StandardCollector::getResults method.

Is there an easy way to add a few CV_WRAP 'here and there' to get multiple predictions using Java wrapper for:

std::vector< std::pair<int, double> > StandardCollector::getResults(bool sorted) const {
    std::vector< std::pair<int, double> > res(data.size());
    std::transform(data.begin(), data.end(), res.begin(), &toPair);
    if (sorted)
    {
        std::sort(res.begin(), res.end(), &pairLess);
    }
    return res;
}

?

Thanks in advance!

edit retag flag offensive close merge delete

Comments

there were recent changes, imho, you should try to update, and then try the predict_collect method.

berak gravatar imageberak ( 2016-05-30 06:52:13 -0500 )edit

Yesterday I compiled OpenCV and OpenCV Contrib from newest available source code (commits d3930cdee1a0c7124045883b3062f25b3027fa97 and ba1d3ef99cf5e67241c5a31dbd9c344d12a2f7c5 respectively). Main results of the compilation is opencv-310.jar and libopencv_java310.so. I imported both of them to my project in Eclipse, clicked on Eclipse'sPackage Explorer and there is no predict(InputArray src, Ptr<PredictCollector> collector)Java's equivalent. See screenshot.

patryk.beza gravatar imagepatryk.beza ( 2016-05-31 20:47:28 -0500 )edit
1

As a workaround you can add one more predict method to FaceRecognizer:

CV_WRAP_AS(predict_dummy) vector<Point2f> predict(InputArray src) const {
    Ptr<StandardCollector> c = StandardCollector::create();
    predict(src, c);
    vector<pair<int, double> > res = c->getResults();
    vector<Point2f> ret;
    for (vector<pair<int, double> >::const_iterator i = res.begin(); i != res.end(); ++i)
        ret.push_back(Point2f(i->first, i->second));
    return ret;
}

Then, probably, it will be available in Java wrappers.

mshabunin gravatar imagemshabunin ( 2016-06-01 09:31:10 -0500 )edit

Thank you @mshabunin! It works! I just added getThreshold() as a StandardCollector::create parameter (optional modification) and std:: specifiers before vector and pair.

patryk.beza gravatar imagepatryk.beza ( 2016-06-03 18:31:53 -0500 )edit