Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

hi caaarlos,

unfortunately, the createFisherFaceRecognizer() method (as well as the other 2 createXXXFaceRecognizer()) were skipped during the java wrapper code generation, it's a known , yet unsolved problem. you will have to fill in the hole using jni/ndk, and write a replacement.

you will have to build:

  • an .so file with the native c++ code, let's call it facerec.so
  • an additional java wrapper class calling that, FisherFaceRecognizer.java

sadly, can't help much with ndk(no such thing here), but it worked nicely on desktop/eclipse (the dll/so would go right into your project folder), so here's the code (quite a wall of it).


// --- 8< --------- facerec.cpp -------------------------------

#include "jni.h"
#include "opencv2/contrib/contrib.hpp"



#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_10(JNIEnv* env, jclass);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_10(JNIEnv* env, jclass) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer();
        pfr.addref();
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_11(JNIEnv* env, jclass, jint num_components);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_11(JNIEnv* env, jclass, jint num_components) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer(num_components);
        pfr.addref();
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_12(JNIEnv* env, jclass, jint num_components, jdouble threshold);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_12(JNIEnv* env, jclass, jint num_components, jdouble threshold) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer(num_components,threshold);
        pfr.addref();
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

#ifdef __cplusplus
}
#endif

// --- 8< --------- FisherFaceRecognizer.java -----------------

import org.opencv.contrib.FaceRecognizer;
import org.opencv.core.Core;


public class FisherFaceRecognizer extends FaceRecognizer {

    static{ System.loadLibrary("facerec"); }

    private static native long createFisherFaceRecognizer_0();
    private static native long createFisherFaceRecognizer_1(int num_components);
    private static native long createFisherFaceRecognizer_2(int num_components, double threshold);

    public FisherFaceRecognizer () {
        super(createFisherFaceRecognizer_0());
    }
    public FisherFaceRecognizer (int num_components) {
        super(createFisherFaceRecognizer_1(num_components));
    }
    public FisherFaceRecognizer (int num_components, double threshold) {
        super(createFisherFaceRecognizer_2(num_components, threshold));
    }
}

once you got all this compiled (congrats!!), you would call it like this:

   FaceRecognizer  facerec = new FisherFaceRecognizer();
   facerec.load("/sdcard/smile.yml"); // note, that it can't read from apk or zip, so you need to copy it somewhere

   Mat img = ...//test face
   int [] label = new int[1];
   double [] conf = new double[1];
   facerec.predict(img, label, conf);

hi caaarlos,

unfortunately, the createFisherFaceRecognizer() method (as well as the other 2 createXXXFaceRecognizer()) were skipped during the java wrapper code generation, it's a known , yet unsolved problem. you will have to fill in the hole using jni/ndk, and write a replacement.

you will have to build:

  • an .so file with the native c++ code, let's call it facerec.so
  • an additional java wrapper class calling that, FisherFaceRecognizer.java

sadly, can't help much with ndk(no such thing here), but it worked nicely on desktop/eclipse (the dll/so would go right into your project folder), so here's the code (quite a wall of it).


// --- 8< --------- facerec.cpp -------------------------------

#include "jni.h"
#include "opencv2/contrib/contrib.hpp"



#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_10(JNIEnv* env, jclass);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_10(JNIEnv* env, jclass) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer();
        pfr.addref();
pfr.addref(); // this is for the 2.4 branch, 3.0 would need a different treatment here
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_11(JNIEnv* env, jclass, jint num_components);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_11(JNIEnv* env, jclass, jint num_components) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer(num_components);
        pfr.addref();
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_12(JNIEnv* env, jclass, jint num_components, jdouble threshold);
JNIEXPORT jlong JNICALL Java_FisherFaceRecognizer_createFisherFaceRecognizer_12(JNIEnv* env, jclass, jint num_components, jdouble threshold) {
    try {
        cv::Ptr<cv::FaceRecognizer> pfr = cv::createFisherFaceRecognizer(num_components,threshold);
        pfr.addref();
        return (jlong) pfr.obj;
    } catch (...) {
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "sorry, dave..");
    }
    return 0;
}

#ifdef __cplusplus
}
#endif

// --- 8< --------- FisherFaceRecognizer.java -----------------

import org.opencv.contrib.FaceRecognizer;
import org.opencv.core.Core;


public class FisherFaceRecognizer extends FaceRecognizer {

    static{ System.loadLibrary("facerec"); }

    private static native long createFisherFaceRecognizer_0();
    private static native long createFisherFaceRecognizer_1(int num_components);
    private static native long createFisherFaceRecognizer_2(int num_components, double threshold);

    public FisherFaceRecognizer () {
        super(createFisherFaceRecognizer_0());
    }
    public FisherFaceRecognizer (int num_components) {
        super(createFisherFaceRecognizer_1(num_components));
    }
    public FisherFaceRecognizer (int num_components, double threshold) {
        super(createFisherFaceRecognizer_2(num_components, threshold));
    }
}

once you got all this compiled (congrats!!), you would call it like this:

   FaceRecognizer  facerec = new FisherFaceRecognizer();
   facerec.load("/sdcard/smile.yml"); // note, that it can't read from apk or zip, so you need to copy it somewhere

   Mat img = ...//test face
   int [] label = new int[1];
   double [] conf = new double[1];
   facerec.predict(img, label, conf);