基于Opencv的Android图像处理(Eclipse和ndk)

前段时间做了一个失败的图像处理项目,结果虽然不太好,也学到了不少东西,其中关于在Eclipse里如何使用opencv的图片处理api折腾了一阵子,记录一下:

1、Android NDK 配置

其实opencv提供了一些基于android的库,但是个人认为限制很多,需要装个opencv manager应用作为基础服务,而且感觉很多基础类型和函数都没有,可能我也不太熟悉,网上很多关于opencv的帖子都是关于C++的,所以最后还是决定使用ndk开发。

网上很多帖子说要配置Cygwin,其实根本不用,只要NDK用比较新的就可以了,r9以后就不需要配置Cygwin来编译C++文件了,我开始用的是r9d后来换成相对新的r10了。

新建Android工程,然后新建jni文件夹,然后把工程转成C++的,

在项目名称上右键,选择New,选择other,然后输入选择Convert to a C/C++………………



Next,下一步选择非常关键

左边选择Makefile project,然后在右边选择Other Toolchain,我之前配置cygwin,但是这里根本不需要。这里不能选错,因为每个编译工具Eclipse会自动拷贝一些windows系统里的环境变量过来,会出各种奇葩的问题。


因为我已经转过一次了,所以下面这个finish按钮不让点了,选择完以后点击finish即可。

转完以后,打开cpp文件,这个时候如果cpp文件里有c++代码的话,肯定会报很多错误,一切都是正常的。


然后打开properties,选择c/c++ build 下面的 Environment查看一下当前已有的环境变量


如果多了,就说明配置得不对,比如如果刚才错选了Cygwin的GCC编译环境,那这里就会有显示Cygwin的环境变量。然后点击add,添加NDK环境变量,命名为NDKROOT,值设置为ndk的路径,路径不要太长,最好不要有中文


点击ok后,选择c/c++ build ,设置编译命令,这里要设置Builder setting里面的Build command和勾选Behavior里对应图中的三个复选框,后面的命令都空着,不要填

然后保存,选择C/C++ General里面的Path and Symbol,增加编译C++所需要的Ndk里面的头文件


这里,添加了ndk 的c++头文件路径和opencv sdk 的头文件路径,这五个路径缺一不可,添加完以后,点击apply,如果还是出现IplImage,jintArray等之类的无法识别的错误的话,就clean一下工程。

添加完了以后,Eclipse在cpp文件里就不会识别不了jni.h,JNICALL之类的C++基础的文件和标示符了,函数前面的JNICALL之类的无法识别的话,直接删掉即可,不影响使用。

配置结束,然后在项目中写cpp文件完成你需要的各种图片处理功能即可

正常结果如下:Eclipse不会报错,然后终端会显示自动编译生成了so库文件



遇到的各种奇葩报错记录如下:

1、Eclipse提示找不到ndk-build.cmd

D:\android-ndk-r10\ndk-build.cmd系统找不到指定路径

在Windows下面配置Eclipse里面的ndk-build.cmd指令的时候,Ndk路径也是对的,指定的目录下也有对应的ndk-build.cmd文件,但是Eclipse提示找不到ndk-build.cmd文件,

在CMD下,cd到Ndk目录下,运行ndk-build,也会提示提示找不到ndk-build.cmd文件,这个时候基本就可以确定,NDK的版本下错了,肯定是NDK不是32位的,要下载32位的NDK,一般64位的NDK文件名都有x86_64,如下图所示,第二个就是64位的,这样解压后32位的系统是认不出来的,必须用第一个带了32和只有x86的压缩包。


2、cbuf= env->GetIntArrayElements(buf, false); 报错

这一行报错, 提示如下,把false改成NULL即可


更正后如下:



3 报错make.exe: *** No rule to make target`../../sdk/native/jni/OpenCV.mk'.  

报错截图如下:


项目里配置各种C++头文件也都配置好了,但是还是报这个错误,这个错误时由于

Jni里面的android.mk文件里的配置路径写错导致的,



改成opencv的opencv.mk文件的绝对路径即可,路径需要自己查看本机上opencv.mk的存放路径,我的路径如下:


把include的路径修改成本地的绝对路径,修改后如下:


复制windows的路径过来,最好把斜杠改成反斜杠,不改也行,然后保存,或者clean一下就可以了。


4、报错:Program "/ndk-build.cmd" is not found in PATH


这种报错,看提示是在Eclipse的变量Path中找不到ndk-build.cmd命令

打开Eclipse的变量Path看看


点击右边的Variables按钮查看该项目对应的变量里面有没有NDKROOT


果然是没有的,


添加一下就好了,设置成ndk在本机的路径即可,

项目名称上右键,选择Properties,添加环境变量NDKROOT



5、报错Unresolved inclusion:<opencv2/core/core.hpp>

这个主要是由于opencv的库文件没有配置对引起的

重新配置一次就好了

查看一下原始配置


很明显,这个路径不是我本机上opencv的路径,点击右边的edit按钮修改成本机上正确的opencv的路径即可。

添加以后,apply一下,或者重新clean一下基本就解决了。这个还可以解决__android_log_print无法识别等等问题

6、报错Type 'size_t' could not be resolved

size_t无法识别,如果其他#include <opencv2/core/core.hpp>这些是正常的,提示Type 'size_t' could not be resolved,检查一下添加的头文件,是否有下面这个include存在,没有的话添加一下即可


本人的路径如下:

D:\android-ndk-r10\toolchains\arm-linux-androideabi-4.8\prebuilt\windows\lib\gcc\arm-linux-androideabi\4.8\include

因为我设置的变量NDKROOT为D:\android-ndk-r10,所以我添加以后的效果如上图所示。

7、报错Invalid arguments'Candidates are:void * memset(void *, int, unsigned long int)

报错代码


报错的原因是这个函数第三个参数的类型是size_t类型的,也就unsigned long int类型的,强制转型即可

8、报错Symbol '__FLT_MAX__' couldnot be resolved

FLT_MAX无法识别

代码如下


添加头文件即可

#include <float.h>

但是在Eclipse里添加了,貌似也没用,还没有解决,等待大神指导,可能是依赖混乱。

但是其实这应该就是宏定义的一个常量而已,搜了一下值应该是这个,自己在代码里宏定义一下,先调通代码要紧。

/* min positive value */
#define FLT_MIN 1.175494351e-38F

/* max value */
#define FLT_MAX 3.402823466e+38F

/* smallest such that 1.0+FLT_EPSILON!= 1.0 */
#define FLT_EPSILON 1.192092896e-07F

就是 定义了 FLOAT 所能表示的最大值,最小值,以及最小的正数


9、报错Unspecified error (The function is notimplemented


这个报错的原因是java层调用c层的接口参数没匹配对,这有两种情况,

第一种是参数不匹配;第二种是参数匹配了,但是在C层代码里没有声明那个函数可以被外部调用。

比如我是调用函数Process,

Java层参数和C层的参数也是对应的

Java层:


C层:JNIEnv*是上下文环境参数,jobject是上下传递的对象数据,后面的四个参数要严格与java层对应


在C层实现这个函数之前,要通过extern "C"再声明一下这个函数,然后再去实现



相关的文档链接如下,都是开发中踩过的坑,记录一下,0分共享:

http://download.csdn.net/detail/diaoliangwang/9577380


猜你喜欢

转载自blog.csdn.net/Diaoliangwang/article/details/51920836