在android工作室实时进行面部地标检测,仅对shape_predictor_68_face_landmarks.dat反序列化一次

时间:2017-10-21 18:29:19

标签: android c++ android-studio opencv dlib

我正在尝试使用android studio中的opencv,dlib库检测面部地标。 我可以捕捉图像并从图像中检测地标。 但是当我试图实时检测面部地标时,我遇到了问题。

因为我正在为每个帧反序列化shape_predictor_68_face_landmarks.dat文件。

onCameraFrame method of MainActivity.Java

@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame)
{
    matInput =inputFrame.rgba();

        NativeClass.LandmarkDetection(matInput.getNativeObjAddr(), matOutput.getNativeObjAddr());

    return matOutput;
}

NativeClass.Java

package com.example.user.drowsinessdetection;


public class NativeClass {
    public native static String getMessage();
    public native static void LandmarkDetection(long addrInput,long addrOutput);
}

Landmark检测的cpp文件:

com_example_user_drowsinessdetection_NativeClass.cpp

#include <com_example_user_drowsinessdetection_NativeClass.h>
#include <dlib/geometry/rectangle.h>


JNIEXPORT jstring JNICALL 
Java_com_example_user_drowsinessdetection_NativeClass_getMessage
    (JNIEnv *env, jclass){
env->NewStringUTF("JNI message");
}

JNIEXPORT void JNICALL
Java_com_example_user_drowsinessdetection_NativeClass_LandmarkDetection
    (JNIEnv *env, jclass thiz, jlong addrInput, jlong addrOutput){
    Mat& image = *(Mat*)addrInput;
    Mat& dst = *(Mat*)addrOutput;

    faceDetectionDlib(image, dst);
}



void faceDetectionDlib(Mat& img, Mat& dst){

    try {
        frontal_face_detector detector = get_frontal_face_detector();
        shape_predictor pose_model;
       deserialize("storage/emulated/0/shape_predictor_68_face_landmarks.dat")>>pose_model;
        cv_image<bgr_pixel>cimg(img);

        std::vector<dlib::rectangle> faces = detector(cimg);
        std::vector<full_object_detection> shapes;
        int k=faces.size();

        for(unsigned long i = 0;i < k; ++i)
            shapes.push_back(pose_model(cimg,faces[i]));

        dst = img.clone();
        renderToMat(shapes, dst);
       }
    catch (serialization_error& e)
    {
        cout<<endl<<e.what()<<endl;
    }

}

void renderToMat(std::vector<full_object_detection>& dets, Mat& dst){
Scalar color;
int sz = 3,l;
color = Scalar(0,255,0);
//chin line
l=dets.size();
for(unsigned long idx = 0; idx < l; idx++) {

    //left eye
    for (unsigned long i = 37; i <= 41; ++i)
        cv::line(dst, Point(dets[idx].part(i).x(), dets[idx].part(i).y()),
                 Point(dets[idx].part(i - 1).x(), dets[idx].part(i - 1).y()), color, sz);
    cv::line(dst, Point(dets[idx].part(36).x(), dets[idx].part(36).y()),
             Point(dets[idx].part(41).x(), dets[idx].part(41).y()), color, sz);
    //right eye
    for (unsigned long i = 43; i <= 47; ++i)
        cv::line(dst, Point(dets[idx].part(i).x(), dets[idx].part(i).y()),
                 Point(dets[idx].part(i - 1).x(), dets[idx].part(i - 1).y()), color, sz);
    cv::line(dst, Point(dets[idx].part(42).x(), dets[idx].part(42).y()),
             Point(dets[idx].part(47).x(), dets[idx].part(47).y()), color, sz);
    //lips out part

}
}

我不想执行此行

frontal_face_detector detector = get_frontal_face_detector();

deserialize("storage/emulated/0/shape_predictor_68_face_landmarks.dat")>>pose_model;

每一帧。

那么我怎么能只做一次然后将这些用于所有其他帧呢?

我是新手。 请帮忙。

抱歉我的英语不好。 :)

0 个答案:

没有答案