Android studio 2.3.3+Dlib

最近因为需要,尝试着将Dlib移植到android上。android小白一枚,做之前没接触过android,所以就用了别人说比较好的android studio 最新稳定版(windows下)。在android studio2.3.3版本中使用cmake+clang来编译C/C++。我直接将之前在Ubuntu17.04的跑通了的代码拿过来,之前用的cmake+gcc,所以CMakeList.txt也是直接复制过来稍加修改。因为用dlib一般少不了要用opencv的库,网上很多教程,我配置的时候一些问题基本都能从网上找到解决办法,就不在这里多说了。

其实弄好opencv之后,再把这个库加到项目里基本就没啥问题了,修改CmakeList.txt如下(这里是最基本的样子):

set(pathToProject D:/AndroidStudioProjects/MyProject)
set(pathToOpenCv D:/AndroidStudioProjects/OpenCV-android-sdk)
set(pathToDlib D:/AndroidStudioProjects/MyProject/app/src/main/dlib)
cmake_minimum_required(VERSION 3.4.1)
include(${pathToDlib}/dlib/cmake)
add_library( lib_opencv SHARED IMPORTED )
include_directories(lib_opencv ${pathToOpenCv}/sdk/native/jni/include )
set_target_properties( lib_opencv PROPERTIES IMPORTED_LOCATION ${pathToProject}/app/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so)
add_library( native-lib SHARED src/main/cpp/native-lib.cpp )
find_library( log-lib log )
target_link_libraries( native-lib ${log-lib} lib_opencv dlib::dlib )

内容和dlib给的examples没啥太大差别。android studio 会自动把dlib加进项目中,然后编译就行啦。

问题及解决:

(1)

error :no member named ‘round’ in namespace ‘std’; did you mean simply ‘round’?

一开始看到这个报错在网上翻了好多帖子,都没找到解决办法,无奈只能自己从头文件开始找起。把clang报错的内容拿出来看了,头文件包含路径没有问题,编译的参数没有问题(这个函数是从c++11之后才有的,所以有人会说在build.gradle里的cppFlags加上“-std=c++11”,这个在建项目的时候选C++11就已经加进去了啊,没啥用啊),最后就去看头文件cmath,在cmath中找到了这个函数的声明:

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  // types
  using ::double_t;
  using ::float_t;

  // functions
  ……
  using ::round;
  ……

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

咋一看也没问题啊,可是上面这一段是包含在下面这两句里面的,-std=c++11已经加了,所以就是那个宏的问题了。然后就去找,在别的头文件中确实有这个宏定义,但是那个头文件的引用顺序应该在cmath之后,所以才会出这个问题。

#if __cplusplus >= 201103L
#ifdef _GLIBCXX_USE_C99_MATH_TR1

知道问题之后解决起来就是各种办法了,一开始我直接在cmath中加了一句

#define _GLIBCXX_USE_C99_MATH_TR1 1

编译,没错。不过后来用这个关键词去检索,查到了stackoverflow上的一个类似的问题,按照里面的方法改了一下,也没问题。不过,

$ndk\sources\cxx-stl\gnu-libstdc++\libs\armeabi\include\bits\c++config.h

这个路径再自己看一下,好多个c++config.h,应该改哪个就根据实际来咯。
(2)

error: no type named ‘exception_ptr’ in namespace ‘std’; did you mean ‘exception’?

这个问题和上面的如出一辙,先去找对应的头文件,在该文件的最后

#if (__cplusplus >= 201103L) && (ATOMIC_INT_LOCK_FREE > 1)
#include
#include
#endif

std::exception_ptr就是在里面定义的,那就往回找ATOMIC_INT_LOCK_FREE 这个宏,在atomic_lockfree_defines.h里面有如下宏定义:

#if __cplusplus >= 201103L
……
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
……
#endif

参考预定义宏,用clang++.exe -E -dM - < nul可以看到这个宏在clang里也是有的并且值为2(那为啥还会报错???黑人问号脸.jpg)。这里暂时先不管了,我直接把#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE改成了#define ATOMIC_INT_LOCK_FREE 2 ,编译妥妥的,至于这两个宏,自己去查资料吧……

(3)

error: “DLIB_NO_GUI_SUPPORT is defined so you can’t use the GUI code. Turn DLIB_NO_GUI_SUPPORT off if you want to use it.”

这是移植过来又一个问题,因为之前在Ubuntu下面已经捯饬过dlib,所以大概知道问题出现在dlib的cmake文件中,DLIB_NO_GUI_SUPPORT这个宏相关的在dlib/dlib/CMakeLists.txt里面,可以自己看一下,下图是问题所在Android studio 2.3.3+Dlib_第1张图片
在windows下面编译我怎么去给你弄这些包啊?那干脆注释掉好了。

(8月3日修改)在写程序测试的时候也遇到过一些问题,参考了github上的这个,Java的bitmap转换成mat,还有如何在Java里使用C++类等。
打算把dlib的人脸特征点提取使用在android程序上,但是dlib和opencv库的存储开销对一个小程序来说就有点大,如果大家有啥减少存储开销的好办法请留言我。

你可能感兴趣的:(android)