OpenCV android 开发

Stella981
• 阅读 683

这篇指南用于帮助你在你的Android项目中使用OpenCV。

请记住这篇指南是基于Windows 7所写的,尽管它应该适用于OpenCV4Android SDK所支持的其他OS平台。

这篇指南假设你已经安装并配置了下列程序:

  • JDK

  • Android SDK and NDK

  • Eclipse IDE

  • ADT and CDT plugins for Eclipse

关于上面的程序,如有任何需要帮助的,你可以参考我们的_Introduction into Android Development_指南。

这份指南也假设你已经在你的开发机上安装了OpenCV4Android SDK,并在你的测试设备上安装了对应OpenCV Manager。关于这些,如果你有任何需要帮助的,可以参考我们的OpenCV4Android SDK指南。

如果你完全按照这些步骤做了,但仍然遇到了error,请通过OpenCV4Android讨论组或OpenCVQ&A forum和我们联系。我们将尽力为你提供帮助。

在你的Android项目中使用OpenCV库

在这一节中我们将解释如何在已有的项目中使用OpenCV。自Android的2.4.2 release开始,_OpenCV Manager_被用于给apps提供OpenCV的最好的可用版本。你可以在此处获取更多信息:Android OpenCV Manager和这些slides中。

Java

Application Development with Async Initialization

建议在应用开发中使用异步的方式来初始化。它使用OpenCV Manager来访问目标系统中外部安装(大概指库不是安装在应用程序中的)的OpenCV库。

  1. 把OpenCV库添加进你的workspace中。 使用菜单_File -> Import -> Existing project in your workspace_.

    点_Browse_按钮并定位到OpenCV4Android SDK (OpenCV-2.4.9-android-sdk/sdk)。

    OpenCV android 开发

  2. 在应用程序项目中添加一个对OpenCV Java SDK的引用:Project -> Properties -> Android -> Library -> Add 选择OpenCV Library - 2.4.9.

    OpenCV android 开发

在大多数情况下,OpenCV Manager可能自动的由Google Play安装了。对于那些Google Play不可用的情况,比如模拟器,开发板,等等,你可以使用adb工具手动安装它。参考How to select the proper version of OpenCV Manager来获取详细信息。

有一个简单的代码片段实现了异步初始化。它演示了基本的原理。参考“15-puzzle” OpenCV示例来获取更多信息。

public class Sample1Java extends Activity implements CvCameraViewListener {

    private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
        @Override
        public void onManagerConnected(int status) {
            switch (status) {
                case LoaderCallbackInterface.SUCCESS:
                {
                    Log.i(TAG, "OpenCV loaded successfully");
                    mOpenCvCameraView.enableView();
                } break;
                default:
                {
                    super.onManagerConnected(status);
                } break;
            }
        }
    };

    @Override
    public void onResume()
    {
        super.onResume();
        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
    }
    ...
}

在这个例子中,应用程序以异步的方式与OpenCV Manager协同工作。OnManagerConnected将在初始话结束时,在UI线程中被调用。请注意,在调用这个回调之前,不允许使用OpenCV调用或者加载OpenCV-dependent native库。请在OpenCV初始化成功之后再加载你自己的依赖于OpenCV的native库。默认的BaseLoaderCallback实现将application context看作是Activity,并会在初始化失败时调用Activity.finish()方法来退出。要覆写这一行为,你需要覆写BaseLoaderCallback类的finish()方法并实现你自己的初始化方法。

Application Development with Static Initialization

以这种方法,所有的OpenCV binaries会被包含进你的应用包中。这种方法主要设计来在开发的时候使用。对于产品代码,这种方法是不推荐的,在release包中建议通过上面描述的异步初始化与OpenCV Manager通信。

  1. 以与添加上面的异步初始化部分相同的方式将OpenCV library工程添加到你的workspace中。使用菜单_File -> Import -> Existing project in your workspace_, 点击 _Browse_按钮并选择OpenCV SDK path (OpenCV-2.4.9-android-sdk/sdk).
