Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager

Posted mydddfly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager相关的知识,希望对你有一定的参考价值。

http://johnhany.net/2016/07/build-opencv-manager-for-android-on-ubuntu/

   最近想在Android上尝试一下SIFT和SURF匹配算法,但考虑到这些算法都是专利保护的,并没有被包含在预编译库中,所以还需要自己来动手编译OpenCV Android SDK。在OpenCV 2.4.x版本中,这些算法被包含在nonfree模块中;从3.0版本开始,用于图像特征匹配的一些算法(比如SIFT,SURF,BRIEF,FREAK等)被转移到了opencv_contrib项目的xfeatures2d模块中。在PC环境下,为C++编译opencv+contrib库是很方便的,不过为Android平台的编译过程就有些麻烦了。

        我在编译的过程中也遇到了一些问题,在网络上搜索相应解决方案时也发现很多人都在尝试为OpenCV Android SDK添加contrib(nonfree)支持,某些遇到难以解决的问题最后只能绕路而行,比如这里这里。我找到相应解决办法后回应了他们,但愿对别人会有所帮助吧!

        本文要介绍的内容就是如何在Ubuntu 16.04环境下利用最新的OpenCV和opencv_contrib为Android平台编译一个可用的OpenCV Android SDK,并生成相应的OpenCV Manager。

