Quantcast
Channel: Sam的技术Blog
Viewing all articles
Browse latest Browse all 158

OpenCV编译总结

$
0
0
作者: Sam (甄峰)   sam_code@hotmail.com

自从2011年开始交叉编译OpenCV, 到今天陆陆续续编译了很多版本, 有尝试过编译Linux版本(http://blog.sina.com.cn/s/blog_602f87700102wuv7.html),交叉编译过ARM版本,在Android版本出现后,又编译过OpenCV4Android (http://blog.sina.com.cn/s/blog_602f87700102wwvb.html)  (http://blog.sina.com.cn/s/blog_602f87700102xdzq.html).


编译这么多次后,希望对自己的编译历程做个总结,所以借这次机会记录下来。


0. 交叉编译OpenCV的原因
0.1:OpenCV2.0时代:
最初交叉编译OpenCV,是想在Android系统上使用它,而在OpenCV2.0时代,并不提供Android版本。所以下载了OpenCV2.0 Source For Linux. 对各个模块自己写Android.mk, Application.mk. 顺利的编译出对应版本。
cvaux,cv, cxcore, ml, highgui等全部成功编译。且highgui底层支持V4L2, libv4l, ffmpeg等
(http://blog.sina.com.cn/s/blog_602f87700101de4o.html)

0.2: OpenCV3.1时代
OpenCV3.1时代,已经开始提供OpenCV4Android,理论上,根本不需要再自行编译.
OpenCV的官方建议是: 直接使用OpenCV库。libopencv_java.so.
并提供了两套使用方法:
A. 利用OpenCV提供的全套Java接口, 在Android Java层使用。
B. 利用OpenCV提供的C/C++ 接口, 在JNI层使用。

但Sam当时需要比较特殊: 与官方提供过使用方法不同的是:需要在Android NativeC控制台层面使用OpenCV。这本身没有问题,但会遇到Camera问题(注1)。

换句话说,就是要在Android NativeC 层, 把V4L2支持也打开。这就是每升级一次OpenCV, Sam都需要重新编译的核心原因。

0.3: OpenCV3.4时代
从OpenCV3.3. 它加入了DNN,需要用它,还想把OpenCL加入。又需要用到Camera,所以.....


1. OpenCV编译思路:
既然知道了特殊的OpenCV使用要求(在NativeC控制台程序中使用OpenCV, 同时提供Camera接口)。 那编译思路就很清晰了。
1.1:打开所有想要支持的模块和功能:
如:TBB, Eigen, OpenCL.

1.2:  打开V4L2支持。
此处要注意,使用官方方法打开V4L2支持,并不一定可以起效。因为在设置文件中,这个设置会被去掉。

1.3:堵住Native-JNI所用的Camera接口:
这个接口是给JNI-NativeC用的,与OpenCV-Manager关联。不是Sam所能使用的。所以需要把这条路堵住。



2. 编译方法研究总结
回顾:
OpenCV2.0时代,当时编译工具还采用autoconf. 所以直接自己写Android.mk , Application.mk。
OpenCV2.4.20时代,编译工具切换到cmake. 所以编译方法有所变化。直到OpenCV3.4, (OpenCV4.0还没看)。 一直可以延续这种编译方法。(中间也许添加了Python编译方法,后续再研究)。

首先看这种编译方法:
2.1: 几个关键文件
A. CMakeLists.txt
在OpenCV Source Tree根目录。有CMakeLists.txt. 它是OpenCV CMake 的根 Makefile。
B: platforms/scripts 目录
V2.4.20,  V3.1.0  V3.3.0中,platforms/scripts目录中,有很多 sh 脚本。
这些脚本用来帮助开发人员编译不同平台,不同架构的OpenCV.
cmake_android_arm.sh  :  Android ARM平台版本。
cmake_android_mips.sh: Android MIPS平台版本
cmake_android_x86.sh:  X86版本。
cmake_arm_gnueabi_hardfp.sh:  ARM hardfp版本。

其中,我们用到的就是cmake_android_arm.sh

这些脚本,其实是帮助开发人员编译的。
它的主要思想是:
#cd platforms
#sh scripts/cmake_android_arm.sh

它就会在platforms下建立一个类似 build_android_arm的目录。并生成(新产生,而非copy)将要编译的源码和头文件以及Makefile。等待用户编译。


其中,不同平台,不同架构的的编译设置, -DCMAKE_TOOLCHAIN_FILE=../android/android.toolchain.cmake:放在platforms/中不同目录内。
如:android,  ios,  linux, osx等。
android-ARM的编译配置文件:就在android/android.toolchain.cmake 中 .

C: platforms/android
这个目录放置的是android-arm版本的编译设置选项。
其中,V3.4.1版本,在platforms/scripts中,已经没有cmake_android_arm.sh 了。
但在platforms/android/ 增加了build_sdk.py , ndk-xx.config.py等。 估计是为python编译准备的。
不过,既然platforms/android/android.toolchain.cmake  还在,那老版本应该还行的通。

 
3. 编译前的准备工作
不同OpenCV版本的编译中,要求各个软件和库的版本也在不断升级中。所以就不提具体版本了。只说需要什么软件吧。 
git 
cmake
Android NDK
JDK
Android SDK
Apache Ant
Python.

环境变量设置:

export ANDROID_NDK=/opt/android-ndk-r14b/
export ANDROID_SDK=/home/sam/Android/android-sdk-linux/
#export ANDROID_SDK=/home/sam/Android/Sdk/
export ANDROID_ABI=armeabi-v7a

export ANT_HOME=/usr/share/ant
export PATH=${PATH}:${ANT_HOME}/bin

Sam 把他们写到一个脚本中:
SET_ENV_32BIT

#source  SET_ENV_32BIT 

4.  实际编译:
4.1:设置环境变量:
#source  SET_ENV_32BIT 

4.2:
哪怕是V3.4.1, Sam也建议自己建立scripts/cmake_android_arm.sh. 这样在后续修改设置,如加入TBB,OpenCL等时,就直接添加在cmake_android_arm.sh 中了。


#cd platforms
#sh scripts/cmake_android_arm.sh

#cd build_android_arm
#make VERBOSE=1



5.  修改OpenCV设置
5.1: Eigen支持添加:
A. 添加设置:  
在scripts/cmake_android_arm.sh 中,添加:
-DHAVE_EIGEN=1
但此时可以看到:
--   Other third-party libraries:
--     Eigen:                       YES (ver ..)
说明没找到Eigen的库和头文件。
查看CMakeLists.txt, 可以看到以下语句:
if(WITH_EIGEN OR HAVE_EIGEN)
  status("    Eigen:"      HAVE_EIGEN       THEN "YES (ver ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})" ELSE NO)
endif()
说明没有获取到以上信息。

查看CMakeList.txt:
OCV_OPTION(WITH_EIGEN          "Include Eigen2/Eigen3 support"               (NOT CV_DISABLE_OPTIMIZATION)       IF (NOT WINRT AND NOT CMAKE_CROSSCOMPILING) )
可以看到,如果是交叉编译,则WITH_EIGEN不被设置。

所以如果需要加入EIGEN支持,首先要交叉编译EIGEN, 再去掉这个语句。这个后面再尝试。







5.2: 添加TBB支持:
添加设置:
-DWITH_TBB=1
它会自动下载TBB。



5.3: 增加动态库
-DBUILD_SHARED_LIBS=ON



5.4:增加V4L2支持:























注1:
OpenCV中本机Camera支持:
Android Camera的原生接口与平台相关。 OpenCV将依赖于平台的代码隔离到单独的库中,并提供了几个预构建的库。如: libnative_camera_r2.2.0.so  libnative_camera_r4.0.3.so  libnative_camera_r4.1.1.so等。

OpenCV的本机Camera在控制台应用程序中不起作用



注2:
WITH_EIGEN, HAVE_EIGNE, WITH_TBB, HAVE_TBB关系。



 

Viewing all articles
Browse latest Browse all 158

Trending Articles