Android中使用OpenCV

由于项目的关系,需要在Android中使用OpenCV。网上也有很多相关的博文,但由于版本等问题,按照他们的步骤并不能顺利的完成环境的配置。我自己也尝试摸索了几天,现在将我在配置中遇到的问题,陈列出来,希望能给他人有些帮助。


首先需要搭建NDK环境。需要安装Eclipse、Cygwin和android-ndk。具体的安装过程就不在这里陈述,网上有很多这方面的介绍,按照他们的步骤完成即可。我使用的ndk版本是r6b,大家最好选择较高的版本;较低的版本对C++的支持不是很好。


下载OpenCV,我使用的是OpenCV版本是2.3.1,大家可以在http://opencv.willowgarage.com/wiki/Android下载,上面有直接编译好的OpenCV库。该网址上也有环境的配置,大家可以参考。我主要想说在使用OpenCV过程中遇到的问题。

问题1:在创建工程时,要选择Build Target版本Android2.3.1,我之前选择的是Android2.2,在编译cpp文件时,可以正确生成动态库,但在加载apk时,一直没有加载成功,会出现以下问题:

[2011-09-20 19:57:24 - testopencv] Installation failed due to invalid APK file!
[2011-09-20 19:57:24 - testopencv] Please check logcat output for more details.
[2011-09-20 19:57:24 - testopencv] Launch canceled!

PS:后来测试在Android2.2,apk文件也可以加载成功,可能我当时设置有些错误。如果大家遇到一些奇怪的问题时,可以尝试改变一下Build Target版本


问题2:Android.mk,该MakeFile文件,我们可以从OpenCV所带的例子中拷贝该文件到我们工程中。只需要修改LOCAL_MODULE和LOCAL_SRC_FILES,改成自己的cpp文件名字和模块名字。下面是我的Android.mk文件的内容

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

include ../includeOpenCV.mk
ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
	#try to load OpenCV.mk from default install location
	include $(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk
else
	include $(OPENCV_MK_PATH)
endif


LOCAL_MODULE    := ImageConvert
LOCAL_SRC_FILES := ImageConvert.cpp
#LOCAL_LDLIBS +=  -llog -ldl

include $(BUILD_SHARED_LIBRARY)

注意:红色标注的部分都是相对路径,我们需要将文件放入正确的位置,不然在编译的时候,会找不到相应的文件。includeOpenCV.mk在OpenCV自带例子中也有,我们将该文件拷贝过来,和我们的工程文件放在同一级目录。如下图所示:我的工程文件名字是testopencv,Fuck是我另一个工程文件,includeOpenCV.mk就放在这里。

对于$(TOOLCHAIN_PREBUILT_ROOT)/user/share/OpenCV/OpenCV.mk,

该文件是在OpenCV-2.3.1\share\OpenCV中,由于涉及到相对路径,我们也要将OpenCV-2.3.1放在正确的位置。

OpenCV-2.3.1是和workspace放在同一级目录中的。

如下:我的testopencv所在的workspace是OpenCV,OpenCV-2.3.1位置如此。


问题3:Application.mk。将该文件从OpenCV自带的例子中拷贝到自己工程的jni文件夹下面,内容如下:

APP_STL :=gnustl_static

APP_CPPFLAGS :=-frtti -fexceptions

APP_ABI := armeabi

该文件主要是对STL库的一些选择;需要注意的是红色部分,APP_ABI是生成相应硬件平台的机器码。在OpenCV自带的例子的文件中,是armeabi-v7a,生成该平台的机器码,编译时可以成功,但在加载apk时会出现错误或者加载成功,但运行有错误。我们需要改成aremabi。

下面是我的测试代码,从sdcard中读出一张图片,然后保存为另外格式的图片

#include 

#include 
#include 
#include 
#include 
#include 
#include 

extern "C"
{
	jint Java_com_testopencv_testopencv_ConvertImage(
			JNIEnv *env, jobject obj)
	{

		IplImage *pImg = NULL;
		pImg = cvLoadImage("/mnt/sdcard/cat.jpg");

		if (pImg == NULL)
		{
			return 1;
		}

		cvSaveImage("/mnt/sdcard/cc.bmp", pImg);

		return 0;
	}
}

这里需要注意修改权限,使我们能够读写sdcard中的文件,在AndroidManifest.xml中加入下面语句


以上描述有些混乱,大家有不太清楚的地方,或者发现有错误的地方,欢迎交流指正。


你可能感兴趣的:(Android,android,wildcard,include,build,makefile,module)