本文介绍如何构建OpenCV Android开发环境,在OpenCV与Android Studio集成的过程中,看了很多文章,但实际操作的时候都还是多多少少碰到了一些问题,所以写一篇文章,总结记录一下,也希望能够帮助到他人。

我使用的环境是:

  • MacOS 10.15.3
  • Android Studio 3.6.1(下载,包含MacOS Android SDK)
  • OpenCV Android SDK 3.4.9(下载

环境准备

Android Studio的安装就不说了非常简单(只要你网络畅通),OpenCV Android SDK下载后直接解压即可。关于OpenCV Android SDK目前最新的4.x版本是4.2.0,我刚开始使用的是这个版本,但发现问题比较多,所以最后使用了3.x的最新版本3.4.9。也强烈建议你使用3.x版本。

OpenCV底层的算法都是使用C/C++实现的,并且编译成了.so/.a,所以安卓(Java)要使用这些库必须通过JNI,安卓提供了一个开发工具包NDK(Native Development Kit),可以更方便的帮助开发人员通过JNI访问本地代码。这个包默认是没有安装的,所以第一步就是安装NDK及其一些依赖包。

安装NDK

直接上图吧:

3OxbyF.png
3OxqL4.md.png

安装NDK和CMake。

创建项目

先创建一个Android的工程,按照下面的图来就行(重点地方已标记):

3Ozr79.md.png
3OzykR.md.png
3OzD0J.md.png

项目创建成功后在build的时候可能会出现如下错误:

A problem occurred configuring project ':app'.
> NDK not configured. Download it with SDK manager. Preferred NDK version is '20.0.5594570'. Log: /Volumes/Files/Study/android/opencv/Demo/app/.cxx/ndk_locator_record.json

这个时候打开“Project Structure”设置一下NDK的路径即可(NDK安装完成后再Android SDK目录下):

NDK

然后再Build,应该就没有什么错误了。接下来就是导入OpenCV SDK了。

导入OpenCV

右键工程,选择新增module:

module

module type选择Eclipse ADT Project:

module type

然后就是选择模块的Source directory了,选择OpenCV Android SDK解压目录下面的sdk里面的java目录,如图所示:

source

java

选择以后,会自动生成一个模块名,自己也可以修改,建议使用默认值,因为随sdk的那些samples里面都用的是这个名字。4.x版本就没有这个贴心了。然后Next,后面都保持默认,直到Finish。

导入以后,修改导入的OpenCV模块的build.gradle文件。主要有这么几个修改点:

  • 修改第一行的apply plugin: 'com.android.application'apply plugin: 'com.android.library',这样才能将导入的OpenCV作为模块使用。
  • 用app的build.gradle里面的compileSdkVersionbuildToolsVersionminSdkVersiontargetSdkVersion值替换掉OpenCV build.gradle里面对应的值。然后编译。有可能会提示“AndroidManifest.xml”文件里面不应该有版本之类的错误,直接根据提示移除即可,如下图:

gradle

修改完之后,确保build成功。

然后就是将导入的OpenCV添加为app的依赖:

dependency

d2

确定即可。然后确保编译没有错误。到这里openCV依赖就算添加完了,只要编译没有错误,就可以在项目中使用OpenCV了。

但工作并没有完,OpenCV为了减小应用的体积,单独提供了一个OpenCV Manager的apk文件,这个文件包含了OpenCV的一些库。也就是要使用OpenCV,你的手机上面除了要安装你自己的app,还要安装OpenCV Manager才可以。如果没有装,你自己的app启动的时候,就会提示去Google Play下载。这里有几个坑:

  1. 我试了一下,即使能访问Google Play,也搜索不到这个app。
  2. 本来这个OpenCV Manager的apk文件是随sdk一起的,但4.2的版本里面没有这个文件了(我估计4.x的都没有),但3.x的sdk包里面却有,就在解压目录里面有个apk目录,里面有各个硬件架构的apk:

    apks

当然很多时候,让别人为了使用你的App,再去安装另外一个app不是很OK,所以也有一种方式可以将需要的OpenCV的库直接打到自己的这个App里面。操作方式如下(这里有很多坑,网上绝大多数都没有说清楚):

  • 将工程显示方式从Android切换为Project:

    project

  • 然后在app目录下面创建一个"jniLibs"目录,将OpenCV Android SDK的sdk->native->libs下面的目录拷贝到这个目录下(只拷贝需要的架构即可,一般手机都是arm64-v8a,模拟器一般都是x86、x86_64),如下图:

    so

    jnilibs

  • 然后在app目录下面的build.gradle文件的android里面添加如下内容(网上绝大多数教程都漏了这一步):

    srclib

    文字版:

        sourceSets {
            main {
                jni.srcDirs = []
                jniLibs.srcDirs = ['jniLibs']
            }
        }

最后就是验证环境是否完全部署好了:修改MainActivity.java文件,在onCreate里面增加一些内容,如下:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        // tv.setText(stringFromJNI());

        if (OpenCVLoader.initDebug()) {
            Log.i("CV", "load OpenCV Library Successful.");
           tv.setText("load OpenCV Library successfully.");
        } else {
            Log.i("CV", "load OpenCV Library Failed.");
            tv.setText("load OpenCV Library failed.");;
        }
    }

然后连上你的手机或者模拟机,运行一下,如果提示加载OpenCV库成功,那整个环境搭建就算完成了:

successfully

至此,环境搭建就算完成了,总体来说,网上的文章有很多问题,包括官方那古老的文档。祝你好运!下篇文章介绍一下如何基于整个环境构建一个手机端的目标检测程序。