![Add dependency from OpenCV library](http://static.oschina.net/uploads/img/201407/07095253_5q59.png)
  1. 在应用程序工程中添加一个对OpenCV4Android SDK的引用_Project -> Properties -> Android -> Library -> Add_ 选中OpenCV Library - 2.4.9;

    OpenCV android 开发

  2. 如果你的应用程序没有没有JNI部分,可以只是把对应的OpenCV native libs从<OpenCV-2.4.9-android-sdk>/sdk/native/libs/<target_arch> to复制到你的工程的libs/<target_arch>目录下。

    在应用程序中有JNI部分的情况下,则你需要修改你的Android.mk文件而不是手动的libraries复制:把下面的两行代码添加在"include $(CLEAR_VARS)"之后及"include path_to_OpenCV-2.4.9-android-sdk/sdk/native/jni/OpenCV.mk"之前。

    OpenCV android 开发

    结果看起来应该像下面这样:

    OpenCV android 开发

    随后OpenCV libraries将在JNI编译期间被复制到你的应用的libs目录下。

    Eclipse将会自动地把libs目录下的所有libraries包含进应用程序包中(APK)。

  3. 在你的应用程序中启用OpenCV的最后一步是在调用OpenCV API之前进行Java初始化。这可以通过在,比如,在Activity类的static部分完成:

    OpenCV android 开发

    如果你的应用程序包含其他OpenCV-dependent native libraries的话,你应该在OpenCV初始化之后加载它们:

    OpenCV android 开发

Native/C++

要把OpenCV作为native部分,来构建你自己的Android应用,则应该依照下面的步骤来做:

  1. 你可以在你的工程的jni/Android.mk中使用一个环境变量来指定OpenCV包的位置,或者只是硬编码绝对或相对路径。

  2. 为当前应用程序所写的jni/Android.mk应该使用这类文件的通用规则来写。

    要获取详细的信息请参考Android NDK包中的Android NDK文档,在文件<path_where_NDK_is_placed>/docs/ANDROID-MK.html中。

  3. 下面的这一行:

    OpenCV android 开发

    应该被插入jni/Android.mk文件中这一行的后面

    OpenCV android 开发

  4. 有些变量可以被用来定制OpenCV stuff,但当你的应用程序通过OpenCV Manager API使用异步初始化initialization时,则不需要使用它们。

    注意

    这些变量应该在"include .../OpenCV.mk"行之前设置:

    OpenCV android 开发

    复制必须的OpenCV动态库到工程的libs目录下以使它们被包含进APK中。

    OpenCV android 开发

    跳过把OpenCV camera相关libs复制到项目的libs目录下。

    OpenCV android 开发

    执行对OpenCV的静态链接。默认情况下使用动态链接,并且工程的JNI lib会依赖于libopencv_java.so。

  5. 应该有Application.mk文件,并且其中应该包含这几行:

    OpenCV android 开发

    也要包含如下的这一行:

    OpenCV android 开发

    应该指定应用程序的目标平台。有些情况下,依赖于OpenCV,当编译一个应用程序的JNI库时,会有一个linkage error (比如"In function 'cv::toUtf16(std::basic_string<...>... undefined reference to'mbstowcs'")出现。Application.mk中下面的这一行通常可以解决它:

    OpenCV android 开发

  6. 在(重)编译Java部分并创建一个APK之前,_手动_使用ndk-build调用或者设置 Eclipse CDT Builder 来编译native JNI lib。

Hello OpenCV Sample

创建一个简单的OpenCV-centric应用程序的过程。它将能够访问camera输出,处理它并显示结果。

  1. 打开Eclipse IDE,创建一个新的干净的workspace,创建一个新的Android工程_File ‣ New ‣ Android Project_

  2. 相应地设置name,target,及minSDKVersion。编译OpenCV4Android SDK的最小的SDK版本是11。最小的设备API Level (for application manifest)是8。

  3. 允许Eclipse创建默认的activity。将activity命名为HelloOpenCvActivity。

  4. 选择full screen layout的Blank Activity。将layout命名为HelloOpenCvLayout。

  5. 把OpenCV library工程导入到你的workspace中。

  6. 在你的工程属性中引用OpenCV library。

    OpenCV android 开发

  7. 编辑你的layout xml文件,并使用下面的layout:

    OpenCV android 开发

  8. 给AndroidManifest.xml文件添加如下的permissions:

    OpenCV android 开发

  9. 在AndroidManifest.xml中设置application theme来隐藏标题栏及系统按钮。

    OpenCV android 开发

  10. 把OpenCV library初始化的部分加入你的activity。通过加入所需的imports来解决errors。

![](http://static.oschina.net/uploads/space/2014/0707/112209_2Jb1_919237.png)
  1. 定义你的activity实现CvCameraViewListener2接口,并通过定义遗漏的方法来解决activity有关的errors。为这个activity定义onCreate,onDestroy和onPause并根据下面的代码片段实现它们。通过添加所需的imports来解决errors。
![](http://static.oschina.net/uploads/space/2014/0707/112344_zJyI_919237.png)
  1. 在设备或模拟器上运行你的应用程序。

让我们讨论一些最重要的步骤。每一个有UI的Android应用必须实现Activity和View。通过第一步,我们创建了空的activity和默认的view layout。最简单的OpenCV-centric应用必须实现OpenCV初始化,创建它自己view来显示来自于camera的preview,并实现CvCameraViewListener2接口来从camera获取framew并处理它。

首先我们使用xml layout来创建我们应用程序的view。我们的layout只由一个full screen 组件opencv.android.JavaCameraView组成。这个类是在OpenCV库中实现的。它继承自CameraBridgeViewBase,而后者则继承自SurfaceView并使用了标准的Android camera API。你也可以使用org.opencv.android.NativeCameraView类,它实现了相同的接口,但使用了VideoCapture来作为camera访问的后端。opencv:show_fps="true" andopencv:camera_id="any"选项启用FPS消息,并允许使用设备上的任何的camera。应用程序会首先尝试使用后置camera。

创建了layout之后,我们需要实现Activity类。OpenCV初始化过程已经在上面讨论过了。在这个例子中我们使用了异步的初始化。CvCameraViewListener接口的实现允许你在从camera获取了frame之后而在把会渲染在屏幕上之前执行一定的处理。最重要的函数是onCameraFrame。它是回调函数,当从camera提取了frame时会被调用。回调的输入是CvCameraViewFrame类的对象,其表示从camera获取的frame。

注意

不要保存或在onCameraFrame回调之外使用CvCameraViewFrame对象。这个对象没有它自己的状态,并且在回调之外它的行为是不可预测的!

它有rgba()和gray()方法,以分别允许以RGBA的形式和单通道灰度Mat获取frame。它期望onCameraFrame函数返回将在屏幕上绘制的RGBA frame。

译自:http://docs.opencv.org/trunk/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#application-development-with-static-initialization

Done.

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这