如何从OpenCV for Android中的指针创建FaceRecognizer

时间:2015-02-03 02:16:06

标签: android opencv java-native-interface

我正在使用OpenCV 2.4.10。

JNI - 训练面部识别

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转换存储的指针,并实时使用它来检测和识别一个函数中的面部。如何将该指针转换回nativeDetect中可用的FaceRecognizer?

1 个答案:

答案 0 :(得分:2)

编辑:与berak的评论一样,最好使用原始指针版本,否则您需要使用addref保存对象。

如果仍然偏好cv::Ptr版本,而不是Ptr < FaceRecognizer > model = recog;,我们应该给予

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

C ++中的智能指针实现(std::shared_ptrstd::unique_ptr或已弃用std::auto_ptr)将不支持从原始指针到智能指针的赋值。在此处查看旧的cv::Ptr实施(1)。他们还添加了explicit关键字(2),以防止从原始指针到智能指针的意外转换。

注意:在OpenCV 3.0中,Ptr类,obj成员是私有的(3),addref方法已被删除。所以这不会与3.0一起工作。还有好奇心为什么所有这些都是通过JNI调用的。没有Java包装器?