OpenCV ARM移植(交叉编译opencv)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yueguanyun/article/details/51272989

部分内容来自下面2编文章
http://www.cnblogs.com/emouse/archive/2013/04/01/2993842.html

http://blog.csdn.net/satanhbl/article/details/25734887

arm-oe-linux-gnueabi-gcc编译opencv3.1.0

Cmake的安装

OpenCV 2.2以后版本需要使用Cmake生成makefile文件,因此需要先安装cmake。

ubuntu下安装cmake比较简单,

apt-get install cmake

如果觉得自带的版本不符合要求,可以下载安装包。

下载最新版的安装包:

http://www.cmake.org/cmake/resources/software.html

这里下载已经编译好的,这样只需要解压至需要的目录下即可使用:

tar zxvf cmake-2.8.10.2-Linux-i386.tar.gz –C /usr/local/

设置环境变量:

sudo gedit /home/emouse/.bashrc

在打开的文件后添加:

export PATH=$PATH:/usr/local/cmake-2.8.10.2-Linux-i386/bin

查看版本,测试是否安装成功:

root@emouse:/home# cmake --version 

OpenCV 的交叉编译

解压OpenCV压缩文件,得到文件夹。

#cmake-gui 打开cmake的gui界面,开始进行配置,配置过程如下图所示:

首先电脑得先安装arm-linux的交叉编译环境,这里就不介绍这个了,直接说重点。

方法一(编译通过):

1、在终端窗口输入sudo apt-get install cmake-qt-gui下载cmake图形界面

2、安装好后在终端窗口输入cmake-gui打开cmake的gui界面


3.在“where is the source code”中填入电脑中opencv源码的位置,“where to build the binaries”填入生成make编译文件的位置,然后点击configure按钮,选择最后一项


4.点击NEXT再跳出的界面中做如下设置

Operating System 选择目标系统arm-linux

Compilers中选择交叉编译器的gcc和g++

这里注意选择用什么编译,根据不同的编译选择编译命令的路径。

我是使用的arm-oe-linux-gnueabi来编译,找到编译器的安装路径:/usr/local/oecore-i586/sysroots/i586-oesdk-linux/usr/bin/cortexa9hf-vfp-neon-oe-linux-gnueabi/

gcc:/usr/local/oecore-i586/sysroots/i586-oesdk-linux/usr/bin/cortexa9hf-vfp-neon-oe-linux-gnueabi/arm-oe-linux-gnueabi-gcc

g++:/usr/local/oecore-i586/sysroots/i586-oesdk-linux/usr/bin/cortexa9hf-vfp-neon-oe-linux-gnueabi/arm-oe-linux-gnueabi-g++

Target Root选择交叉编译器的路径


5.点击Finish按钮,开始生成配置文件,但是这个时候会报错。


6.此时主界面如下图所示,这时Cmake会读取程序的一些配置信息,可以再下图红框中对每一个编译选项进行修改,这里去掉WITH_TIFF,修改CMAKE_FIND_ROOT_PATH安装路径::/usr/local/oecore-i586/sysroots/i586-oesdk-linux/usr/bin/cortexa9hf-vfp-neon-oe-linux-gnueabi/。

System is unknown to cmake, create:

Platform/arm-linux to use this system, please send your config file to [email protected] so it can be added to cmake

这个是因为Operating System填写的arm-linux不算Cmake能识别的目标系统,这里可以忽略这个错误。

但是这个时候还有其他错误,

CMake Error at cmake/FindCUDA.cmake:763 (if):

if given arguments:


"CUDA_VERSION" "VERSION_GREATER" "5.0" "AND" "CMAKE_CROSSCOMPILING" "AND" "MATCHES" "arm"


Unknown arguments specified

Call Stack (most recent call first):

cmake/OpenCVDetectCUDA.cmake:26 (find_package)

cmake/OpenCVFindLibsPerf.cmake:24 (include)

CMakeLists.txt:468 (include)


应该是我的电脑里没有安装CUDA的库,因为后面的开发中也不会用到CUDA,所以我将 WITH_CUDA的钩去掉,然后再点击一次Configure按钮,看看还有没有提示缺少哪些第三方库,网上其他文章说WITH_TIFF要去掉,但是这里没有报错就不管它了。


7.同时可以将CMAKE_INSTALL_PREFIX改成你想要的路径,这个路径所opencv最后库文件和头文件的安装路径。在不存在其他问题后点击Generate生存Makefile文件,如果前面第三方的问题没有解决这里是会报错而无法生存Makefile。生成的Makefile文件和Cmake配置文件都在 Wher to build the binarier 中设置的文件夹下



8.

在终端窗口中进入 Wher to build the binarier 中设置的文件夹下执行make指令,make失败提示如下


../../lib/libopencv_core.so: undefined reference to `pthread_spin_init'
../../lib/libopencv_core.so: undefined reference to `pthread_spin_unlock'
../../lib/libopencv_core.so: undefined reference to `pthread_spin_lock'
../../lib/libopencv_core.so: undefined reference to `pthread_spin_destroy'
../../lib/libopencv_core.so: undefined reference to `pthread_once'
../../lib/libopencv_core.so: undefined reference to `clock_gettime'
../../lib/libopencv_core.so: undefined reference to `pthread_spin_trylock'

//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=-lpthread -lrt

lrt这个不知道是什么,只是网上其他文章说要加上我就也加上了,然后再继续编译,编译完成后执行指令make install安装库文件和头文件到CMAKE_INSTALL_PREFIX指定的文件夹下。虽然网上有很多文章写的都是用这个方法,都是这个方法是有问题的,前面所提到的configure时提示的System is unknown to cmake,这个错误是直接被我忽略的,都是其实这个是很有问题的,因为CMake编译过程中我们没有告诉编译器我们要用的是是哪个系统,那有些功能它就不知道是选择编译和window兼容的代码,还是和linux兼容的代码,比如我在后面用这个编译好的opencv库写的程序放到210的板子上运行时,软件自带的函数cvCreatCamerCapture没办法识别板子上的usb摄像头,在谷歌查了很久才发现是编译的时候没有支持V4L2,后来发现是目标系统选择的问题,下面的另一种方法将解决这个问题。

方法二 (编译不通过):

前面再configure时提示的System is unknown to cmake是被我忽略不管的下面介绍下不忽略这个错误的编译过程。

出现这个错误的原因是Cmake不能识别arm-linux这种系统,所以我们把他改成Linux,注意第一个字母大写,不能写错linux,否则还会出现那个错误


另外需要注意的是include Mode要选择成Search only in Target Root这样在后面opencv编译时搜索头文件就只会在Target Root指定的文件夹下搜索,而不会到你电脑的usr/include/下搜索,如果这里还是先前的search in Target Root, then native system则会到/usr/include/下搜索头文件,就会出现一些问题,在

10.我的电脑中出现了下面的问题


/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'

/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'

/usr/include/bits/mathinline.h:675:3: error: unknown register name 'st' in 'asm'

mathinline.h在/usr/include/bits/和/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/usr/include/bits/目录下都有,这个时候优先选择了/usr/include下的mathinline.h,于是编译就出错了,那之前在Operating System为arm-linux时为什么没有这个错误呢?笔者认为可能是在arm-linux时会默认先搜索电脑中配置的arm-linux的路径也就是/opt/FriendlyARM/toolschain/4.5.1/下的include文件夹,而如果设置成Linux则优先搜索/usr/include。因此要将include Mode选择成Search only in Target Root,这样编译的时候就只会在/opt/FriendlyARM/toolschain/4.5.1/文件夹下搜索头文件了。

11.接着后面和前面一样所去掉CUDA第三方库,更改CMAKE_INSTALL_PREFIX,更改后记得再点击一次configure然后再点击Generate,进入文件夹修改CmakeCache.txt,make,这个时候又报错了:

undefined reference to `dlopen' 

没有找到dl库,继续修改CmakeCache.txt

CMAKE_EXE_LINKER_FLAGS:STRING=-lpthread -lrt -ldl

编译好后make install,这个时候其实大家会发现这个方法编译出来的链接库比第一种方法编译出来的链接库要多一些,在目前的嵌入式开发阶段中使用这个链接库还没有发现什么。其实我才移植了一个软件而已,哈哈!

参考文档:

http://www.cnblogs.com/emouse/archive/2013/04/01/2993842.html

http://blog.csdn.net/noodies/article/details/5798434

http://www.bubuko.com/infodetail-534692.html

http://blog.csdn.net/zdyueguanyun/article/details/51262136

http://blog.csdn.net/zdyueguanyun/article/details/51273547






猜你喜欢

转载自blog.csdn.net/yueguanyun/article/details/51272989