ARM交叉编译OpenCV错误总结

ARM交叉编译OpenCV错误总结

最近尝试给两个ARM板子与用交叉编译配置OpenCV,为此查了很多资料,学了很多交叉编译的操作。 经过多次的交叉编译全都失败,都不能成功的在目标板上运行简单的OpenCV的Demo程序。最后都是在对板子失去希望的时候,破罐破摔的直接用ARM板自己编译。讽刺的是,这样虽然效率低到极致,但最后还真的成功了…… 在Demo程序在ARM板自行编译成功的OpenCV环境中顺利的跑起来的时候,笔者感觉茫然无措,根本没有什么开心的情绪,一是感觉终于解脱了,二是感觉自己学了这么长时间的交叉编译,最后还是没有用,还写了这么多技术博客,深深的无力感…… 笔者决定还是痛定思痛,还是得总结一下这段时间交叉编译的错误所在。在中间的一些操作中,笔者总感觉自己交叉编译的过程中,就是还是那么差了一点点才导致失败。虽然已经没有精力再重新搞一遍交叉编译。这些疑点还是可以记录下来,以后有机会的时候,笔者会重新拿出来看,也许真的是这些原因导致我交叉编译错误呢?

笔者的两个ARM板配置如下:

  • 迅为i.MX6Q开发板
    • 操作系统:Linux
    • 发行版:Debian GNU/Linux (BeagleBoard.org Debian Image)
    • CPU:1GHz四核
    • 容量:16GBytes eMMC
  • BeagleBone Black
    • 操作系统:Linux
    • 发行版:Ubuntu 12.04
    • CPU:1GHz单核
    • 容量:4GBytes eMMC

之前笔者写的交叉编译相关技术文章地址如下: 《 Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9》 《Windows系统下远程连接BeagleBone Black开源电路板桌面》 《Windows系统下通过PSCP传输文件至BeagleBone Black》 《交叉编译学习笔记(一)——交叉编译和交叉工具链》 《交叉编译学习笔记(二)——交叉编译器的命名规则》 《程序生成之编译、链接、加载浅析》

一. BeagleBone Black编译总结

BeagleBone Black(即BBB)上OpenCV的编译是真的痛苦。 主要原因是它的4GBytes的容量实在让我绝望,而且我拿到板子的时候基本上也只有1GBytes的剩余容量了,OpenCV编译过程中生成的中间文件大小都得有2GB啊…… 这导致笔者几乎从一开始就否定了直接用BBB编译的想法,一直在尝试交叉编译……

1. 编译成功方法

讽刺的是交叉编译一直失败,最后我还是直接在ARM上编译成功的,即先设置各项CMake选项,然后对OpenCV进行make操作,最后make install,并make clean清除中间文件。 为什么笔者能在1GBytes的剩余容量中编译出2GB的中间文件?这就是最蛋疼的地方所在…… 笔者OpenCV源码路径是/root/Desktop/opencv-2.4.9,编译生成路径是源码路径下的/build路径。在make过程中,中间文件基本存在于/root/Desktop/opencv-2.4.9/build/module中,所以在make过程中,笔者会在终端显示已经将上一个模块编译结束后,直接手动将对应模块路径下的中间文件删除…… 笔者当时想反正make install指令的目标一般都是/include, /lib, /bin文件夹,这些中间文件占的空间又这么大,删除也不会对make install指令有什么影响…… 事实证明我是正确的,但是过程很繁琐,不能像在PC机上编译时,只要放在那里编译就好,笔者可以去看电视剧…… 这种盯着终端输出信息,手动删除编译中间文件的操作,需要进行两遍:make一次,make install一次。如果中间跑神了,make过程中出现了错误提示说容量不够导致make失败,那就惨了,需要重新多来一次……

最后make, make install成功后,写了一个Demo文件test_opencv.cpp,内容如下:

#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <iostream>
#include <vector>

