宿主系统:ubuntu9.04 交叉编译器版本:arm-linux-gcc-4.3.2
目标系统:linux kernel 2.6.3.2 硬件ARM-Cotex(AM3517)开发板
2012-11-2 重新编译时 : 目标系统 ubuntu_core linux version 3.0.0-1205-omap4 硬件:OMAP4460
我试过用arm-linux-gcc-4.3.3交叉编译opencv2.0结果总是出错,出错的内容见另一篇博文http://blog.csdn.net/dlutxie/article/details/6769200
由于opencv2.0依懒于png,jpeg图形库,而png又依懒于zlib库,所以应先安装交叉编译器,然后安装zlib,png,jpeg库,具体安装过程见上面的链接。
安装过程如下:
xgy@ubuntu:~/tmp$ tar xvf OpenCV-2.0.0.tar.bz2
xgy@ubuntu:~/tmp$ cd OpenCV-2.0.0/
xgy@ubuntu:~/tmp/OpenCV-2.0.0$ ./configure--host=arm-linux --without-gtk --without-carbon --without-quicktime --without-1394libs --without-ffmpeg --without-python --without-swig--enable-shared --disable-apps CXX=arm-linux-g++ CPPFLAGS=-I/home/xgy/toolchain/arm/4.3.2/arm-none-linux-gnueabi/includeLDFLAGS=-L/home/xgy/toolchain/arm/4.3.2/arm-none-linux-gnueabi/libc/lib--prefix=/opt/arm/opencv --libdir=/opt/arm/opencv/lib --includedir=/opt/arm/opencv/include
产生的报告如下:
xgy@ubuntu:~/tmp/OpenCV-2.0.0$ make
xgy@ubuntu:~/tmp/OpenCV-2.0.0$ make install 执行后出现如下错误:
因为我这里要把opencv安装到/opt/arm/opencv下,而xgy用户对这个目录没有写板限,所以无法安装,于是我改用root用户执行make install结果出现同样的错误,这是因为root用户的PATH环境变量没有指向交叉编译器(我安装完交叉编译器后只设置了xgy用户的PATH环境变量),为此我将opt这个及其子目录设为任何用户均可写,命令如下:
root@ubuntu:/# chmod -R 777 /opt
然后切换到刚才的目录执行make install 如下:
root@ubuntu:/# su - xgy
xgy@ubuntu:~$ cd tmp/OpenCV-2.0.0/
xgy@ubuntu:~/tmp/OpenCV-2.0.0$ make install //这样就可以安装成功了
下面来设置环境变量,先更改一个文件名
xgy@ubuntu:~/tmp/OpenCV-2.0.0$ cd /opt/arm/opencv/lib/pkgconfig/
xgy@ubuntu:/opt/arm/opencv/lib/pkgconfig$ mv opencv.pc opencvarm.cp
因为在我的系统里已经安装了一个X86下的opencv库,在相似的目录下有一个opencv.pc文件,如果这里不改,这两个文件同名将有可能出错!(与PKG_CONFIG_PATH中设置的路径相关)
xgy@ubuntu:/opt/arm/opencv/lib/pkgconfig$ cd
xgy@ubuntu:~$ vi .bashrc
在最后加上export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/arm/opencv/lib/pkgconfig
切换到root用户,在/etc/ld.so.conf文件的最后加入:/opt/arm/opencv/lib或者在/etc/ld.so.conf.d/下创建一个文件opencv.conf,文件的内容为:/opt/arm/opencv/lib
然后记得执行下:ldconfig 命令以加载动态库文件
到目前为止,我们可以在宿主机上交叉编译有关opencv例程的程序了,但我们还没有把刚才编译好的opencv库移植到ARM-cotex开发板上去,接下来我们就做这份工作:
将/opt/arm/opencv/lib里的
libcvaux.so.4.0.0
libcv.so.4.0.0
libcxcore.so.4.0.0
libhighgui.so.4.0.0
libml.so.4.0.0
拷出来全部重命名
*.so.4
然后将在五个文件,还有前面交叉编译的zlib,libpgn,jpeg相关动态链接库一起通过tftp(或者其它方式)拷到ARM-cotex开发板上,然后设置LD_LIBRARY_PATH环境变量,使其指向包含这些库的目录,例如:我把这些库拷到了/mnt/sda/opencvlib日录下,那么设置:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/mnt/sda/opnecvlib,其实也可以在/etc/ld.so.conf文件的最后加入:/mnt/sda/opencvlib的,只是我发现在开发板上没有/etc/ld.so.conf这个文件,所以只好设置LD_LIBRARY_PATH这个环境变量了
到此opencv2.0移植成功!!好好庆祝下吧!!
2012-11-2
这几天又重新移植了一遍Opencv2.0这次是把它移植到OMAP4460上,这次尝试用了4.5.1版本arm-linux-gcc编译移植的时候没有问题,但在跑自己的程序的时候却出错了,出错内容如下:
OpenCV Error: Null pointer (NULL array pointer is passed) in cvGetMat, file cxcore/cxarray.cpp, line 2370
terminate called after throwing an instance of 'cv::Exception'
Aborted
网上有人说,应该把jpg的图片换成png格式的,我试过了,没有用,经过跟踪出错路径为:cvLoadImage() ->imread_()->ImageDecode::readHeader() (我只跟踪到此函数) 而函数readHeader()是一个虚函数,对于不同的图片格式有不同的实现,由于我以前用完全一样的代码编译测试过且正确,所以代码应该是没有问题的,至少以前能跑起来,现在应该也是能跑起来的,所以我还是认为我用arm-linux-gcc-4.5.1的这个版本不对,于是又重新换成4.3.2的编译,configure的配置如下:
./configure --host=arm-cortex-linux --disable-openmp --without-gtk --without-swig --without-python --without-carbon --without-ffmpeg --without-1394libs --without-quicktime --enable-shared CXX=arm-none-linux-gnueabi-g++ CC=arm-none-linux-gnueabi-gcc CXXFLAGS=" -march=armv7-a -mtune=cortex-a9 -mfpu=vfp -mfloat-abi=softfp " CCFLAGS="-march=armv7-a -mtune=cortex-a9 -mfpu=vfp -mfloat-abi=softfp" CPPFLAGS=-I/opt/toolschain/arm/4.3.2/arm-none-linux-gnueabi/include LDFLAGS=-L/opt/toolschain/arm/4.3.2/arm-none-linux-gnueabi/lib/ --prefix=/opt/arm/opencv2.0 --libdir=/opt/arm/opencv2.0/lib --includedir=/opt/arm/opencv2.0/include
配置结果如下图:
本想用:--enable-openmp,这个选项似乎是开启并行计算的,但由于编译器不支持(可以通过arm-linux-gcc -v命令查看)如果要用的话,得自己下载个包编译个库给加进去。
另外,我把那个-mfpu=vfp 换成-mfpu=neon速度几乎没有变,难道是OMAP4460不支持neon?
这次用了A9的板(OMAP4460)还用了fpu比以前用的A8的板(AM3517)、没有用fpu (可以通过反汇编objdump程序查看汇编代码看有没有浮点指令),同样的程序,速度还是快了将近四倍(以前最快3.83秒,现在最快0.99秒),不过比我预想的还是慢了一倍,因为同样的程序在我电脑的VM虚拟机里跑时间为0.27秒,我发现初始化时,用的是omap3的配置,不知道是不是板子的频率还没有配置上来,另外jpg,png,还有zlib这几个库我都没有用fpu的选项进行重编译,而是直接用了原来编译的库,所以比预想的慢了点,有空再重新弄下。
所用的ubuntu_core下载及烧进开发板的步骤:http://omappedia.org/wiki/OMAP_Ubuntu_Core
之后就是编译Opencv2.0 编译选项如下:
./configure --host=arm-linux-gnueabi --disable-openmp --without-gtk --without-swig --without-python --without-carbon --without-ffmpeg --without-1394libs --without-quicktime --enable-shared CXX=arm-linux-gnueabihf-g++ CC=arm-linux-gnueabihf-gcc CPPFLAGS=-I/home/xgy/arm-gcc4.7/arm-linux-gnueabihf/include LDFLAGS=-L/home/xgy/arm-gcc4.7/arm-linux-gnueabihf/lib/ --prefix=/opt/arm/opencv2.0-gcc4.7 --libdir=/opt/arm/opencv2.0-gcc4.7/lib --includedir=/opt/arm/opencv2.0-gcc4.7/include
这次去掉了CXXFLAGS的选项,因为通过arm-linux-gnueabihf-g++-v 可以看到如下的选项:
--with-arch=armv7-a --with-tune=cortex-a9 --with-fpu=vfpv3-d16 --with-float=hard 也就是说这个gcc默认编译出来的程序就是在cortex-a9上跑的,当初我加上那个CXXFLAGS反而在配置的时候就出错了。
之后就是make ; make install 当然这中间也遇到一些问题。具体如下:
../include/opencv/cxcore.hpp:169:13: error: 'ptrdiff_t' does not name a type
../include/opencv/cxoperations.hpp:1916:15: error: 'ptrdiff_t' does not name a type
../include/opencv/cxoperations.hpp:2465:31: error: 'ptrdiff_t' does not name a type
../include/opencv/cxmat.hpp:356:15: error: expected ';' before 'delta1'
../include/opencv/cxmat.hpp:358:9: error: 'delta1' was not declared in this scope
../include/opencv/cxmat.hpp:367:31: error: 'delta2' was not declared in this scope
上面这个问题只需要在OpenCV2.0.0/include/opencv/cxcore.hpp文件中加入: #include <stddef.h>即可!!
highgui/loadsave.cpp:333:28: error: ‘unlink’ was not declared in this scope
这个问题也是在哪个文件中加入: #include<unistd.h> 即可,具体是哪个文件想不起来了。
undefined reference to `cvCreateCameraCapture_V4L(int)'
这个问题可以参考:https://code.ros.org/trac/opencv/changeset/5206,解决如下:
修改OpenCV2.0.0/cvconfig.h.cmake文件如下:
19 19 /* V4L2 capturing support */
20 20 #cmakedefine HAVE_CAMV4L2
21
22 /* V4L/V4L2 capturing support via libv4l */ //增加这一行
23#cmakedefine HAVE_LIBV4L //增加这一行
21 24
22 25 /* Carbon windowing environment */
修改 OpenCV2.0.0/src/highgui/cvcap.cpp如下:
172 172 return capture;
173 173 #endif
174 #if defined (HAVE_CAMV4L) || defined (HAVE_CAMV4L2) //删除这一行
174 #if defined HAVE_LIBV4L || (defined (HAVE_CAMV4L) && defined (HAVE_CAMV4L2)) //增加这一行
175 175 capture = cvCreateCameraCapture_V4L (index);
176 176 if (capture)
修改 OpenCV2.0.0/src/highgui/cvcap_libv4l.cpp如下:
227 #if !defined WIN32 && defined HAVE_CAMV4L && defined HAVE_CAMV4L2 //删除这一行
227 #if !defined WIN32 && defined HAVE_LIBV4L //增加这一行
228 228
229 229 #define CLEAR(x) memset (&(x), 0, sizeof (x))
… …
242 242 #include <sys/ioctl.h>
243 243
244#ifdef HAVE_CAMV4L //增加这一行
244 245 #include <linux/videodev.h>
246#endif //增加这一行
247#ifdef HAVE_CAMV4L2 //增加这一行
245 248 #include <linux/videodev2.h>
249#endif //增加这一行
246 250
247 251 #include <libv4l1.h>
make install的时候出现如下错误:
libtool: install: error: relink `libcv.la'
没找到解决方案,库文件在OpenCV2.0.0/src/.libs/* 目录下,注意是个隐藏文件,头文件在 OpenCV2.0.0/include目录下,将库和头文件直接拷到要安装的跟径下即可。
在编应用程序时出现如下错误:
undefined reference to `jpeg_alloc_huff_table@LIBJPEG_9.0'
libcxcore.so: undefined reference to `gzclose'
解决方法: 在 编译选项中加入: -lpng -lpng12 -ljpeg -lz 即包含这些库
OK,之后把需的Opencv2.0的库及png,libz.jpeg等库移植到板子上,设置好环境执行ldconfig加载库,通过ldd test可以查看测试程序依懒哪些库
./test OK 运行成功!
同样的测试代码,不知道是因为重新编译了png, jpeg, libz等库的原因还是啥,运行的速度已达0.54秒!!比最开始的快了6倍!