您的位置:首页 > 移动开发 > Android开发

Android中使用OpenCV

2011-09-21 08:47 405 查看
由于项目的关系,需要在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 <jni.h>

#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc_c.h>

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中加入下面语句
<uses-permissionandroid:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permissionandroid:name = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

以上描述有些混乱,大家有不太清楚的地方,或者发现有错误的地方,欢迎交流指正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: