在android 平台编译并使用dlib进行人脸68个特征检测

上一篇文章描述了在ndk环境下编译opencv JNI用于简单的图像处理的流程。本篇文章主要讲述在Android环境下基于opencv + dlib 进行人脸68个特征点提取。

  1. 分别下载dlib库和opencv库,网站如下:
    http://dlib.net/files/ 在android 平台编译并使用dlib进行人脸68个特征检测_第1张图片
    opencv的下载请参照上篇文章。

    1. 新建Android Project ,新建时要选中include c++ support。
    2. 工程新建好后,按照如下操作:在android 平台编译并使用dlib进行人脸68个特征检测_第2张图片
      在这里插入图片描述
      4 .修改CMakeLists.txt 文件内容,如下:
      在android 平台编译并使用dlib进行人脸68个特征检测_第3张图片
      在android 平台编译并使用dlib进行人脸68个特征检测_第4张图片
  2. 修改build.gradle 文件内容:
    在android 平台编译并使用dlib进行人脸68个特征检测_第5张图片
    6 .在代码中加载静态库,加载时要注意顺序:
    在android 平台编译并使用dlib进行人脸68个特征检测_第6张图片

  3. java层代码如下:
    public class FaceActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
    private JavaCameraView cameraView;
    private Mat rgba;

    static {
    System.loadLibrary(“opencv_java3”);
    System.loadLibrary(“native-lib”);

    }
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

     requestWindowFeature(Window.FEATURE_NO_TITLE); //设置无标题
    // getWindow().setFlags(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.FILL_PARENT);  //设置全屏
     setContentView(R.layout.activity_face);
     cameraView = findViewById(R.id.javaCameraView);
     cameraView.setCvCameraViewListener(this);
     faceinit();
    
     }
    

public void onCameraViewStarted(int width, int height) {
//定义Mat对象
rgba = new Mat(width, height, CvType.CV_8UC3);
}

public void onCameraViewStopped() {
rgba.release();
}

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
rgba = inputFrame.rgba();
//得到当前一帧图像的内存地址
long addr = rgba.getNativeObjAddr();
//对一帧图像进行处理
nativeRgba(addr);
//得到一帧灰度图
// rgba = inputFrame.gray();
return rgba;
}

@Override
protected void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
} else {
cameraView.enableView();
}
}

@Override
protected void onPause() {
super.onPause();
if (cameraView != null) {
cameraView.disableView();
}
}

@Override
protected void onDestroy() {
super.onDestroy();
if (cameraView != null) {
cameraView.disableView();
}
}

public static native void nativeRgba(long jrgba);
public static  native void faceinit();

}
8. jni层代码如下:
9.
extern “C” float getDistance(CvPoint pointO, CvPoint pointA)
{
float distance;
distance = powf((pointO.x - pointA.x), 2) + powf((pointO.y - pointA.y), 2);
distance = sqrtf(distance);
return distance;
}
extern “C” JNIEXPORT void JNICALL Java_com_facetest_FaceActivity_faceinit(
JNIEnv *env, jclass obj){

        LOGD("------------JNI to nativeRgba 1 ");
        deserialize("/sdcard/shape_predictor_68_face_landmarks.dat") >> pose_model;
        detector = get_frontal_face_detector();

      }

extern “C” JNIEXPORT void JNICALL Java_com_facetest_FaceActivity_nativeRgba(
JNIEnv *env, jclass obj, jlong jrgba)
{

             Mat &img = *(Mat*)jrgba;
               Mat out;
            int A = 0,B = 0,C = 0;
           // cvtColor(img,out,COLOR_RGBA2GRAY);
            clock_t t1 = 0,t2 = 0;
            dlib::array2d arrimg(img.rows, img.cols);
            for(int i=0; i < img.rows; i++)
            {
                  for(int j=0; j < img.cols; j++)
                   {
                       arrimg[i][j].blue = img.at< cv::Vec3b>(i,j)[0];
                       arrimg[i][j].green=img.at< cv::Vec3b>(i,j)[1];
                       arrimg[i][j].red = img.at< cv::Vec3b>(i,j)[2];
                    }
            }

            t1 = clock();
            std::vector faces= detector(arrimg);
            t2 = clock();

           std::vector shapes;

            for (unsigned long i = 0; i < faces.size(); ++i)
                 shapes.push_back(pose_model(arrimg, faces[i]));
             if (!shapes.empty()) {
              for (int i = 0; i < 68; i++) {
                          circle(img, cvPoint(shapes[0].part(i).x(), shapes[0].part(i).y()), 3, cv::Scalar(0, 0,255), -1);
                   }
                   //用于计算眼宽比
                    A = getDistance(Point(shapes[0].part(37).x(),shapes[0].part(37).y()),Point(shapes[0].part(41).x(),shapes[0].part(41).y()));
                    B = getDistance(Point(shapes[0].part(38).x(),shapes[0].part(38).y()),Point(shapes[0].part(40).x(),shapes[0].part(40).y()));
                    C = getDistance(Point(shapes[0].part(36).x(),shapes[0].part(36).y()),Point(shapes[0].part(39).x(),shapes[0].part(39).y()));
                    char temp[32] = {0 };
                    sprintf(temp,"rightEye:%f  time: %lu",((A+B)/(C*2.0)),(t2-t1));
                    putText(img, temp, Point(10,30), FONT_HERSHEY_SIMPLEX, 0.5, Scalar(0, 0, 0, 255));


               }

你可能感兴趣的:(在android 平台编译并使用dlib进行人脸68个特征检测)