Tiny6410的OpenCV2.4.2移植笔记

关于OpenCV在ARM上的移植最经典的应该就是这篇:
编译OpenCV for arm-linux

去年在什么都不懂的情况下移植的时候也主要是靠这篇文章,写得很详细,如果你觉得还不够详细的话,推荐个带图的:
opencv2.3.1在arm端的移植

这篇写得也不错:
Linux下移植OpenCV+Qt到ARM(Tiny6410)总结

我的环境是Ubuntu12.04,板子是友善之臂的tiny6410。

首先当然是装好arm-linux-gcc,配置环境变量,输入arm-linux-gcc -v有输出,这步就完成了。
然后是cmake,比较方便的是用带界面的cmake-gui,要注意的地方是CMAKE_INSTALL_PREFIXWITH_TIFF还有CMAKE_EXE_LINKER_FLAGS

第一个参数需要注意是因为我们编译的库是适用于ARM的,不应该直接放在/usr/local里,否则如果装了x86的OpenCV会有冲突,比如改成/usr/local/opencv-arm。第二个参数一般情况下需要去掉勾,因为似乎默认情况下ubuntu是没有这个支持的,要选上得自己装些什么东西。第三个参数是因为OpenCV需要这两个库的支持?我现在也还不太明白,总之加上-lrt和-lpthread就不会报错了。其它参数保持原状基本都不会报错。

cmake好后下一步是make,对于双核的机器加上-j4参数速度会快很多,但是也发烫,在系统监视器里看到四个线程的CPU都是接近100%,风扇一直呼呼地响。

然后是配置编译环境了,好像在2.3以后OpenCV的x86版安装好后都会有pkgconfig的.pc文件。//2.3以前的版本不清楚

所以比较方便的就是用pkgconfig来配置了,它的.pc文件是在/usr/local/lib/pkgconfig下面。这是适用于PC版本的OpenCV的(因为之前已经安装好了x86的OpenCV)。但是只要把那第一行的prefix路径改成ARM版OpenCV的安装路径(也就是上面CMAKE_INSTALL_PREFIX参数的值)就可以直接用了。opencv2.3.1在arm端的移植这篇帖子说再Libs里要加上-lrt -lpthread参数,我的环境下似乎不需要,但是加上也没什么问题。

这样配置好后,arm-linux-gcc编译的时候加上参数`pkg-config —cflags —libs opencv-arm`就行了,比如arm-linux-gcc `pkg-config —cflags —libs opencv-arm` test.c -o test。//在这个情况下.pc文件名是opencv-arm,注意是两个反引号。
我用的主要是Qt,所以在.pro文件里加上:

    unix {
        CONFIG += link_pkgconfig
        PKGCONFIG += /usr/local/lib/pkgconfig/opencv-arm.pc
    }

但是编译成功后可能会显示一些警告,比如:

    ../../lib/libopencv_core.so, needed by /usr/local/opencv-arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)

这个警告在我的情况下只要把opencv-arm/lib里的.so文件全部放到/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/lib下面就可以解决,但事实上不管这条警告也不会出什么问题,不会影响到程序的运行。//去年移植的时候就一直没管

但是耗费我四天的根本就不是这些问题有木有啊!我要开始吐槽了有木有啊!

首先要吐槽一下u盘,有个以前编译好的程序放在u盘上一直不能运行,报错

    ../../lib/libopencv_core.so, needed by /usr/local/opencv-arm/lib/libopencv_highgui.so, not found (try using -rpath or -rpath-link)

和编译时那个警告一样,害得我以为是那个警告必须解决掉。后来折腾了好久发现只要把程序拷到板子的存储介质上就直接能运行了!尼玛啊是文件系统还是权限的神马问题啊!于是我就换成用nfs挂载了。

现在去年编译的那个程序是能运行了,可是新编译的程序都不能和OpenCV库连上,也是报相同的错,好吧,我试过把.so文件放在/lib下,放在/usr/local/opencv-arm/lib下,两个都放,甚至还试过新建好多个文件夹,放在/opt/FriendlyARM/toolschain/4.5.1/arm-none-linux-gnueabi/sys-root/lib下,结果都一样!只有老的程序能运行,新编译的都不行。后来脑袋终于开窍了,既然老程序可以运行,说明我移植的OpenCV库没有问题。于是我尝试直接用armm-linux-gcc编译了一个简单的程序,发现运行正常?!然后不知什么想法让我把新编译的程序拷贝到/mnt下,也就是nfs挂载的那个目录,神奇的事情发生了,它正常运行了!!!

那么,这究竟是什么原理呢?我到现在还没搞明白。nfs挂载以后,所有挂载的文件都相当于自己原本文件系统里的文件么?还是有权限什么的问题呢?