using namespace std;
using namespace cv;

int main(int argc, char* argv[])
{
    const char* imagename = "/root/Desktop/miska.jpg";
    Mat img = imread(imagename);

    if(img.empty())
    {
        fprintf(stderr, "Can not load image %s\n", imagename);
        return -1;
    }
    else
        printf("Read Image Success.\n");

    Mat imgGray;
    cvtColor(img, imgGray, CV_BGR2GRAY);

    const char* imgGrayName = "/root/Desktop/miska_gray.jpg";
    vector<int> params;
    params.push_back(CV_IMWRITE_JPEG_QUALITY);
    params.push_back(90);
    imwrite(imgGrayName, imgGray, params);

    if(imgGray.empty())
    {
        fprintf(stderr, "Can not save image %s\n", imgGrayName);
        return -1;
    }
    else
        printf("Save Image Gray Success.\n");

    imshow("Image", imgGray);
    waitKey();

    return 0;
}

然后在cpp文件所在目录下,输入指令如下:

arm-linux-gnueabihf-g++ `pkg-config --cflags --libs opencv` test_opencv.cpp -lpthread -lrt -o test_opencv_g++_show

然后就生成了test_opencv_g++_show的可执行文件。这时候输入指令:

./test_opencv_g++_show

便出现如图所示:

除了显示出图片之外,在桌面上还存储了相应的灰度图.jpg文件miska_gray.jpg。

这就是笔者愚蠢但有效的移植方法……

2. 错误情况总结与猜想

(1) error while loading shared libraries: libopencv_highgui.so.2.4

其实上面成功的内容并不是在make install之后直接就完成的。 笔者对test_opencv.cpp进行编译指令如下:

arm-linux-gnueabihf-g++ `pkg-config --cflags --libs opencv` test_opencv.cpp -lpthread -lrt -o test_opencv_g++_show

却出现如下错误提示: error while loading shared libraries: libopencv_highgui.so.2.4 后来笔者参考了网上的资料,原来是笔者的OpenCV路径没有设置。 参考地址: http://blog.csdn.net/gaobobo138968/article/details/24253703 http://blog.csdn.net/fangquan1980/article/details/49363173

首先,笔者在进行make install命令之前,设定的install路径为/usr/local/arm/opencv-install/,生成的库文件都是动态链接库。而在Linux系统中,文件/etc/ld.so.conf中记录着动态函数库所在目录。所以笔者需要在/etc/ld.so.conf中将路径/usr/local/arm/opencv-install/添加进去。 然后就需要执行指令:

ldconfig

这样就将/etc/ld.so.conf中的内容读入了高速缓存,同时/etc/ld.so.cache文件中开始记录数据。 重新用arm-linux-gnueabihf-g++编译Demo程序,就编译成功,且能成功运行了。

(2) file not recognized

之前笔者的OpenCV是交叉编译的,且交叉编译的过程已经在我之前的文章中《 Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9》有过记录。 笔者把编译后的目录opencv-install放置在和PC机相同的路径(即/usr/local/arm/opencv-install/) 之后使用arm-linux-gnueabihf-g++编译Demo程序,然而出现错误: /usr/local/arm/opencv-install/lib/libopencv_calib3d.so: flie not recognized: File format not recognized collect2: ld returned 1 exit status 也就是因为这个原因,笔者放弃了用PC机交叉编译……

网上查了查原因,有人出现这样的问题,但却是因为文件格式,或者是x86的32/64位系统版本,或者是直接就没有用arm-linux-gcc系列的编译器之类的原因,况且我用的也是arm平台的编译器(笔者在PC机端用的编译器是arm-none-linux-gcc-4.3.2,在BeagleBone Black板上的编译器是4.6.3版本的arm-linux-gnueabihf-gcc),虽然版本不同,但笔者认为在PC机上用的编译器应该是被BBB的编译器向下兼容的。

