Использование Facemark OpenCV Contribute в Android C ++ - PullRequest
0 голосов
/ 18 октября 2018

Я новичок в opencv, я пытаюсь использовать Facemark в модулях opencv contrib в моем родном приложении C ++ для Android.Тем не менее, я получаю ошибку

A / libc: фатальный сигнал 11 (SIGSEGV), код 1, адрес ошибки 0x1788 в тид 21567 (my_app)

при созданииэкземпляр Facemark, использующий

 Ptr<Facemark> facemark = FacemarkLBF::create();

Я использую https://github.com/chaoyangnz/opencv3-android-sdk-with-contrib opencv library
вот моя реализация c ++

    void
    Java_com_makeover_makeover_1opencv_MainActivity_nativeDetectFaceLandmarks(
            JNIEnv *env,
            jobject , jlong srcAddr, jlong retAddr,
            jstring faceCascadePath, jstring faceYamlPath)
    {
        const char *faceCascadeFile = env->GetStringUTFChars(faceCascadePath,NULL);
        const char *yamlFile = env->GetStringUTFChars(faceYamlPath,NULL);

        LOGI("nativeDetectFace called");
        string cascadePath(faceCascadeFile);

        LOGI("nativeDetectFace called");

        string yamlPath(yamlFile);

        Mat& colorMat = *(Mat*)srcAddr;
        Mat& retValMat = *(Mat*)retAddr;
        Mat gray;

        // Load Face Detector
        CascadeClassifier faceDetector(cascadePath);
        LOGI("cascade file loaded");

        // Create an instance of Facemark
        Ptr<Facemark> facemark = FacemarkLBF::create();

        LOGI("face instance created");


        // Load landmark detector
        facemark->loadModel(yamlPath);

        LOGI("yalm model loaded");

        // Find face
        vector<Rect> faces;
        // Convert frame to grayscale because
        // faceDetector requires grayscale image.
        cvtColor(colorMat, gray, COLOR_BGR2GRAY);

        // Detect faces
        faceDetector.detectMultiScale(gray, faces);

        // Variable for landmarks.
        // Landmarks for one face is a vector of points
        // There can be more than one face in the image. Hence, we
        // use a vector of vector of points.
        vector< vector<Point2f> > landmarks;

        // Run landmark detector
        bool success = facemark->fit(colorMat,faces,landmarks);

        if(success)
        {
            // If successful, render the landmarks on the face
            for(int i = 0; i < landmarks.size(); i++)
            {
                drawLandmarks(colorMat, landmarks[i]);
            }
        }

    }

Java-реализация

    drawFaces.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Mat colorMat,grayMat;
            colorMat = new Mat();
            grayMat = new Mat();

            Utils.bitmapToMat(bmp,colorMat);

            nativeDetectFaceLandmarks(colorMat.getNativeObjAddr(), grayMat.getNativeObjAddr(),
                    getCascade("face"),getCascade("yaml"));

            Bitmap new_bmp2 = Bitmap.createBitmap(bmp);
            Utils.matToBitmap(colorMat,new_bmp2);

            img_face.setImageBitmap(new_bmp2);

        }
    });

метод getCascade

    public String getCascade(String cascadeType){
    String fileName;
    File mCascadeFile;
    final InputStream is;
    FileOutputStream os;
    switch (cascadeType){
        case "mouth":
            fileName="haarcascade_mcs_mouth.xml";
            break;
        case "face":
            fileName = "haarcascade_frontalface_alt2.xml";
            break;
        case "right_eye":
            fileName = "haarcascade_mcs_righteye.xml";
            break;

        case "yaml":
            fileName = "lbfmodel.yaml";
            break;


        case "left_eye":
            fileName = "haarcascade_mcs_lefteye.xml";
            break;
        default:
            fileName = null;
    }
    if(fileName==null) {
        return null;
    }
    try {
        is = getResources().getAssets().open(fileName);
        File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);

        mCascadeFile = new File(cascadeDir,fileName);


        os = new FileOutputStream(mCascadeFile);

        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            os.write(buffer, 0, bytesRead);
        }
        is.close();
        os.close();
        Log.i("TAG", "getCascade: face cascade found");
        return mCascadeFile.getAbsolutePath();
    } catch (IOException e) {
        Log.e("TAG", "face cascade not found", e);
        return null;
    }

}

Любой, кто знает, что я делаю неправильно, или лучший способ использовать Facemark в модулях contrib openvv в android native

1 Ответ

0 голосов
/ 07 декабря 2018

В каждом уроке, который я видел до сих пор, этот метод реализован по-своему, чтобы прояснить это, я расскажу о методах, которые у меня работают.

Во-первых, объявление метки лица в приведенном ниже методе возвращает ошибку SIGSEGV:

Ptr<Facemark> facemark = FacemarkLBF::create();

Вместо этого используйте:

Ptr<Facemark> facemark = createFacemarkLBF();

Во-вторых, я видел много учебных пособий:

facemark->load(filename);

Но правильный синтаксис будет:

facemark->loadModel(filename);

Если проблема не исчезла, перейдите по этой ссылке, загрузите ссылку и получите последний SDK с вкладом:

https://pullrequest.opencv.org/buildbot/export/opencv_releases/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...