2015-02-03 2 views
0

Я использую OpenCV 2.4.10.Как создать FaceRecognizer из указателя в OpenCV для Android

JNI - Обучать facialRecognition

JNIEXPORT jlong JNICALL Java_com_sample_facialRecognition_DetectionBasedRecognition_nativeTrain 
(JNIEnv * jenv, jstring pathIn) 
{ 
    vector<Mat> images; 
    vector<int> labels; 
    try { 

     std::string path; 
     std::string classlabel = "A"; 
     GetJStringContent(jenv,pathIn,path); 

     if(!path.empty() && !classlabel.empty()) { 
      images.push_back(imread(path, 0)); 
      labels.push_back(atoi(classlabel.c_str())); 
     } 
     Ptr<FaceRecognizer> model = createEigenFaceRecognizer(); 
     model->train(images, labels); 

     model.addref(); //don't let it self-destroy here.. 
     FaceRecognizer * pf = model.obj; 
     return (jlong) pf; 

    } 
    catch (...) 
    { 
     return 0; 
    } 

} 

Java - обучить распознаватель

mNativeRecognition = nativeTrain(getFilesDir().toString()); 

Java - сделать обнаружение и распознавание

nativeDetect(mGray, faces, mNativeRecognition); 

JNI - признать

JNIEXPORT jint JNICALL Java_com_sample_facialRecognition_DetectionBasedTracker_nativeDetect 
(JNIEnv * jenv, jclass, jlong thiz, jlong imageGray, jlong faces, jlong recog) 
{ 
    jint whoAreYou= 0; 

    try 
    { 
     vector<Rect> RectFaces; 
     ((DetectionBasedTracker*)thiz)->process(*((Mat*)imageGray)); 
     ((DetectionBasedTracker*)thiz)->getObjects(RectFaces); 

     Ptr <FaceRecognizer> model = recog; //here is the problem 

     vector_Rect_to_Mat(RectFaces, *((Mat*)faces)); 

     for (int i = 0; i < faces.size(); i++) 
     { 
      cv::Point pt1(faces[i].x + faces[i].width, faces[i].y + faces[i].height); 
      cv::Point pt2(faces[i].x, faces[i].y); 

      cv::Rect face_i = faces[i]; 

      cv::Mat face = grayscaleFrame(face_i); 
      cv::Mat face_resized; 

      cv::resize(face, face_resized, cv::Size(100, 120), 1.0, 1.0, INTER_CUBIC); 
      whoAreYou = model->predict(face_resized); 
     } 
    } 
    catch (...) 
    { 

     //catch... 
    } 

    return whoAreYou; 
} 

Итак, я пытаюсь преобразовать сохраненный указатель из nativeTrain и использовать его в реальном времени для обнаружения и распознавания лица в одной функции. Как преобразовать этот указатель обратно в полезный FaceRecognizer в nativeDetect?

+1

try: 'FaceRecognizer * model = (FaceRecognizer *) recog; // здесь проблема'. если вы используете версию cv :: Ptr, должна быть: 'Ptr model ((FaceRecognizer *) recog);' и 'model.addref();' в конце func. – berak

ответ

2

EDIT: Как и в комментарии berak, лучше пойти с исходной версией указателя, иначе вам нужно будет сохранить объект с помощью addref.

Если по-прежнему предпочитает версию cv::Ptr, вместо Ptr <FaceRecognizer> model = recog;, мы должны дать

Ptr <FaceRecognizer> model((FaceRecognizer *)recog); 
model->addref(); 

смарт реализации указателей в C++ (std::shared_ptr, std::unique_ptr или осуждаются std::auto_ptr), не будет поддерживать назначения из сырого указателя умный указатель. См. Старую версию cv::Ptr здесь (1). Они также добавляют ключевое слово explicit (2), чтобы предотвратить случайные преобразования из необработанных указателей в интеллектуальные указатели.

Примечание: В OpenCV 3.0, Ptr класс, obj членом является частным (3) и addref метод удаляется. Таким образом, это не будет работать с 3.0. Также любопытно, почему все эти призывы над JNI. Нет Java-обертки?

+1

«Нет оболочек Java?», К сожалению, не в этом случае. java api генерируется сценарием, и этот скрипт не знает, как правильно обрабатывать cv :: Ptr. – berak

+0

@berak [JavaCPP] (https://github.com/bytedeco/javacpp) создает для этого оболочки: [public static FaceRecognizer createEigenFaceRecognizer()] (http://bytedeco.org/javacpp-presets/opencv/apidocs/org /bytedeco/javacpp/opencv_contrib.html#createEigenFaceRecognizer--) –

Смежные вопросы