算法移植优化(三)android dlib 人脸检测使用

android dlib 人脸检测使用

一、编译阶段

1、在cmakelist.txt中加入:

include(src/main/cpp/dlib/cmake)
然后再链接dlib库就可以了:

target_link_libraries( # Specifies the target library.
                       native-lib

                       dlib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

2、可能出现的错误

Android NDK 编译器默认不支持 C++ 异常控制导致。

Error:(124, 17) error: cannot use 'throw' with exceptions disabled
Error:(119, 21) error: cannot use typeid with -fno-rtti
在build.gradle中加入cpp编译选项:

cppFlags "-fexceptions"
cppFlags "-frtti"

最后build文件如下:

    compileSdkVersion 24
    buildToolsVersion "24.0.1"
    defaultConfig {
        applicationId "image.imageapp"
        minSdkVersion 19
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags "-std=c++11"
                cppFlags "-fexceptions"
                cppFlags "-frtti"
            }
        }
    }

4、找不到opencv.cmake

SET(OpenCV_INCLUDE_DIRS "/usr/include")
SET(OpenCV_LIB_DIR "/usr/lib")
INCLUDE_DIRECTORIES(${OpenCV_INCLUDE_DIRS})
二、NDK使用、Dlib调用

1、dlib接口调用

#include <jni.h>
#include <string>
#include <vector>
#include <iostream>

#include "face_detection/dlib/image_io.h"
#include "face_detection/dlib/image_processing.h"
#include "face_detection/dlib/image_processing/frontal_face_detector.h"

#include <ctime>


dlib::frontal_face_detector m_facedetector=dlib::get_frontal_face_detector();
//获取人脸框
std::vector<int > getfacerect(const std::vector<int>img,int height,int width)
{
    dlib::array2d<unsigned char>image;
    image.set_size(height,width);


    for (int i = 0; i < height; i++)
    {
        for(int j=0;j<width;j++)
        {
            int clr = img[i*width+j];
            int red = (clr & 0x00ff0000) >> 16; // 取高两位
            int green = (clr & 0x0000ff00) >> 8; // 取中两位
            int blue = clr & 0x000000ff; // 取低两位
            unsigned char gray=red*0.299+green*0.587+blue*0.114;
            //dlib::rgb_pixel pt(red,green,blue);
            image[i][j]=gray;
        }
    }



    clock_t begin = clock();
    std::vector<dlib::rectangle> dets= m_facedetector(image);


    std::vector<int >rect;
    if (!dets.empty())
    {
        rect.push_back(dets[0].left());
        rect.push_back(dets[0].top());
        rect.push_back(dets[0].width());
        rect.push_back(dets[0].height());
    }
    return rect;

}


extern "C" jintArray  Java_image_imageapp_MainActivity_stringFromJNI(JNIEnv *env, jobject /* this */
        ,jintArray image_data,jint image_height,jint image_widht)
{
    //const char* cha = env->GetStringUTFChars(imagepath, nullptr);
    // char* 转 string
   // std::string image_str(cha);
   // if(cha == NULL) {
        //return NULL;
   // }
    //jstring rtstr = env->NewStringUTF(image_str.c_str());//env->NewStringUTF(hello.c_str());
    // return rtstr;
    std::vector<int>image_datacpp(image_height*image_widht);
    jsize len = env->GetArrayLength(image_data);
    jint *body = env->GetIntArrayElements(image_data, 0);
    for (jsize i=0;i<len;i++){
        image_datacpp[i]=(int)body[i];
    }


    std::vector<int>rect=getfacerect(image_datacpp,image_height,image_widht);
    jintArray result =env->NewIntArray(4);
    env->SetIntArrayRegion(result, 0, 4, &rect[0]);

    return result;

}

2、MainActivity.JAVA中调用库函数:
    private int[] face_detection(Bitmap origin_image){
        float scale = 240.f/ Math.max(origin_image.getHeight(), origin_image.getWidth());
        int width = (int)(origin_image.getWidth()*scale);
        int height = (int)(origin_image.getHeight()*scale);
        Bitmap resize_image=Bitmap.createScaledBitmap(origin_image,width,height , false);

        // 保存所有的像素的数组,图片宽×高
        int[] pixels = new int[width * height];

        resize_image.getPixels(pixels, 0, width, 0, 0, width, height);
        int[] rect=stringFromJNI(pixels,height,width);
        int[] result_rect=new int[4];
        result_rect[0]=(int)(rect[0]/scale);
        result_rect[1]=(int)(rect[1]/scale);
        result_rect[2]=(int)(rect[2]/scale);
        result_rect[3]=(int)(rect[3]/scale);
        result_rect[2]=result_rect[2]+result_rect[0];
        result_rect[3]=result_rect[3]+result_rect[1];




        return  result_rect;
    }

3、显示绘制结果
            int[] rect=face_detection(scaled);
            Canvas canvas=new Canvas(scaled);
            Paint p=new Paint();
            p.setColor(Color.RED);
            p.setStrokeWidth(3.0f);
            canvas.drawLine(rect[0], rect[1], rect[2], rect[1], p);//up
            canvas.drawLine(rect[0], rect[1], rect[0], rect[3], p);//left
            canvas.drawLine(rect[0], rect[3], rect[2], rect[3], p);//down
            canvas.drawLine(rect[2], rect[1], rect[2], rect[3], p);
            //cnvs.drawRect(rectangle,paint);
            imageView.setImageBitmap(scaled);







评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值