标签:
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