编译方法有几种:1.使用现成Dock编译镜像(一)

图片[1]-编译方法有几种:1.使用现成Dock编译镜像(一)-唐朝资源网

OpenCV%3A//opencv.org/releases/库了,理论上我们是不须要再自行编译的。并且OpenCV的官方建议也是直接使用OpenCV4Android库(也就是预编译的libopencv_java3.so),并提供了两套使用方式:

并且因为在实际的应用中难免会碰到一些问题,例如在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未能编译通过。

另外一方面opencv源码编译,官方预编译好的OpenCV4Android库是不带contrib模块的,所以未能使用像是xfeatures2d这样的类。

以上缘由驱使我们须要才能自己从源码编译OpenCV4Android的库。编译方式有几种,可以在Linux下基于NDK编译,也可以在Windows中使用MinGW编译,本文选择的是后者,由于可以生成Docker镜像便捷之后布署编译环境。

1.使用现成Dock编译镜像

这儿使用的是我早已配置好的编译镜像,因为镜像文件规格很大(10GB左右),所以就不上传了,你们可以看完这一节的方式后按照下一节的教程自己生成一样的镜像。(这儿就假定你们已然会使用Docker啦,话说Docker这些利器早用早享受啊~)

Docker镜像环境配置如下:

启动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 PATH=$ANDROID_SDK/tools:$PATH
export JAVA_HOME=/workspace/opencv4android/tools/jdk/jdk1.8.0_221
export JRE_HOME=${JAVA_HOME}/jre  
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib  
export PATH=${JAVA_HOME}/bin:$PATH
source  ~/.bashrc

假如须要更改NDK或则SDK等的版本则也须要更新那些环境变量。

之后步入目录/workspace/opencv4android/build,运行下边的脚本即可开始编译:

python ../opencv/platforms/android/build_sdk.py 
--extra_modules_path=/workspace/_net/opencv_contrib/modules/ 
--config ../opencv/platforms/android/ndk-17.config.py

如须要更改编译选项,则可以更改opencvplatformsandroidandroid.toolchain.cmake文件。

2.从头开始搭建编译环境

这一节会介绍怎么从头开始搭建里面的镜像环境,整个过程踩了好多坑,所以这儿记录出来。

2.1生成Docker基础容器

使用的基础镜像为Ubuntu16.04,因而假如本地没有这个镜像的话,须要先从网上pull一下:

sudo docker pull ubuntu:16.04

之后生成容器:

docker run -it --name opencv4android-builder-tmp  --network host 
-v /home/pengzhihui/_share/OpenCV:/workspace/_share/OpenCV 
-v /etc/timezone:/etc/timezone 
-v /etc/localtime:/etc/localtime 
ubuntu:16.04

步入容器以后先构建在/worksapce/opencv4android工作目录(名子你自己定):

mkdir /worksapce/opencv4android && cd /worksapce/opencv4android

再依照须要构建如下结构的几个目录(有的目录是前面下载过程形成的):

接出来须要安装一些基础工具:

由于纯净的ubuntuDocker镜像是不带任何文本编辑器的,其实了假如你喜欢用cat命令那也可以直接操作。

deb http://mirrors.aliyun.com/ubuntu/ xenial main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial main

deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main
deb http://mirrors.aliyun.com/ubuntu/ xenial universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main
deb http://mirrors.aliyun.com/ubuntu/ xenial-security universe
deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security universe

再度执行aptupdate即可。

编译Java代码须要用到ant或则gradle,而且我由于是在服务器上进行编译,没有x11环境,也没装AndroidStudio,所以这儿使用ant编译Java。

2.2编译安装Cmake

倘若直接使用apt安装cmake的话,得到的版本会偏低(我这儿是3.5),而编译OpenCV源码要求的Cmake最低版本是3.6,因而须要从源码编译安装一下。

另一方面,假如所用的cmake版本没有支持HTTPS,则编译OpenCV过程中会报Downloadfailed:1;”unsupportedprotocol”错误,造成编译过程中的一些文件难以下载,因而勿必安装下边的方式安装Cmake。

下载Cmake3.9.0的源码并编译:

wget --no-check-certificate https://cmake.org/files/v3.9/cmake-3.9.0.tar.gz
tar -zxvf cmake-3.9.0.tar.gz
cd cmake-3.9.0
apt-get install libcurl4-gnutls-dev
apt-get install zlib1g-dev
./bootstrap --system-curl
make && make install

大约须要10分钟时间。

完成后检查安装是否成功:

cmake --version

2.3安装与配置JDK环境

在官网%3A//www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载jdk安装包,这儿选择的是:

图片[2]-编译方法有几种:1.使用现成Dock编译镜像(一)-唐朝资源网

