码迷,mamicode.com
首页 > 移动开发 > 详细

编译并使用带有OpenCL模块的OpenCV for android SDK

时间:2015-08-11 16:01:35      阅读:535      评论:0      收藏:0      [点我收藏+]

标签:

OpenCV Android SDK中提供的静态、动态库是不支持OpenCL加速的,如果在程序中调用OpenCL相关函数,编译时不会报错,但运行时logcat会输出如下信息,提示OpenCL函数不可用

08-11 11:43:07.140: E/cv::error()(18198): OpenCV Error: Unknown error code -6 (OpenCL function is not available: [clGetPlatformIDs]) in void* opencl_check_fn(int), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/ocl/src/cl_runtime/cl_runtime.cpp, line 83
08-11 11:43:07.140: E/cv::error()(18198): OpenCV Error: Unknown error code -221 (OpenCL not available) in static cv::ocl::ContextImpl* cv::ocl::ContextImpl::getContext(), file /hdd2/buildbot/slaves/slave_ardbeg1/50-SDK/opencv/modules/ocl/src/cl_context.cpp, line 678

所以,如果想使用OpenCV for Android中的ocl模块,需要自己编译一套支持OpenCL的OpenCV库文件,同时还需要有一部具有OpenCL驱动的设备。下面详细讲述整个过程,整个的编译过程都是基于windows平台的,其他平台过程类似,只是编译时的命令会有所不同。

 

1.如何判断设备是否支持OpenCL

可以下载一款叫OpenCL-Z的软件。安装后,它可以检测当前设备的GPU是否支持OpenCL和是否具有OpenCL驱动。下面是豌豆荚上的下载地址:

http://www.wandoujia.com/apps/com.robertwgh.opencl_z_android

 

2.编译带OpenCL模块的OpenCV for Android

(1)首先需要从OpenCV官网下载源码,我是基于2.4.11版本的源码编译的(3.x版本工程整体结构变化太大,而且单独的ocl模块被合入其他模块了,我还没搞明白怎么用)。

这个网址可以下载到2.4.11版本的源码:https://github.com/Itseez/opencv/releases

(2)接下来配置需要的工具,主要有两个:cmake,Android ndk。下载&安装,在环境变量中配置好cmake的bin目录,并将ndk的根目录添加为ANDROID_NDK值。

(3)在opencv_path\modules\ocl\src\cl_runtime\cl_runtime.cpp文件中,做如下修改:

  第48行,#if defined(__linux__) 改为 #if defined(__linux__)&&!defined(__ANDROID__)

  第70行后,添加如下代码:

  

#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"
                                          };
#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

(4)编译opencv。打开cmd,将当前目录切换到opencv_path\platforms\下面,执行如下命令:

1 mkdir build_opencl
2 cd build_opencl
3 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_ABI=armeabi ..\..

其中,ANDROID_NDK是在环境变量中设置好的变量值,为android ndk的根目录,DANDROID_ABI可以根据需要选择。执行完毕后,执行如下命令即可:

cmake --build .

注意build后面的那个“.”不能少。

(5)编译完成后,把\build_opencl\lib\armeabi下面的库覆盖到opencv android sdk中的sdk\native\libs目录下对应的文件夹。

(6)clean原有的工程,然后build project。在设备上运行,一切OK。

这里是测试工程的源码,需要用自己图片path替换代码中的path,然后app会在同一目录下生成一幅灰度图。例如:输入图像为设备根目录下a.jpg,运行后同一目录下会生成agray.jpg灰度图片。

编译并使用带有OpenCL模块的OpenCV for android SDK

标签:

原文地址:http://www.cnblogs.com/hrlnw/p/4720977.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!