我正在尝试使用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;
每一帧。
那么我怎么能只做一次然后将这些用于所有其他帧呢?
我是新手。 请帮忙。
抱歉我的英语不好。 :)