移植Dlib 到 Android (Dlib + OpenCV2)以及可能会遇到的一些问题

时间:2022-02-05 16:35:41

上篇文章 里面配置好了Android + OpenCV2的环境。
下面介绍如何把Dlib也移植到Android端:

1.从官网上面下载相关的Dlib。
2.解压压缩包到拥有读写权限的文件夹下面。
3.把dlib(包含所有源代码)的文件夹拷贝到jni文件夹下面。
移植Dlib 到 Android (Dlib + OpenCV2)以及可能会遇到的一些问题
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 (Dlib + OpenCV2)以及可能会遇到的一些问题

好了,现在dlib就移植到了Android上面。