2017.08.03更新:

        更新到OpenCV 3.2,Android SDK API 24,Android NDK r15b。

        我原本挣扎了三天尝试在Windows平台通过MinGW来编译最新版本的OpenCV Android SDK,但在生成Manager的apk时遇到很棘手的问题,只好作罢转回Linux进行编译。不过读者放心,在Linux下编译得到的OpenCV Android SDK也可在Windows下直接使用,另外我在文章结尾添加了我编译好的SDK下载链接。

        我的开发环境如下:

                Ubuntu 16.04 LTS (x64)

                GCC 5.4.0

                CMAKE 3.9.0

                OpenCV 3.2.0

                Android SDK API 24(Android 7.0)

                Android SDK Tools r25.2.2

                Androird NDK r15b

                Python 3.5

        虽然目前Android SDK Tools已经更新到r26,但由于其相对原来的工具变化较大,为了稳妥起见,建议手动降级到r25版本(下载地址:https://dl.google.com/android/repository/tools_r25.2.2-linux.zip

        当然在编译过程中还会用到很多其他工具和软件包,比如Ninja,Ant等,我会在文中需要的时候给出它们的版本和安装方法。

        关于GCC,CMAKE和Python的安装过程本文就不详述了,一是因为这些工具的安装过程很容易,网络上的介绍都很详细,二是因为之前刚刚配置好TensorFlow,安装了一大堆软件包,我也不清楚本文的内容究竟会涉及哪些依赖库,我会尽量把我在编译过程中所需的工具和库标记出来。

        同样,Android SDK和NDK的安装方法这里也不会作过多介绍。我是通过Android Studio 2.1.2提供的SDK Manager下载的Android SDK和Android NDK,在Android Studio中下载Android SDK和Android NDK的方法可以参考《Android Studio 2上利用NDK进行OpenCV 3.1开发》,虽然开发平台不同,但在软件界面中的操作过程是相似的。我的Android SDK路径是/home/john/Android/Sdk,Android NDK的路径是/home/john/Android/Sdk/ndk-bundle。


下载源码

        在opencv的master分支Release页面下载opencv 3.2源码,解压到一个有读写权限的目录下,比如/home/john/Downloads/opencv-master。在这里下载对应3.2的opencv-contrib源码,解压到某个目录下,个人习惯是解压到OpenCV的源码根目录下,使得opencv-contrib/modules目录的路径如/home/john/Downloads/opencv-master/opencv_contrib/modules,这个路径后面会用到。

个人推荐在编译其他OpenCV版本甚至编译其他软件包时要下载有版本号的Release版,而不是直接git下来最新的master版。毕竟master一般是正在开发修缮的版本,即便是整合了功能强大的CI(比如OpenCV在用的buildbot,或者其他开源库喜欢用的travis-ci)也不能保证其测试过程考虑到了大多数应用环境。

        如果你的机器上已经有了一份opencv源码,但不想花时间去下载最新版本,至少要保证你的opencv源码是在16年5月份之后下载的(具体来讲,至少要包含该Pull Request:Added –extra_modules_path to build_sdk.py #6460,这样你的build_sdk.py才会包含后面要用到的extra_modules_path)。

        仅仅下载好源码还不够,还要对源码做一些修改,具体如下:

        1.把/home/john/Downloads/opencv-master/opencv_contrib/modules/xfeatures2d/include/opencv2目录下的xfeatures2d.hpp文件和xfeatures2d文件夹复制到/home/john/Downloads/opencv-master/modules/features2d/include/opencv2目录下。此时,该目录包含的文件应该如下图所示:

技术分享图片        2.找到/home/john/Downloads/opencv-master/modules/features2d/misc/java/src/cpp目录,打开features2d_manual.hpp文件,做以下修改:

        在第8行增加一个头文件opencv2/xfeatures2d.hpp,即把

 

 

改为

 

 

        把第120-125行的

 

 

改为

 

 

        把第239-245行的

 

 

改为

 

 

        把第254-256行的

 

 

改为

 

 


编译OpenCV Android SDK

        找到/home/john/Downloads/opencv-master/platforms/android目录,在该目录下会发现build_sdk.py文件,这个文件就是用来编译OpenCV Android SDK的Python脚本文件。

        首先做一些检查工作:

        1.在第78行的ABIs定义了需要编译的ABI目标以及相应的NDK工具链。保险起见,可以先在/home/john/Android/Sdk/ndk-bundle/toolchains中查看一下你的NDK工具链版本,如果版本号有所不同,就要修改build_sdk.py中对应ABI工具链的版本,如下图所示:

技术分享图片        mips和mips64两行被注释掉的原因是,在我的机器上编译时,由于依赖库之一Google Protobuf的编译错误,无法为这两个架构成功编译OpenCV Android SDK。不过我手边并没有采用该架构的Android设备,而且我暂时还不需要考虑短期内编写的代码有太好的兼容性,所以干脆放弃对这两种架构进行编译。如果感兴趣,你可以试着为mips编译一下:)目前在编译OpenCV 3.2版本时,所有ABI都能够成功编译(包括:arm64-v8a,armeabi,armeabi-v7a,mips,mips64,x86,x86_64)。上图并没有相应更新,还请见谅!

        2.安装Ninja。打开终端,输入:

 

 

        另外,我在编译之前参考这里又安装了几个用于交叉编译的库,不确定是否必要,但还是贴出来吧:

 

 

        其中版本号4.9根据你的NDK工具链的版本来修改(工具链路径在android-sdk\ndk-bundle\toolchains当中)。

        3.安装Ant。在终端输入:

 

 

        如果不安装Ant,在编译过程中CMAKE关于Java的输出信息全是NO,而且后面还会出现unknown target ‘opencv_engine‘的错误。

        4.在build_sdk.py里还有很多可以根据需要来修改的地方,比如-DANDROID_NATIVE_API_LEVEL可以适当地提高,可以选择开启-DBUILD_EXAMPLES和-DBUILD_TESTS等等。这里为了演示的目的,除了前文提到的,其他地方全部保持默认,不做修改。

        5.在终端中输入:

 

 

        注意命令是一行的,中间没有换行符。

        根据build_sdk.py文件中第252行的说明,其采用的参数按照以下格式:

 

 

        其中,<output-dir>是保存编译中间结果和最终结果的目录(也叫工作目录),<android-sdk-path>指向OpenCV源码目录,<android-sdk-path>为Android SDK目录,<ndk-path>为Android NDK目录,<opencv-contrib-path>为opencv_contrib/modules所在的路径。


结果

        最终,在/home/john/Downloads/opencv-master/build目录中会得到一个名为OpenCV-android-sdk的文件夹,这就是你编译得到的OpenCV Android SDK。和官方预编译库一样,在apk子文件夹中是OpenCV Manager的安装包,在sdk/java文件夹中是OpenCV的Java接口,sdk/native是OpenCV的Native接口。

        在新项目中使用自己编译的OpenCV Android SDK时,要注意需要在设备上重新安装OpenCV Manager,还要修改Android.mk中指向OpenCV.mk的路径。

技术分享图片

        如果需要调用SIFT,SURF等匹配算法,还要把相应的源码文件(位于/home/john/Downloads/opencv-master/opencv_contrib/modules/xfeatures2d/src)拷贝到项目jni文件夹中,然后在Android.mk中为LOCAL_SRC_FILES添加对应的源码文件。

        在编译的过程中如果发现有错误或异常出现,可以首先比较一下OpenCV官方BuildBot的输出信息,便于分析自己的问题原因。最新编译结果的链接为:http://pullrequest.opencv.org/buildbot/one_line_per_build。一次编译成功的输出结果为precommit_pack_android Build Log #116。如果你的网络比较好,甚至可以把网站上生成的压缩包下载下来(比如这里)!

        我编译产生的OpenCV Android SDK可以在这里下载:http://pan.baidu.com/s/1kVOejLt。因为考虑到在编译过程中需要从网络下载一些文件,我已经把Linux与Windows编译所需的文件全部下载好,并和3.2的源码一同放在sources文件夹中。感兴趣的读者可以直接用这个源码包进行编译。

        另外附上一篇在Android上利用SIFT,SURF和FREAK进行目标匹配的教程:《深入OpenCV Android应用开发 中文版 – 第三章代码更新》


参考资料

[1] http://stackoverflow.com/questions/30657774/surf-and-sift-algorithms-doesnt-work-in-opencv-3-0-java

[2] https://github.com/opencv/opencv/issues/5561

[3] https://github.com/opencv/opencv/issues/6215

[4] http://answers.opencv.org/question/73863/how-to-run-build_sdkpy-for-android-sdk/

[5] https://zami0xzami.wordpress.com/2016/03/17/building-opencv-for-android-from-source/

[6] http://eevee.cc/2017/05/05/build-ocv-for-android-with-cuda/

以上是关于Ubuntu 16.04下为Android编译OpenCV 3.2.0 Manager的主要内容,如果未能解决你的问题,请参考以下文章

[Android 编译] Ubuntu 16.04 LTS 成功编译 Android 6.0 源码教程

配置Ubuntu16.04编译Android

Ubuntu 16.04 LTS 成功编译 Android 6.0 源码教程 (转)

Ubuntu 16.04编译Android 7.1.2

Ubuntu16.04下编译android6.0源码

Ubuntu16.04配置Android5.0编译环境