这网站很坑非得要登录就能下载

之后解压:

tar -zxvf  jdk-8u221-linux-x64.tar.gz

添加环境变量:

export JAVA_HOME=/workspace/opencv4android/tools/jdk/jdk1.8.0_221
export JRE_HOME=${JAVA_HOME}/jre 
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib 
export PATH=${JAVA_HOME}/bin:$PATH
source  ~/.bashrc

这儿配置的环境变量会在重启后失效,须要在步入docker时重新配置,可以参考第一节中的脚本。(我也不想把环境变量写死以防前面须要更新各类SDK版本)。

运行下边的命令检测JDK是否配置成功:

java -version

2.4安装与配置AndroidSDK

在这儿下载AndroidSDK的安装包,这儿选择的是android-sdk_r24.4.1-linux.tgz。

将压缩包放置到tools/sdk文件夹并解压:

tar -zvxf android-sdk_r24.4.1-linux.tar

配置环境变量:

export ANDROID_SDK=/workspace/opencv4android/tools/sdk/android-sdk-linux
export PATH=$ANDROID_SDK/tools:$PATH
source  ~/.bashrc

运行下边的命令检测AndroidSDK是否配置成功:

看安装选项的序列号:

android list sdk --all

按序列号安装须要的组件和sdk包:

这儿安装以下内容:

android update sdk -u --all --filter  24,54

之后运行下边的命令安装AndroidSDKPlatform-tools:

这条命令作用是安装所有包,而且这儿不须要那么多包,等见到它安装完AndroidSDKPlatform-tools后就可以ctrl-c中止了。

android update sdk --no-ui

2.5下载OpenCV源码和contrib库

运行下边的命令克隆opencv源码:

git clone https://github.com/opencv/opencv.git
cd opencv && git checkout 3.4

下载opencv的扩充库:

git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib && git checkout 3.4

注意一定要选择切换到合适的分支,否则编译肯定报错的。

这儿目前Github库房的3.4版本为3.4.8。

2.6开始编译

跟第一节中的方式一样,切换到build目录执行下边的命令即可编译:

python ../opencv/platforms/android/build_sdk.py 
--extra_modules_path=/workspace/_net/opencv_contrib/modules/ 
--config ../opencv/platforms/android/ndk-17.config.py

因为cmakeconfigure可能会失败,多试几次就好了。

所有的指令集都编译完成后opencv源码编译,生成的库就在OpenCV-Android-SDK目录下。

3.编译选项剖析

编译的配置文件就是前面命令指明的ndk-17.config.py,上面可以选择须要编译的指令集、STL库等等。

而调用ndk-17.config.py的是build_sdk.py脚本,在上面有ABI类的定义:

class ABI:
    def __init__(self, platform_id, name, toolchain, ndk_api_level = None, cmake_vars = dict()):
        self.platform_id = platform_id # platform code to add to apk version (for cmake)
        self.name = name # general name (official Android ABI identifier)
        self.toolchain = toolchain # toolchain identifier (for cmake)
        self.cmake_vars = dict(
            ANDROID_STL="gnustl_static",
            ANDROID_ABI=self.name,
            ANDROID_PLATFORM_ID=platform_id,
        )
        if toolchain is not None:
            self.cmake_vars['ANDROID_TOOLCHAIN_NAME'] = toolchain
        else:
            self.cmake_vars['ANDROID_TOOLCHAIN'] = 'clang'
            self.cmake_vars['ANDROID_STL'] = 'c++_static'
        if ndk_api_level:
            self.cmake_vars['ANDROID_NATIVE_API_LEVEL'] = ndk_api_level
        self.cmake_vars.update(cmake_vars)
        print ("---> "+self.cmake_vars['ANDROID_TOOLCHAIN'] +" " +self.cmake_vars['ANDROID_ABI']+" " +self.cmake_vars['ANDROID_STL'])
    def __str__(self):
        return "%s (%s)" % (self.name, self.toolchain)
    def haveIPP(self):
        return self.name == "x86" or self.name == "x86_64"

可以看见在ndk-17.config.py中传入的配置参数会在这儿被解析更新,例如假如要使用clang编译带NEON支持的armeabi-v7a库并链接c++_shared的话,就改成下边的参数:

ABIs = [
    ABI("2", "armeabi-v7a", None, cmake_vars=dict(ANDROID_ABI='armeabi-v7a with NEON',ANDROID_STL="c++_shared"))
]

就完成啦,得到的OpenCV-Android-SDK库可以在AndroidStudio中愉快地使用了,不管是Java还是C++插口都很便捷,甜滋滋~

© 版权声明
THE END
喜欢就支持一下吧
点赞180赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容