为Android平台编译支持OpenCL的Opencv静态库

来源:互联网 发布:好春光不如梦一场 知乎 编辑:程序博客网 时间:2024/05/16 01:14

Opencv中封装了OpenCL,直接下载的Opencv4Android SDK中提供了一些相关的库,我们可以利用nm命令查看这些库是否包含opencl的相关函数。ocl集成在core中,所以我们直接查看libopencv_core.a这个库。

nm -D libopencv_core.a

查看结果如下图,其中包含了ocl、opencl等.o文件。

这里写图片描述

也许,这还不能断定这个静态库是否支持OpenCL,那么最好的方法就是写一个测试程序,去尝试获取手机的GPU信息,之后我也会写一篇文章来介绍Android平台的GPU信息获取。大家可以利用OpenCL-Z这个软件来查看手机平台的GPU信息。OpenCL-Z.apk

当然,我们可以亲自动手去编译一套可以支持opencl的库,本文也基于OpenCV3.2.0,介绍如何编译Opencl支持库。

工具准备:

Cmake的安装和配置 点击下载cmake ,需要指定cmake的系统变量,安装过程有个选项可以选上,会自动添加Cmake的bin目录到path变量中。
Android NDK:可以到官网下载或者直接用Android studio安装,同样也需要指定NDK的系统变量。
Opencv Sources的下载:官网,百度云

关键文件修改:

  • 修改CMakeList.txt:
    这里写图片描述

    打开该文件,找到WITH_OPENCL这一项,将其状态修改为ON:
    这里写图片描述

  • 修改opencl_core.cpp文件:

    打开文件..\modules\core\src\opencl\runtime\opencl_core.cpp,找到 #if defined(linux)这一项将其修改为:
    #if defined(__linux__)&&!defined(__ANDROID__)

    如下:

    #if defined(__linux__)&&!defined(__ANDROID__)#include <dlfcn.h>#include <stdio.h>......#endif //linux

    在上面这片代码块之后添加Android的编译代码:

    #if defined(__ANDROID__)    #include <dlfcn.h>    #include <sys/stat.h>#if defined(__ARM_ARCH_8A__) || defined(_X64_)    static const char *default_so_paths[] = {                                            "/system/lib64/libOpenCL.so",                                            "/system/vendor/lib64/libOpenCL.so",                                            "/system/vendor/lib64/egl/libGLES_mali.so"                                          };#else    static const char *default_so_paths[] = {                                            "/system/lib/libOpenCL.so",                                            "/system/vendor/lib/libOpenCL.so",                                            "/system/vendor/lib/egl/libGLES_mali.so"                                          };#endifstatic int access_file(const char *filename)    {        struct stat buffer;        return (stat(filename, &buffer) == 0);    }    static void* GetProcAddress (const char* name)    {        static void* h = NULL;        unsigned int i;        if (!h)        {            const char* name;            for(i=0; i<(sizeof(default_so_paths)/sizeof(char*)); i++)            {                if(access_file(default_so_paths[i])) {                    name = (char *)default_so_paths[i];                    h = dlopen(name, RTLD_LAZY);                    if (h) break;                }            }            if (!h)                return NULL;        }        return dlsym(h, name);    }    #define CV_CL_GET_PROC_ADDRESS(name) GetProcAddress(name)#endif

编译Opencv

在..\platforms\目录下创建一个新文件夹opencv_armeabi_v7a并进入该目录,创建一个opencv_build.bat文件,文件里面的内容如下:

cmake -G "MinGW Makefiles" -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON -DWITH_EIGEN=off -DCMAKE_TOOLCHAIN_FILE=..\android\android.toolchain.cmake -DCMAKE_MAKE_PROGRAM="%ANDROID_NDK%\prebuilt\windows-x86_64\bin\make.exe" -DANDROID_NATIVE_API_LEVEL=23 -DANDROID_ABI=armeabi-v7a ..\..cmake --build .

上面ANDROID_NDK是Android NDK的home目录,需要在环境变量中指定好
-DANDROID_NATIVE_API_LEVEL=23: 指定api level为android-23
-DANDROID ABI=armeabi-v7a: 指定编译的架构为armeabi-v7a, 它可以指定为以下这些:
·”armeabi-v7a”, “armeabi”, “armeabi-v7a with NEON”, “armeabi-v7a-hard with NEON”, “armeabi-v7a with VFPV3”, “armeabi-v6 with VFP”, “arm64-v8a”, “mips”, “mips64”, “x86”, “x86_64”
双击opencv_build.bat运行编译命令,耐心等待,等很久。

这里写图片描述

编译完成后,可以在lib目录下找到编译好的静态库。这时候再利用nm命令去查看库中的信息,就可以知道是否包含有opencl相关的cpp文件了。当然,大家可以写一个小demo来验证这些库是否支持OpenCL。如何写一个demo来检验一些编译库呢,可以参阅:Opencv4Android的OpenCL的测试,使用Opencv的ocl封装库

0 0
原创粉丝点击