OpenCV android 开发

这篇指南用于帮助你在你的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 开发_第1张图片

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

    OpenCV android 开发_第2张图片

在大多数情况下,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).

    OpenCV android 开发_第3张图片

  2. 在应用程序工程中添加一个对OpenCV4Android SDK的引用Project -> Properties -> Android -> Library -> Add 选中OpenCV Library - 2.4.9;

    OpenCV android 开发_第4张图片

  3. 如果你的应用程序没有没有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 开发_第5张图片

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

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

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

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

    OpenCV android 开发_第6张图片

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. 下面的这一行:

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

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

    注意

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


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

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

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

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

    也要包含如下的这一行:

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

  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 layoutBlank Activity。将layout命名为HelloOpenCvLayout

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

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

    OpenCV android 开发_第7张图片

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

    OpenCV android 开发_第8张图片

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

    OpenCV android 开发_第9张图片

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

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

    OpenCV android 开发_第10张图片

  11. 定义你的activity实现CvCameraViewListener2接口,并通过定义遗漏的方法来解决activity有关的errors。为这个activity定义onCreateonDestroy和onPause并根据下面的代码片段实现它们。通过添加所需的imports来解决errors。

    OpenCV android 开发_第11张图片

  12. 在设备或模拟器上运行你的应用程序。

让我们讨论一些最重要的步骤。每一个有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.

你可能感兴趣的:(OpenCV android 开发)