交叉编译OpenCV的Android版本
交叉编译OpenCV的Android版本
OpenCV作为一个强大的图像处理库,在Android上也有强大的应用。
OpenCV官网提供了SDK的下载,可以直接下载使用
OpenCV官网地址:https://opencv.org/
不过有时候也会有自定义编译的需求
下面来记录一下最近在交叉编译OpenCV所作的笔记
避免以后走弯路。
编译Host系统是Ubuntu 16.04
准备工作
下载opencv:
git clone git@github.com:opencv/opencv.git
git checkout 3.4
下载opencv依赖的库
git clone git@github.com:opencv/opencv_contrib.git
git checkout 3.4
这里我们使用的版本都是3.4。
配置环境:
1. 安装ant
编译Java代码需要用到ant或者gradle
但是我还没搞清楚怎么配置使用gradle编译
而且我这次是在服务器上工作,没有x11环境
没装Android Studio,所以,姑且使用ant编译Java。
修改opencv/CMakeLists.txt文件
激活ant编译
set(ANDROID_PROJECTS_SUPPORT_ANT ON)
sudo apt-get install ant
2. 安装ndk
安装ndk需要翻wall,请自备梯子
这里写了一个python程序,用于枚举NDK的版本,
然后手动输入选择下载对应的版本,
这里我下载的r17c版本NDK,下载完成之后配置NDK_ROOT环境变量
#!/usr/bin/env python import urllib2
import collections
import json
import os def init():
"""
Return name/link dict @return: name-to-link dict
"""
with open('table.json') as data_file:
url_table = json.load(data_file) if url_table is None or len(url_table) <= 0:
print('\033[91m' + ' There is no item in table.json ' + '\033[0m')
os.sys.exit(0) # Sort alphabetically
url_table = collections.OrderedDict(sorted(url_table.items()))
index = 0
for key in url_table:
index = index + 1
print str(index) + '] ' + key return url_table def getTargetLink(desired_index, url_table):
"""
Return download link @type desired_index: number
@param desired_index: Desired index
@type url_table: dict
@param url_table: name-to-link @return: Download link
"""
index = 0
for key in url_table:
index = index + 1
if desired_index == index:
return url_table[key]
return None def download(url):
if url == None:
return file_name = url.split('/')[-1]
u = urllib2.urlopen(url)
f = open(file_name, 'wb')
meta = u.info()
file_size = int(meta.getheaders("Content-Length")[0])
print "Downloading: %s Bytes: %s" % (file_name, file_size) file_size_dl = 0
block_sz = 8192
while True:
buffer = u.read(block_sz)
if not buffer:
break file_size_dl += len(buffer)
f.write(buffer)
status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
status = status + chr(8)*(len(status)+1)
print status, f.close() if __name__ == '__main__':
url_table = init()
var = raw_input("Please enter the numer you want to download: ")
link = getTargetLink(int(var), url_table)
download(link)
3. 安装SDK
由于我们需要编译的android版本,需要用到SDK的build tools和sdk的platform版本库
这里使用SDK的build tools版本是24.0.3
往上的版本,Google去掉了aidl,会导致没法编译Java端的代码,也无法生成libopencv_java3.so
所以在下载的SDK版本中,build tools只能保留不高于24.0.3的版本
platform版本库使用android-21
下载SDK的方法:
找一台装有Android Studio的电脑,使用SDK Manager下载对应的版本即可
然后将SDK拷贝至交叉编译的电脑上,配置SDK环境变量
export NDK_ROOT=/path/to/android-ndk-r17c
export ANDROID_HOME=path/to/sdk
4. 配置SDK tools版本
在我们的SDK中,有个tools目录
具体的版本,是Android Studio在SDK Manager中配置的
但是OpenCV只能支持到tools_r25.2.5-linux.zip
所以需要手动下载tools_r25.2.5-linux.zip,解压替换SDK目录的tools
下载地址:https://dl.google.com/android/repository/tools_r25.2.5-linux.zip
5. 安装CMake和其它编译环境
sudo apt-get install cmake
sudo apt-get install build-essential make
开始交叉编译
由于OpenCV需要使用cmake编译
需要配置很多参数,所以使用bash脚本是最方便的方式
编译脚本放在opencv和opencv_contrib的同级目录
#!/bin/bash
NDK_ROOT="${1:-${NDK_ROOT}}" ### ABIs setup
#declare -a ANDROID_ABI_LIST=("armeabi-v7a with NEON")
declare -a ANDROID_ABI_LIST=("armeabi-v7a") ### path setup
SCRIPT=$(readlink -f $)
WD=`dirname $SCRIPT`
OPENCV_ROOT="${WD}/opencv"
N_JOBS=${N_JOBS:-} INSTALL_DIR="${WD}/opencv-build"
rm -rf "${INSTALL_DIR}/opencv" ### Make each ABI target iteratly and sequentially
for i in "${ANDROID_ABI_LIST[@]}"
do
ANDROID_ABI="${i}"
echo "Start building ${ANDROID_ABI} version" if [ "${ANDROID_ABI}" = "armeabi" ]; then
API_LEVEL=
else
API_LEVEL=
fi temp_build_dir="${OPENCV_ROOT}/platforms/build_android_${ANDROID_ABI}"
### Remove the build folder first, and create it
#-DANDROID_TOOLCHAIN_NAME=clang
#-DANDROID_TOOLCHAIN_NAME="arm-linux-androideabi-5" \
#-DANDROID_STL=gnustl_static \
rm -rf "${temp_build_dir}"
mkdir -p "${temp_build_dir}"
cd "${temp_build_dir}" cmake -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON \
-DCMAKE_TOOLCHAIN_FILE="${OPENCV_ROOT}/platforms/android/android.toolchain.cmake" \
-DANDROID_NDK="${NDK_ROOT}" \
-DANDROID_NATIVE_API_LEVEL=${API_LEVEL} \
-DANDROID_ABI="${ANDROID_ABI}" \
-DANDROID_CPP_FEATURES="rtti exceptions" \
-DANDROID_ARM_NEON=TRUE \
-DANDROID_STL=gnustl_static \
-DCMAKE_BUILD_TYPE=Release \
-D BUILD_opencv_java=ON \
-D BUILD_ANDROID_PROJECTS=ON \
-D WITH_CUDA=OFF \
-D WITH_MATLAB=OFF \
-D BUILD_ANDROID_EXAMPLES=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-DOPENCV_EXTRA_MODULES_PATH="${WD}/opencv_contrib/modules/" \
-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}/opencv" \
../..
# Build it
make -j${N_JOBS}
# Install it
make install/strip
### Remove temp build folder
cd "${WD}"
rm -rf "${temp_build_dir}"
echo "${temp_build_dir}"
echo "end building ${ANDROID_ABI} version"
done
这里只启用了armeabi-v7a编译目标
其它平台可根据需求添加
目前无法使用ANDROID_TOOLCHAIN_NAME来指定clang编译器
因为OpenCV的makefile在解析clang交叉编译工具链使用的代码没做匹配
而我也暂时没精力自己修改做匹配
有兴趣的同学,可以修改
${OPENCV_ROOT}/platforms/android/android.toolchain.cmake
来匹配clang编译器
STL链接使用的是gnu版本的
因为OpenCV用到了C++11
如果使用c++_static版本,因为Google没做后续支持维护
gcc在这个工具链上不支持很多C++和C++11特性
会导致编译失败,我尝试过使用CrystaX NDK
但是在configure阶段就失败了
只能无疾而终
其它编译选项顾名思义,不做过多解析。
备注:
如果需要使用C++14特性编译
需要修改opencv/CMakeList.txt文件
手动添加,pathch如下所示
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -, +, @@ endif()
OCV_OPTION(ENABLE_CXX11 "Enable C++11 compilation mode" "${OPENCV_CXX11}")
include(cmake/OpenCVDetectCXXCompiler.cmake)
ocv_cmake_hook(POST_DETECT_COMPILER)
-
+set(CMAKE_CXX_STANDARD )
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_VERBOSE_MAKEFILE ON)
+set(ANDROID_PROJECTS_SUPPORT_ANT ON)
# Add these standard paths to the search paths for FIND_LIBRARY
# to find libraries from these locations first
if(UNIX AND NOT ANDROID)
交叉编译OpenCV的Android版本的更多相关文章
- 在fedora25x86下编译opencv的Android版本的过程记录
准备材料: 1. 32位的Fedora25(不建议使用64位系统----64位系统下也是可以编译的,这里为了简单起见,考虑使用32位操作系统.事实上,本人在64位操作系统下也做了尝试,也完成了编译.) ...
- OpenCV在Android平台上的应用
今年8月份, OpenCV 2.3.1发布了. 虽然从2.2开始, OpenCV就号称支持Android平台, 但真正能让OpenCV在Android上运行起来还是在2.3.1版本上. 在这个版本上, ...
- NDk编译opencv for Android,并引用在Unity3d游戏中的一般步骤
本文使用:Unity3d + opencv + Android Unity3d中可以调用opencv 编译好的.so 动态库,在生成Android apk时可以正常运行. 因为Android系统是 ...
- 编译并使用带有OpenCL模块的OpenCV for android SDK
OpenCV Android SDK中提供的静态.动态库是不支持OpenCL加速的,如果在程序中调用OpenCL相关函数,编译时不会报错,但运行时logcat会输出如下信息,提示OpenCL函数不可用 ...
- android版本vqmon移植IOS版
IOS交叉编译 1.android版本 vqmon已经正常运行,现需要开放IOS版本,作移植工作. 2. 注意事项: 1)ROOT权限,IOS必须越狱. 2)依赖库:pcap, ffmpeg,lib ...
- OpenCV On Android环境配置最新&最全指南(Android Studio篇)
本文是从本人简书上搬运而来,属本人原创,如有转载,请注明出处:http://www.jianshu.com/p/6e16c0429044 简介 本文是<OpenCV On Android环境配置 ...
- OpenCV On Android环境配置最新&最全指南(Eclipse篇)
简介 本教程是经过本人多次踩坑,并参考网上众多OpenCV On Android的配置教程总结而来,尽希望能帮助学习移动图像处理的朋友们少走弯路.这也是本人第一次在简书上发布文章,如有不足,希望各位d ...
- Delphi XE5 支持的Android 版本
Delphi XE5 已经支持Android应用开发. 那XE5支持Android的哪些版本呢?Delphi编译的APP能部署到Gingerbread (2.3.3-2.3.7), Ice Crea ...
- 获取Android版本信息和电话信息
Android的版本信息可以通过android.os.Build获得,电话信息可以通过TelephonyManager获得,代码如下: private void get_infor(){ sd ...
随机推荐
- MQ选型对比RabbitMQ RocketMQ ActiveMQ Kafka
几种MQ产品说明: ZeroMQ : 扩展性好,开发比较灵活,采用C语言实现,实际上他只是一个socket库的重新封装,如果我们做为消息队列使用,需要开发大量的代码 RabbitMQ :结合erla ...
- thinkphp3.2验证码在服务器上显示不出来
ThinPHP3.2 验证码 在本地服务器访问可以显示,上传到服务器就不能访问了 /**** * 验证码 */ function code() { $config=array( 'fontSize'= ...
- Oracle 9i & 10g编程艺术-深入数据库体系结构-学习笔记(持续更新中)
--20170322 --1.0 --更新表的统计信息begin dbms_stats.set_table_stats(user,'EMP',numrows => 10000);end; beg ...
- codeforce——因数筛
题目大意:给你一个 n 和 k 求 n 的第 k 个因数. #include<iostream> #include <algorithm> #include <queue ...
- C++ lower_bound 和upper_bound
二分查找的函数有 3 个: 1.lower_bound(起始地址,结束地址,要查找的数值) 返回的是数值 第一个 出现的位置. 2.upper_bound(起始地址,结束地址,要查找的数值) 返回的是 ...
- IOS-快速集成检查更新
一直以为Appstore有了检查版本是否更新的机制,我们在APP上做这个更新功能会被拒,但是也有看到一些APP也是做了这个更新功能的.因为在网上没有找到完全正确的方法能获取到iTunes里的数据的,于 ...
- bzoj1077
题解 这道题n的范围很小,所以我们可以考虑枚举+判定 设放在天平右边的是C,D. 以A+B<C+D为例,因为差分约束必须是差的形式,所以我们将式子变形 B−C<D−A然后枚举D,A的取值, ...
- 二叉树题目集合 python
二叉树是被考察频率非常高的数据结构.二叉树是按照“父节点-左子树&右子树”这样的方式,由根节点不断向下扩展,形成一棵树的结构.二叉树经常被提到的三种遍历方式:前序遍历.中序遍历和后序遍历,既是 ...
- [转] .net软件反编译笔记
原文地址:http://blog.csdn.net/three_bird/article/details/51433734 在软件的破解及源码获取及重新编译的道路上会遇到一些问题,书此备查. 大名鼎鼎 ...
- 第10课 struct和union分析
struct的小秘密:空结构体占多大内存呢? 直观的答案有两种: 1.空结构体的大小为0 2.结构体本来就是为了将不同的变量集合在一起使用的,定义空结构体会导致编译错误 实例分析: #include ...