[Ubuntu 16.04][Anaconda3][OpenCV_Contrib 4.0.1]编译OpenCV4Android
OpenCV4.0.1
中的人脸识别模块被移植到了opencv_contrib
仓库,官网没有编译好的OpenCV4Android
包,所以需要自己编译
前后大概花了两天时间,一个是需要配置许多依赖,另外一个是官网没有很好的提供对于编译选项的解释,导致多次编译错误
OpenCV
在2.x/3.x/4.x
的迭代中有了很多的改变,NDK
同样也有改变,可能不再支持一些版本,或者指定一些版本工具
为了减少编译错误,当前使用最新的配置环境
源码下载
下载OpenCV-4.0.1压缩包以及OpenCV_Contrib仓库,
$ wget https://github.com/opencv/opencv/archive/4.0.1.zip
$ git clone https://github.com/opencv/opencv_contrib.git
注意:切换opencv_contrib到4.0.1版本
配置环境
当前操作系统:Ubuntu 16.04
NDK:android-ndk-r18b
cmake:
$ cmake --version
cmake version 3.14.0-rc3
CMake suite maintained and supported by Kitware (kitware.com/cmake).
ninja:
$ ninja --version
1.8.2
java:
$ java -version
java version "1.8.0_201"
Java(TM) SE Runtime Environment (build 1.8.0_201-b09)
Java HotSpot(TM) 64-Bit Server VM (build 25.201-b09, mixed mode)
ant:
$ ant -version
Apache Ant(TM) version 1.10.5 compiled on July 10 2018
python:
$ python --version
Python 3.6.8 :: Anaconda, Inc.
同时设置环境变量
# cmake
export PATH=/home/zj/software/cmake/cmake-3.14.0-rc3-Linux-x86_64/bin:$PATH
# ant
export ANT_HOME=/home/zj/software/ant/apache-ant-1.10.5
export PATH=$PATH:$ANT_HOME/bin
## android
export ANDROID_NDK=/home/zj/Android/android-ndk-r18b
export ANDROID_SDK=/home/zj/Android/Sdk
export ANDROID_HOME=/home/zj/Android/Sdk
# JAVA
export JAVA_HOME=/home/zj/software/java/jdk1.8.0_201
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
export JRE_HOME=$JAVA_HOME/jre
编译脚本
在opencv-4.0.1/platforms/android
文件夹内有编译脚本build_sdk.py
$ ./build_sdk.py --help
usage: build_sdk.py [-h] [--config CONFIG] [--ndk_path NDK_PATH]
[--sdk_path SDK_PATH]
[--extra_modules_path EXTRA_MODULES_PATH]
[--sign_with SIGN_WITH] [--build_doc] [--no_ccache]
[--force_copy] [--force_opencv_toolchain]
[work_dir] [opencv_dir]
Build OpenCV for Android SDK
positional arguments:
work_dir Working directory (and output)
opencv_dir Path to OpenCV source dir
optional arguments:
-h, --help show this help message and exit
--config CONFIG Package build configuration
--ndk_path NDK_PATH Path to Android NDK to use for build
--sdk_path SDK_PATH Path to Android SDK to use for build
--extra_modules_path EXTRA_MODULES_PATH
Path to extra modules to use for build
--sign_with SIGN_WITH
Certificate to sign the Manager apk
--build_doc Build javadoc
--no_ccache Do not use ccache during library build
--force_copy Do not use file move during library build (useful for
debug)
--force_opencv_toolchain
Do not use toolchain from Android NDK
执行脚本程序
python build_sdk.py --config=ndk-18.config.py --extra_modules_path=/home/zj/opencv/opencv_contrib/modules --no_ccache /home/zj/opencv/opencv-4.0.1/build_android/ /home/zj/opencv/opencv-4.0.1
- 参数
config
指定了要编译的指令集,文件ndk-18.config.py
是opencv
自带的,里面指定了armeabi-v7a/arm64-v8a/x86_64/x86
- 参数
extra_modules_path
用于指定opencv_contrib
的路径 - 参数
no_ccache
能够避免编译错误 - 还需要设置
work_dir
以及opencv_dir
注意:如果没有在之前没有设置过NDK
和SDK
的环境变量,需要在执行脚本时添加
--ndk_path NDK_PATH ... --sdk_path SDK_PATH ...
使用该脚本能够实现opencv4android
编译,但是还需要在里面修改一些参数
一个方面是禁止对于Android
工程/服务的编译,因为这涉及到外网连接,常常会失败;另一个方面是为了编译libopencv_java4.so
,需要打开一些开关
修改build_sdk.py
中的build_library
函数
# 原先
def build_library(self, abi, do_install):
cmd = ["cmake", "-GNinja"]
cmake_vars = dict(
CMAKE_TOOLCHAIN_FILE=self.get_toolchain_file(),
INSTALL_CREATE_DISTRIB="ON",
WITH_OPENCL="OFF",
WITH_IPP=("ON" if abi.haveIPP() else "OFF"),
WITH_TBB="ON",
BUILD_EXAMPLES="OFF",
BUILD_TESTS="OFF",
BUILD_PERF_TESTS="OFF",
BUILD_DOCS="OFF",
BUILD_ANDROID_EXAMPLES="OFF",
INSTALL_ANDROID_EXAMPLES="OFF",
)
# 修改后
def build_library(self, abi, do_install):
cmd = ["cmake", "-GNinja"]
cmake_vars = dict(
CMAKE_TOOLCHAIN_FILE=self.get_toolchain_file(),
INSTALL_CREATE_DISTRIB="ON",
WITH_OPENCL="OFF",
WITH_IPP=("ON" if abi.haveIPP() else "OFF"),
WITH_TBB="ON",
BUILD_EXAMPLES="OFF",
BUILD_TESTS="OFF",
BUILD_PERF_TESTS="OFF",
BUILD_DOCS="OFF",
BUILD_ANDROID_EXAMPLES="OFF",
INSTALL_ANDROID_EXAMPLES="OFF",
BUILD_ANDROID_SERVICE="OFF",
CMAKE_BUILD_TYPE="RELEASE",
BUILD_ZLIB="ON"
)
编译问题
问题一:
CMake Error: CMake was unable to find a build program corresponding to "Ninja". CMAKE_MAKE_PROGRAM is not set. You probably need to select a different build tool.
缺少ninja
,下载安装
conda install ninja
问题二:
CMake Error at /home/zj/Android/android-ndk-r16b/build/cmake/android.toolchain.cmake:40 (cmake_minimum_required):
CMake 3.6.0 or higher is required. You are running version 3.5.1
下载CMake源码编译安装
问题三:
CMake Error at /home/zj/software/cmake/cmake-3.14.0-rc3-Linux-x86_64/share/cmake-3.14/Modules/CMakeTestCXXCompiler.cmake:53 (message):
The C++ compiler
"/home/zj/Android/android-ndk-r16b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-g++"
is not able to compile a simple test program.
...
...
/bin/sh: 1: ccache: not found
ninja: build stopped: subcommand failed.
问题四:编译完成后没有libopencv_java.so
参考:
Building OpenCV4Android from source does not output libopencv_java.so
creat libopencv_java.so from source
这个没有很好理解,但是通过添加CMAKE_BUILD_TYPE="RELEASE"
能够解决这个问题
cmake
解析
参考:libc++
执行build_sdk.py
就能够实现opencv4android
编译,里面调用了cmake
进行构建,执行如下
cmake -GNinja -DOPENCV_EXTRA_MODULES_PATH='/home/zj/opencv/opencv_contrib/modules' -DCMAKE_TOOLCHAIN_FILE='/home/zj/Android/android-ndk-r18b/build/cmake/android.toolchain.cmake' -DINSTALL_CREATE_DISTRIB='ON' -DWITH_OPENCL='OFF' -DWITH_IPP='OFF' -DWITH_TBB='ON' -DBUILD_EXAMPLES='OFF' -DBUILD_TESTS='OFF' -DBUILD_PERF_TESTS='OFF' -DBUILD_DOCS='OFF' -DBUILD_ANDROID_EXAMPLES='OFF' -DINSTALL_ANDROID_EXAMPLES='OFF' -DBUILD_ANDROID_SERVICE='OFF' -DCMAKE_BUILD_TYPE='RELEASE' -DBUILD_ZLIB='ON' -DANDROID_STL='c++_static' -DANDROID_ABI='arm64-v8a' -DANDROID_PLATFORM_ID='3' -DANDROID_TOOLCHAIN='clang' /home/zj/opencv/opencv-4.0.1
参数CMAKE_TOOLCHAIN_FILE
指定了交叉编译的配置文件,使用的是NDK
包里面的android.toolchain.cmake
参数ANDROID_STL
指定了编译用的标准库,这是因为Android
自NDK r18
以来指定了c++_static
作为唯一可用的STL
相关参考
OpenCV
提供了一个非正式的编译库:master-contrib_pack-contrib-android/