这次的教程比较复杂,只是个人最近项目中刚好遇到的问题,把解决的过程记录下来顺便分享,大家看不懂没关系,可以先马一下以后开发APP项目中使用OpenCV遇到问题再来回顾~
我后面有空也会尝试写一些OpenCV入门的教程,这个做计算机视觉必备的开源库还是有很多值得研究的地方的。
0.前言
OpenCV3.1时代开始,Android平台就已经有官方提供的OpenCV库了,理论上我们是不需要再自行编译的。而且OpenCV的官方建议也是直接使用OpenCV4Android库(也就是预编译的libopencv_java3.so),并提供了两套使用方法:
- 利用OpenCV提供的全套Java接口, 在Android Java层调用。
- 利用OpenCV提供的C/C++ 接口, 在JNI层使用(就跟在PC端VC++下使用OpenCV一样一样的)。
但是由于在实际的应用中难免会遇到一些问题,比如在Android工程中如果要同时使用SNPE(一个高性能神经网络加速库)和OpenCV时,由于SNPE使用的STL链接的是libc++,而OpenCV默认使用的是gnu_stl,所以会导致gradle不管怎么配置都无法正常编译过的情况。
这种情况下如果gradle中选择arguments '-DANDROID_STL=c++_shared'
的话SNPE可以正常编译,但是在使用像imwrite
这样的OpenCV函数时就会报链接错误。相反如果gradle中选择arguments '-DANDROID_STL=gnu_stl'
则SNPE无法编译通过。
另外一方面,官方预编译好的OpenCV4Android库是不带contrib
模块的,所以无法使用像是`xfeatures2d`这样的类。
以上原因驱使我们需要能够自己从源码编译OpenCV4Android的库。编译方法有几种,可以在Linux下基于NDK编译,也可以在Windows中使用MinGW编译,本文选择的是前者,因为可以生成Docker镜像方便以后部署编译环境。
1.使用现成Dock编译镜像
这里使用的是我已经配置好的编译镜像,由于镜像文件尺寸很大(10GB左右),所以就不上传了,大家可以看完这一节的方法后根据下一节的教程自己生成一样的镜像。(这里就假设大家已经会使用Docker啦,话说Docker 这种神器早用早享受啊~)
Docker镜像环境配置如下:
镜像名称: opencv4android-builder.image
系统版本: Ubuntu 16.04
内部OpenCV版本: 3.4.8
启动Docker的命令如下:
docker run -it --name opencv4android-builder --network host
-v /home/pengzhihui/_share/OpenCV:/workspace/_share/OpenCV
-v /etc/timezone:/etc/timezone
-v /etc/localtime:/etc/localtime
opencv4android-builder.image
进入Docker容器之后首先设置一下环境变量:
export ANDROID_NDK=/workspace/opencv4android/tools/ndk/android-ndk-r17
export PATH=${PATH}:$ANDROID_NDK
export ANDROID_SDK=/workspace/opencv4android/tools/sdk/android-sdk-linux
export PA