对于这种情况,笔者感觉只有两种操作可能解决: 1、用4.6.3版本的arm-linux-gnueabihf-gcc编译相关库;(其实也尝试过,但是在编译ffmpeg源码时貌似出了问题…… ) 2、当时确实没有用过ldconfig命令,也可能是这个原因?……

(3) 使用错误的编译器

这个本来都不想回忆的,因为实在太低级失误了…… 笔者曾经用了gcc的编译器编译Demo程序,然而库文件是交叉编译的arm-linux-gcc版本,结果肯定是运行不了的…… 具体什么情况忘了,记着这个教训就好了……

二. 迅为i.MX6Q开发板编译总结

1. 编译成功方法

虽然交叉编译失败,但是ARM本机编译方面,相比起来迅为的ARM开发板比BBB简单的多了。毕竟i.MX6Q的CPU可以使用多核编译,而且eMMC容量也大得多,所以不需要盯着终端输出信息各种手动删除中间文件腾空间,只需要简单的cmake, make, make install,之后就可以编译运行了…… 其他的基本可以参照BBB的成功范例。

2. 错误情况总结与猜想

i.MX6Q的系统是和PC机一样的Ubuntu,所以错误情况比较少,基本上还是可以参考BBB的总结……(原谅笔者的懒惰,一是因为错误情况少,二是因为时间稍微有点久远了……)

后记:

笔者真的是已经没有精力再专门重新编译了……所以只有在此处记录为博客,以后如果真有重新交叉编译的情况,再重新尝试。 希望个人的错误总结也可以有点价值吧。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阮一峰的网络日志

也许,DOM 不是答案

有一个词"手机网站"(mobile web),指供手机浏览的网站,但它是不存在的。 人们提到"移动互联网"的时候,其实专指另外一样东西:手机App。 ? 一、W...

3205
来自专栏晨星先生的自留地

渗透某网站

2034
来自专栏FreeBuf

有工具了,如何快速发现Windows中毒(含工具下载)

本文是之前《没有外部工具,如何快速发现Windows中毒了》的姊妹篇,探讨Windows电脑感染多种典型病毒后,在没有专业杀毒软件情况下的快速检测方法。 Pro...

1829
来自专栏点滴积累

Ubuntu16.04双网卡主备配置

前几日写了一篇Ubuntu14.04双网卡主备配置,没成想变化总是这么快,今日安装某软件,提示最匹配的ubuntu版本是16.04,作为一个码农能有什么办法,只...

3885
来自专栏Python中文社区

反爬虫机制和破解方法汇总

什么是爬虫和反爬虫? 爬虫:使用任何技术手段,批量获取网站信息的一种方式。 反爬虫:使用任何技术手段,阻止别人批量获取自己网站信息的一种方式。 ? 常见的反...

7719
来自专栏向治洪

iOS开发入门笔记

iOS开发入门笔记 本文面向已有其它语言(如Java,C,PHP,Javascript)编程经验的iOS开发初学者,初衷在于让我的同事一小时内了解如何开始开发i...

3066
来自专栏Android 开发者

Android Oreo 常见问题 3.0 | Android 开发者 FAQ Vol.11

1912
来自专栏ASP.NET MVC5 后台权限管理系统

ASP.NET MVC5+EF6+EasyUI 后台管理系统 (源码购买说明)

系列目录 方便朋友获取一个开发框架,无论是开发还是学习用途将受益匪浅,出售此框架源码价格666,终身免费升级,在线解答问题 您可以通过QQ 729994997 ...

2655
来自专栏FreeBuf

爬虫采集去重优化浅谈

以前在做漏洞Fuzz爬虫时,曾做过URL去重相关的工作,当时是参考了seay法师的文章以及网上零碎的一些资料,感觉做的很简单。近来又遇到相关问题,于是乎有了再次...

2526
来自专栏用户3211691的专栏

前端面试题1(HTML篇)

html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

351

扫码关注云+社区