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

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

nm -D libopencv_core.a

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

为Android平台编译支持OpenCL的Opencv静态库_第1张图片

也许,这还不能断定这个静态库是否支持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:
    为Android平台编译支持OpenCL的Opencv静态库_第2张图片

    打开该文件,找到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 
    
    
    #include 
    
    ......
    
    #endif //linux
    

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

    
    #if defined(__ANDROID__)
    
        #include 
        #include 
    
    
    #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"
                                              };
    
    #endif
    
    
    static 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运行编译命令,耐心等待,等很久。

为Android平台编译支持OpenCL的Opencv静态库_第3张图片

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

你可能感兴趣的:(Opencv4Android)