在上篇文章 里面配置好了Android + OpenCV2的环境。
下面介绍如何把Dlib也移植到Android端:
1.从官网上面下载相关的Dlib。
2.解压压缩包到拥有读写权限的文件夹下面。
3.把dlib(包含所有源代码)的文件夹拷贝到jni文件夹下面。
4.我们需要把source.cpp文件一并加入源文件进行编译:
Android.mk
#添加下面这行
LOCAL_SRC_FILES += ./dlib/all/source.cpp
5.修改Applicaiton.mk文件:
Application.mk
#禁用Dlib的GUI
APP_CPPFLAGS += -DDLIB_NO_GUI_SUPPORT=1
#使Dlib可以加载JPEG类型的图片
APP_CPPFLAGS += -DDLIB_JPEG_SUPPORT -DDLIB_JPEG_STATIC
6.现在就算是把dlib移植到Android上面了。
移植肯定不会这么简单的,上面是过程,下面是遇到的问题
1.两个库之间一些冲突:具体的现象:
Application.mk
APP_STL := gnustl_static
APP_STL := c++_static
前面一篇文章,使用gnustl_static作为标准库,没有任何问题,因为Opencv for Android 好像就是用gnu的标准库来编译的。但是一旦加入了dlib,那么就会出现类似下面的这种错误:
error :no member named ‘round’ in namespace ‘std’; did you mean simply ‘round’?
error :no member named ‘to_string’ in namespace ‘std’;
因为dlib使用的是libc++标准库,就是Applicaiton.mk里面的c++_static。
但是如果我们把gnustl_static替换成c++ _static的话,那么opencv就要报错了:一堆链接错误,也是关于标准库的错误。
解决办法:
自己实现to_string 和 round函数,并在相应的文件里面include。
to_string:
#include <string>
#include <sstream>
using namespace std;
namespace std {
template <typename T> std::string to_string(const T& n) {
std::ostringstream stm;
stm << n;
return stm.str();
}
}
round:
using namespace std;
namespace std {
template <typename T> T round(T v) {
return (v > 0) ? (v + 0.5) : (v - 0.5);
}
}
2.找不到类似于
undefined reference to 'jpeg_set_quality(jpeg_compress_struct*, int, int)'
/home/mercury/AndroidStudioProjects/app/src/main/jni/./dlib/all/../image_saver/save_jpeg.cpp:153: error: undefined reference to 'jpeg_start_compress(jpeg_compress_struct*, int)'
/home/mercury/AndroidStudioProjects/app/src/main/jni/./dlib/all/../image_saver/save_jpeg.cpp:158: error: undefined reference to 'jpeg_write_scanlines(jpeg_compress_struct*, unsigned char**, unsigned int)'
/home/mercury/AndroidStudioProjects/app/src/main/jni/./dlib/all/../image_saver/save_jpeg.cpp:161: error: undefined reference to 'jpeg_finish_compress(jpeg_compress_struct*)'
又是链接错误,这个问题可能是由于c++命名规则造成的,我们需要在jpeg_loader.cpp文件里面加上
extern “C”
好了,现在dlib就移植到了Android上面。