ARM交叉编译OpenCV错误总结

搬运自本人 CSDN 博客:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/71155560


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源码路径是<code>/root/Desktop/opencv-2.4.9</code>,编译生成路径是源码路径下的/build路径。在make过程中,中间文件基本存在于<code>/root/Desktop/opencv-2.4.9/build/module</code>中,所以在make过程中,笔者会在终端显示<font color=ff0000>已经将上一个模块编译结束后,直接手动将对应模块路径下的中间文件删除</font>……
笔者当时想反正<code>make install</code>指令的目标一般都是<code>/include</code>, <code>/lib</code>, <code>/bin</code>文件夹,这些中间文件占的空间又这么大,删除也不会对<code>make install</code>指令有什么影响……
事实证明我是正确的,但是过程很繁琐,不能像在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

便出现如图所示:


miska.jpg 灰度图

除了显示出图片之外,在桌面上还存储了相应的灰度图.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

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

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

ldconfig

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

(2) file not recognized

之前笔者的OpenCV是交叉编译的,且交叉编译的过程已经在我之前的博客中《 Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9》有过记录。
笔者把编译后的目录opencv-install放置在和PC机相同的路径(即<code>/usr/local/arm/opencv-install/</code>)
之后使用arm-linux-gnueabihf-g++编译Demo程序,然而出现错误:
<code>/usr/local/arm/opencv-install/lib/libopencv_calib3d.so: flie not recognized: File format not recognized
collect2: ld returned 1 exit status</code>
也就是因为这个原因,笔者放弃了用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的总结……(原谅笔者的懒惰,一是因为错误情况少,二是因为时间稍微有点久远了……)

后记:

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,919评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,567评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,316评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,294评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,318评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,245评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,120评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,964评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,376评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,592评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,764评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,460评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,070评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,697评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,846评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,819评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,665评论 2 354

推荐阅读更多精彩内容