如何在android中使用opencv_第1页
如何在android中使用opencv_第2页
如何在android中使用opencv_第3页
如何在android中使用opencv_第4页
如何在android中使用opencv_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如何在 Android 中使用 OpenCV 分类: Android 技术初探2012-07-13 11:54 368人阅读 评论(0) 收藏 举报 androideclipselayoutjniapijava 原文链接: /shakespeare001/article/details/7743510 看了网上的很多教程和官方 /wiki/Android 提供的如 何在 Android 上使用 OpenCV 的教程,照着一步一步的做最后总有些问题,不是 APK 安装失 败就是运行时突然报错退出。和同学一起摸索了一段时间后,终于弄成功,在这里做一个 总结。最关键的问题是项目中各个文件夹和文件的位置要放置正确,而且目标机器的 CPU 架构要设置正确,下面是配置的详细过程。 一、Android 开发环境 1.下载安装 Sun JDK 6 访问 /technetwork/java/javase/downloads/index.html 这里并且 安装好 JDK 注意:不要使用 OpenJDK,Android SDK 支持 Sun JDK 2.Android SDK 访问 /sdk/index.html 获取 android sdk,如果选择的是 Windows 安装文件,则你还需要安装32bit JRE。 3.Android SDK 组件 l Android SDK Tools, revision 12或者更新 l SDK 平台 Android 2.2, API 8, revision 2(also known as Java API) 这是 OpenCV Java API 支持的最低平台,OpenCV 发布默认为 Android 2.2 4. Eclipse IDE 和 ADT plugin for Eclipse 访问 /downloads/下载 Eclipse 并解压即可。 打开 Eclipse,选择 Help-Install New Software 菜单,但后点击 Add 按钮,在 Add Repository 对话框中的 Name 一栏输入“ADT Plugin“,Location 一栏输入 https:/dl- /android/eclipse/,但后点击 OK。在 Available Software 对话框中选中 所有单选框,然后一路 next 直到 finish 为止,当安装 ADT 完毕后重启 Eclipse 即可。 5. Android NDK 访问 /sdk/ndk/index.html 下载最新的 Android NDK,是 一个 ZIP 解压包,只需解压到某个路径即可,例如“F:android-ndk-r6b- windowsandroid-ndk-r6b“,再把这个路径添加到系统的环境变量 PATH 中。 6. Cygwin 访问 /index.html 下载最新的 Cygwin,最好安装全部的 Cygwin 组件。 假设安装在“C:cygwin“下,将“C:cygwinbin“添加到系统环境变量 PATH 中,为了方便的 在命令行下调用 Android NDK,找到“C:cygwinhome(你的用户名)“这个目录,打开文件 “.bash_profile“,在文件的最下面加上下面两行内容: NDK=/cygdrive/f/android-ndk-r6b-windows/android-ndk-r6b export NDK 这样便可以在命令行中以 “$NDK/ndk-build“ 这种形式调用 NDK 了。 二、OpenCV 1.首先下载在 /projects/opencvlibrary/files/opencv- android/2.3.1/ 已经预编译好的 opencv 包。 2.把下载好的包解压到某个路径上(最好不要带空格),例如“F:OpenCV-2.3.1-android- bin“ 三、如何在 Android 程序中使用 OpenCV 有两种方式(重点讲后面一种): 1.使用 OpenCV Java API。 OpenCV 安装路径“F:OpenCV-2.3.1-android-bin“下有两个文件夹,如下图 将文件夹“OpenCV-2.3.1“拷贝到你的 Eclipse 工作空间所在的目录,也就是在你的项目的 上一级目录中,然后导入到工作空间中,在 Package Explorer 中选择你的项目,单机右键 在弹出菜单中选择 Properties,然后在弹出的 Properties 窗口中左侧选择 Android,然后 点击右下方的 Add 按钮,选择 OpenCV-2.3.1并点击 OK,如下图: 此时,展开你的项目树,你可以看到新加了一个 OpenCV-2.3.1_src 目录,如下图,那么就 是正确添加了 OpenCV Java API,否则就是你放置 OpenCV-2.3.1的目录路径不正确。 然后就可以在你的 Java 源文件中导入 OpenCV 的 API 包,并且使用 OpenCV API 了,OpenCV API 的包的形式如下: Org.opencv.(OpenCV 模块名).(OpenCV 类名) 例如: Org.opencv.core.Mat 2.利用 JNI 编写 C+ OpenCV 代码,通过 Android NDK 创建动态库(.so) 新建一个工作空间,例如“TestOpenCV“,在 Window-Preferences 中设置好 Android SDK 的路径,如下图所示。 然后新建一个 Android 项目,Build Target 选择 Android2.2,命名为“HaveImgFun“,活动 名改为 HaveImgFun,Package name 中填写 com.testopencv.haveimgfun,最后点击 finish。 如同使用 OpenCV Java API 那样,将 OpenCV-2.3.1文件夹拷贝到与工作空间同一级目录中; 另外,将“F:OpenCV-2.3.1-android-binsamples“下的 includeOpenCV.mk 文件拷贝到和 项目 HaveImgFun 同一级目录中,如下图所示: (上面这个各个文件夹和文件的放置很重要,因为 OpenCV-2.3.1下的 OpenCV.mk 中有很多 相对路径的指定,如果不是这样放置,在 NDK 生成动态库时可能会报文件或文件夹无法找 到的错误) 选择 Package Explorer 中你的项目,右键选择 new-folder,新建一个名为 jni 的文件夹, 用来存放你的 c/c+代码。 然后把 res-layout 下的 main.xml 的内容改为下面所示: 上面的代码就是一个线性布局里面包含2个按钮加上一个显示图像的 ImageView 在文件夹 src 下的 com.testopencv.haveimgfun 包中新建一个类用于包装使用了 opencv c+代码的动态库的导出函数,类名为 LibImgFun。 Eclipse 会为你创建一个新的文件 LibImgFun.java,将里面的内容改为: package com.testopencv.haveimgfun; public class LibImgFun static System.loadLibrary(“ImgFun“); /* * param width the current view width * param height the current view height */ public static native int ImgFun(int buf, int w, int h); 从上面的代码可以得知,我们的动态库名字应该为“libImgFun.so” ,注意“public static native int ImgFun(int buf, int w, int h)“中的 native 关键字,表明这个函数来 自 native code。static 表示这是一个静态函数,这样就可以直接用类名去调用。 在 jni 文件夹下建立一个“ImgFun.cpp“的文件,内容改为下面所示: #include #include #include #include using namespace cv; extern “C“ JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun( JNIEnv* env, jobject obj, jintArray buf, int w, int h); JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun( JNIEnv* env, jobject obj, jintArray buf, int w, int h) jint *cbuf; cbuf = env-GetIntArrayElements(buf, false); if(cbuf = NULL) return 0; Mat myimg(h, w, CV_8UC4, (unsigned char*)cbuf); for(int j=0;jNewIntArray(size); env-SetIntArrayRegion(result, 0, size, cbuf); env-ReleaseIntArrayElements(buf, cbuf, 0); return result; 上面的代码中#include 是必须要包含的头文件,#include 是 opencv 要包含的头文件。 动态库要导出的函数如下声明: JNIEXPORT jintArray JNICALL Java_com_testopencv_haveimgfun_LibImgFun_ImgFun( JNIEnv* env, jobject obj, jintArray buf, int w, int h); JNIEXPORT 和 JNICALL 是必须要加的关键字 jintArray 就是 int,这里返回类型要么为空,要么为 jni 中定义的类型,事实上就是 CC+类型前面加上 j,如果是数组,则在后面加上 Array。 函数名的命名规则如下: Java_(包路径)_(类名)_(函数名) (JNIEnv *env, jobject obj, 自己定义的参数.) 包路径中的“.“用“_“(下划线)代替,类名就是上面包装该动态库函数的类的名字,最后一 个才是真正的函数名;JNIEnv *env 和 jobject obj 这两个参数时必须的,用来调用 JNI 环境下的一些函数;后面就是你自己定义的参数。在这里,jintArray buf 代表了传进来 的图像的数据,int w 是图像的宽,int h 是图像的高。 这个函数的功能是将传进来的图像的上半部分涂成黑色。 然后再在 jni 下新建两个文件“Android.mk“文件和“Application.mk“文件,这两个文件事 实上就是简单的 Makefile 文件。 其中将 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 := ImgFun LOCAL_SRC_FILES := ImgFun.cpp include $(BUILD_SHARED_LIBRARY) Application.mk 的内容改为如下所示: APP_STL:=gnustl_static APP_CPPFLAGS:=-frtti -fexceptions APP_ABI:=armeabi armeabi-v7a 其中 APP_ABI 指定的是目标平台的 CPU 架构。 (经过很多测试,android2.2必须指定为 armeabi,android2.2以上的使用 armeabi-v7a,如果没有设置对,很有可能安装到 android 虚拟机失败,当然你同时如上面写上也是可以的) 上面的步骤完成后,就可以使用 NDK 生成动态库了,打开 cygwin,cd 到项目目录下,如下 图所示: 输入$NDK/ndk-build 命令,开始创建动态库。成功的话如下图所示。 这时候刷新 Eclipse 的 Package Explorer 会出现两个新的文件夹 obj 和 libs。 现在,只剩最后一步完成这个测试程序。 将一张图片,例如“lena.jpg“放到项目 res-drawable-hdpi 目录中并刷新该目录。 然后将 HaveImgFun.java 的内容改为下面所示: package com.testopencv.haveimgfun; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.widget.Button; import android.view.View; import android.widget.ImageView; public class HaveImgFun extends Activity /* Called when the activity is first created. */ ImageView imgView; Button btnNDK, btnRestore; Override public void onCreate(Bundle savedInstanceState) super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTitle(“使用 NDK 转换灰度图“); btnRestore=(Button)this.findViewById(R.id.btnRestore); btnRestore.setOnClickListener(new ClickEvent(); btnNDK=(Button)this.findViewById(R.id.btnNDK); btnNDK.setOnClickListener(new ClickEvent(); imgView=(ImageView)this.findViewById(R.id.ImageView01); Bitmap img=(BitmapDrawable) getResources().getDrawable(R.drawable.lena).getBitmap(); imgView.setImageBitmap(img); class ClickEvent implements View.OnClickListener public void onClick(View v) if(v = btnNDK) long current=System.currentTimeMillis(); Bitmap img1=(BitmapDrawable) getResources().getDrawable(R.drawable.lena).getBitmap(); int w=img1.getWidth(),h=img1.getHeight(); int pix = new intw * h; img1.getPixels(pix, 0, w, 0, 0, w, h); int resultInt=LibImgFun.ImgFun(pix, w, h); Bitmap resultImg=Bitmap.c

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论