Dlib 在Android的编译
1.首先下载最新的Dlib源码,地址:http://dlib.net, 代码依赖一个模型,下载地址:http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
2.新建一个Native C++的工程,如图所示:
3.把第一步下载的文件全部copy到cpp下面,如图所示:
4.如下修改CMakeLists.txt
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s -03 -Wall")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s -03 -Wall")
include(./dlib-19.19/dlib/cmake)
add_library( # Sets the name of the library.
bzfacetrack
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp)
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log)
target_link_libraries( # Specifies the target library.
bzfacetrack
# Links the target library to the log library
# included in the NDK.
dlib ${log-lib} android jnigraphics)
5.最后写测试代码,把第一步下载的模型文件shape_predictor_68_face_landmarks.dat放到SD卡上,测试代码用到的IMG_25_small.jpg,是一张包含人脸的图片,请自行准备,这个代码运行一次需要20秒左右,后续代码会优化,请持续关注
#include
#include
#include
#include
#include
#include
#include "common/BZLogUtil.h"
#include "common/bz_time.h"
using namespace dlib;
using namespace std;
int test_face_landmark() {
// We need a face detector. We will use this to get bounding boxes for
// each face in an image.
frontal_face_detector detector = get_frontal_face_detector();
// And we also need a shape_predictor. This is the tool that will predict face
// landmark positions given an image and face bounding box. Here we are just
// loading the model from the shape_predictor_68_face_landmarks.dat file you gave
// as a command line argument.
int64_t startTime = getCurrentTime();
shape_predictor sp;
deserialize("/sdcard/bzmedia/shape_predictor_68_face_landmarks.dat") >> sp;
BZLogUtil::logD("deserialize 耗时=%lld", getCurrentTime() - startTime);
array2d img;
// load_image(img, "/sdcard/bzmedia/IMG_25.jpg");
load_image(img, "/sdcard/bzmedia/IMG_25_small.jpg");
// Now tell the face detector to give us a list of bounding boxes
// around all the faces in the image.
startTime = getCurrentTime();
std::vector dets = detector(img);
BZLogUtil::logD("detector 耗时=%lld", getCurrentTime() - startTime);
BZLogUtil::logD("Number of faces detected: %lld", dets.size());
// Now we will go ask the shape_predictor to tell us the pose of
// each face we detected.
std::vector shapes;
for (unsigned long j = 0; j < dets.size(); ++j) {
startTime = getCurrentTime();
full_object_detection shape = sp(img, dets[j]);
BZLogUtil::logD("sp 耗时=%lld", getCurrentTime() - startTime);
BZLogUtil::logD("number of parts: %d", shape.num_parts());
BZLogUtil::logD("pixel position of first part: x=%ld y=%ld", shape.part(0).x(),
shape.part(0).y());
BZLogUtil::logD("pixel position of second part: x=%ld y=%ld", shape.part(1).x(),
shape.part(1).y());
shapes.push_back(shape);
}
BZLogUtil::logD("---finish---");
return 0;
}
extern "C" JNIEXPORT jint JNICALL
Java_com_luoye_dlibdemo_MainActivity_nativeTest(
JNIEnv *env,
jobject /* this */) {
test_face_landmark();
return 0;
}
6.修改build.gradle,如下,修改cmake,ndk:
defaultConfig {
applicationId "com.luoye.dlibdemo"
minSdkVersion 17
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
arguments '-DANDROID_PLATFORM=android-16', '-DANDROID_TOOLCHAIN=clang',
'-DANDROID_STL=c++_static', '-DDLIB_NO_GUI_SUPPORT=1', '-DCMAKE_BUILD_TYPE=Release ..'
cppFlags "-std=c++11 -o3", '-frtti', '-fexceptions'
}
}
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
7.至此已经完成编译测试,代码地址https://github.com/bookzhan/bzdlib.git,在分支dlib_src上,请注意区分