交叉编译并移植opencv到arm板遇到的坑

其实,所有的坑,都是自己未来图省事作出来的。重装系统后,仨小时解决了两天没搞定的问题。蛋疼~~~

所以,这篇文章,就说了一个问题: 一定不要用很老的版本(比如tiny210开发板要求的Fedora9)开发嵌入式,否则会蛋疼死你~~~

交叉编译看http://blog.csdn.net/guet_kite/article/details/78667175的文章就行了,按照他的版本进行编译,Ubuntu用16.04  32位,差几个版本也是可以的,但别太多

因为开发板还是12年底买的友善之臂的tiny210,当时想着,随开发板带的库应该会比较老,所以用Fedora9编译会遇到很少的问题,甚至没问题。所以就安装了Fedora9. 首先遇到的问题就是VMware最新版本显示检测到了不支持的CPU,然后下载老版本,却安装不上,然后下载virtualbox安装。

好不容易安装上了,然后下载cmake安装,发现yum不能安装cmake-gui,因为Fedora版本太老,更新yum就花了好长时间。yum安装好,下载cmake-gui安装,并编译的时候提示cmake版本太低,怎么都解决不了,不得已,重装系统~~~


就这一个问题,浪费我一天时间,不断的百度,尝试不同版本,很蛋疼~~~


下面是复制的一篇文章,原地址为http://blog.csdn.net/guet_kite/article/details/78667175 ,我在他的基础之上进行了编译,有一部分不太一样,仅供参考


opencv,计算机视觉库。 
openCV 2.2以后版本需要使用Cmake生成makefile文件,因此需要先安装cmake。 
怎么确保自己的Ubuntu下有没有安装cmake呢? 
cmake –version 
就可以看到已安装的cmake版本号,如果提示cmake命令未知,则没有安装。 
当然,Ubuntu下安装软件一向很简单: 
sudo apt-get install cmake-gui 
之后,可以cmake-gui –version看看cmake安装成功与否: 
cmake 
这里我是在线安装,是3.5.1版本

接下来就是下载opencv了: 
我下载的版本是3.3,当时最新版本应该是3.6

下载好之后解压:unzip opencv-3.3.0.zip 
cd opencv-3.3.0 
建两个文件夹来存放配置和安装路径: 
sudo mkdir /usr/local/opencv/install_opencv -d 
sudo mkdir /usr/local/opencv/config_opencv -d

然后用cmake配置: 

sudo cmake-gui 

还是借用原文中的图,启动区别仅仅是source code路径为opencv-3.3.0

config 
在where is the source code:里写上opencv的源文件路径 
在where to build the binaries:里面写上作为cmake编译arm版本的工作目录 
然后点击configure 
config 
这里generator保持为Unix Makefiles,然后选择第四个选项:Specify options for cross-compiling 
最后点击Next

Linux 
这里Targeting System选的是Linux(之前我选的是arm-linux,有点坑,选这个没有V4L支持), 
接着就是选择工具链了,我用的是友善的4.5.1的工具链(原文章用的是4.4.3,其实都一样),Compliers写的是交叉编译工具 arm-linux-gcc、arm-linux-g++ 
Target Root写的是交叉编译工具 arm-linux-g++/gcc 的所在包含文件夹 
最后点击 Finish即可

ins 
未改任何配置,直接config,也未有错误。

 
最后点击Configure无误后,点击Generate按钮就会在/usr/local/opencv/install_opencv目录生成Makefile(原文有错误,路径应该为/usr/local/opencv/config_opencv

cd /usr/local/opencv/config_opencv 
修改安装opencv的路径: 
sudo vi CMakeCache.txt 
找到:CMAKE_INSTALL_PREFIX:PATH=/usr/local 
修改为:CMAKE_INSTALL_PREFIX:PATH=/usr/local/opencv/install_opencv 
这是我自己的安装路径。 

接着sudo make编译,出现如下错误:

../../lib/libopencv_ts.a(ts_gtest.cpp.obj): In function `testing::internal::UnitTestImpl::~UnitTestImpl()':
ts_gtest.cpp:(.text._ZN7testing8internal12UnitTestImplD1Ev+0xa4): undefined reference to `pthread_getspecific'
ts_gtest.cpp:(.text._ZN7testing8internal12UnitTestImplD1Ev+0xc0): undefined reference to `pthread_key_delete'
ts_gtest.cpp:(.text._ZN7testing8internal12UnitTestImplD1Ev+0x22c): undefined reference to `pthread_getspecific'
ts_gtest.cpp:(.text._ZN7testing8internal12UnitTestImplD1Ev+0x248): undefined reference to `pthread_key_delete'
../../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'
collect2: ld returned 1 exit status
modules/core/CMakeFiles/opencv_test_core.dir/build.make:387: recipe for target 'bin/opencv_test_core' failed
make[2]: *** [bin/opencv_test_core] Error 1
CMakeFiles/Makefile2:1437: recipe for target 'modules/core/CMakeFiles/opencv_test_core.dir/all' failed
make[1]: *** [modules/core/CMakeFiles/opencv_test_core.dir/all] Error 2
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2
  • 解决办法: 

sudo vi CMakeCache.txt 
找到:CMAKE_EXE_LINKER_FLAGS:STRING= 
修改为:CMAKE_EXE_LINKER_FLAGS:STRING=-lpthread -ldl -lrt 
意思是:-lpthread支持线程,-ldl避免未定义dlopen,-lrt避免未定义

最后sudo make编译成功,在sudo make install安装即可。 

sudo  make 的时候遇到一个很蛋疼的问题,我的虚拟机内存开了一个G,编译了九个小时。后来扩大到了两个G,编译了三个小时左右。所以建议虚拟机内存开大一些

这样,就会在/usr/local/opencv/install_opencv出现文件: 
lib

最后把/usr/local/opencv/install_opencv/lib下文件移植到开发板根文件lib下 
即可 
当然,不复制也行,后面再说
 
好了,我们测试下: 
从网上找到一个测试例子,然后修改下,test.cpp:

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <iostream>

using namespace std;

int main(int argc, char **argv)
{
         CvCapture* capture = NULL;
         IplImage* frame = NULL;
         if(!(capture = cvCaptureFromCAM(0))) {
                 cout<<"Can not open camera.\n"<<endl;
                 return -1;
         }
         cvNamedWindow("video", 1);
         while(frame = cvQueryFrame( capture )){
                  cvShowImage("video",frame);
                  cout<<"have capture\n"<<endl;
         }

         cout<<"no have capture\n"<<endl;
         cvDestroyWindow("video");
         cvReleaseCapture(&capture);
         return 0;
}
  • 编译:

arm-linux-g++ -Wno-psabi -I /usr/local/opencv/install_opencv/include/opencv/ -L /usr/local/opencv/install_opencv/lib/ -lopencv_core -lopencv_highgui -lpthread -lrt -o test test.cpp
    • 因为我的库比较新,系统也比较新,所以只出现了下面的问题。

出现两个warning: 
/usr/local/arm/opt/FriendlyARM/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libopencv_imgproc.so, needed by /usr/local/opencv/lib_opencv/lib//libopencv_highgui.so, not found (try using -rpath or -rpath-link) 
/usr/local/arm/opt/FriendlyARM/toolschain/4.4.3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.3/../../../../arm-none-linux-gnueabi/bin/ld: warning: ../../lib/libopencv_core.so, needed by /usr/local/opencv/lib_opencv/lib//libopencv_highgui.so, not found (try using -rpath or -rpath-link)

解决办法是把下面的这些都照着做了一遍,在拷贝库到交叉编译链所在路径时不是有选择的,而是全拷贝。这是链接库的问题,我在网上找了好多办法: 
办法一:

sudo vi /etc/ld.so.conf.d/opencv.conf
  • 1

再文件里写上库文件路径:/usr/local/opencv/install_opencv/lib/ 
接着

sudo ldconfig
  • 1

很遗憾,没有用。。。。

办法二:(此方法中,/usr/local/opencv/install_opencv/lib目录下根本就没有pkgconfig目录,所以添加也白费,

不过我新建一个目录也是白费

sudo vi bash.bashrc
  • 1

在最后写上:

PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opencv/install_opencv/lib/pkgconfig
export PKG_CONFIG_PATH
  • 1
  • 2

也没用!!!

办法三: 
网上找到说,cmake下make出来的.so 文件 arm-linux-gcc-4.3.2不识别。。。。。 
当然,我的编译时是arm-linux-4.4.3,也是一样的, 
他说,在Makefile里将LFLAGS中添加了:-Wl,-rpath-link -Wl,/。。、。。。/…..(lib的目录)就可以了。 
特么我在Makefile里根本没找到LFLAGS,,,失败。

最后,终于找到了办法: 

将这些库内所有的库都复制到编译器的lib中:

sudo cp -d libopencv_*  /usr/local/arm/opt/FriendlyARM/toolschain/4.4.3/arm-none-linux-gnueabi/lib
  • 此时出现一个新的问题
ubuntu@ubuntu-VirtualBox:~/hjm/code$ arm-linux-g++ -Wno-psabi -I /usr/local/opencv/install_opencv/include/ -L /usr/local/opencv/install_opencv/lib/ -lopencv_core -lopencv_highgui -lpthread -lrt -o test test.cpp
/usr/local/opencv/install_opencv/lib//libopencv_core.so: undefined reference to `dlsym'
/usr/local/opencv/install_opencv/lib//libopencv_core.so: undefined reference to `dlopen'
collect2: ld returned 1 exit status


时在编译的时候加上链接-ldl就行了

arm-linux-g++ -Wno-psabi -I /usr/local/opencv/install_opencv/include/ -L /usr/local/opencv/install_opencv/lib/ -lopencv_core -lopencv_highgui -lpthread -lrt -ldl -o test test.cpp


终于可以顺利编译出可执行文件了。。。。。。 
所以,如果之前把/usr/local/opencv/install_opencv/lib下文件移植到开发板根文件lib下,就不会出现这个问题了。 


然后把编译出来的test文件放到开发板上执行:

如果是选择了WITH_GTK而不是选择WITH_QT的,会出现: 
HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP

OpenCV Error: Unspecified error (The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script) in cvNamedWindow, file /usr/local/opencv/opencv-2.4.11/modules/highgui/src/window.cpp, line 483 
terminate called after throwing an instance of ‘cv::Exception’ 
what(): /usr/local/opencv/opencv-2.4.11/modules/highgui/src/window.cpp:483: error: (-2) The function is not implemented. Rebuild the library with Windows, GTK+ 2.x or Carbon support. If you are on Ubuntu or Debian, install libgtk2.0-dev and pkg-config, then re-run cmake or configure script in function cvNamedWindow

Aborted

意思是开发板上缺少GTK/QT 这类图形显示功能。毕竟GTK不好搞。

如果是选择了WITH_QT而不是选择WITH_GTK的,会出现: 
HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP 
init done 
have capture 
have capture

这说明,应该是有数据通过摄像头进来了,因为有了have capture打印输出,但是我们现在是看不到图像的,因为没有平台输出,没有用QT编译。

但是,我们可以看到是有一个error的:HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP 
看了些网上的方法,有人是是因为没有安装libv4l-dev,然而,之前我自己编译安装了libv4l-0.6.3…… 
而且,sudo apt-get install libv4l-dev的话,把opencv按之前的再安装一遍,opencv反而make编译不过,会报错: 
libv4l1.so.1: could not read symbols: File in wrong format 
所以pass掉,sudo apt-get remove libv4l-dev

然后我在opencv源码找到:

/* set the crop area, but don't exit if the device don't support croping */
        if (ioctl (capture->deviceHandle, VIDIOC_S_CROP, &capture->crop) < 0) {
            fprintf(stderr, "HIGHGUI ERROR: V4L/V4L2: VIDIOC_S_CROP\n");
        }

这说的是:设置剪裁面积,如果不能设置,也不退出,我想了下,应该没事吧…… 
毕竟我都能打印出have capture了。而且我拔掉摄像头的话,就会提示Can not open camera.说明打开摄像头失败。

如果不信?那我们试一下opencv的威力: 
我在网上找了一篇opencv的教程, 浅墨博主的文章: 
opencv.cpp:

#include<opencv2/core/core.hpp>  
#include<opencv2/highgui/highgui.hpp>  
#include<iostream>

using namespace cv;  
using namespace std;

int main( )  
{   
    //载入图片  
    Mat image= imread("girl.jpg");  
    Mat logo= imread("fly.jpg");   
    //定义一个Mat类型,用于存放,图像的ROI  
    Mat imageROI;

    imageROI= image(Rect(10,10,logo.cols,logo.rows));//定义一个左上角点坐标为(_x, _y)的cols*rows矩形窗口

    //将logo加到原图
    //参数:图、权重、图、权重、添加的常数项、输出图
    addWeighted(imageROI,0.5,logo,0.3,0.,imageROI);     

    cout << "start add picture......\n" << endl;    
    //输出一张jpg图片到工程目录下  
    imwrite("fly_girl.jpg",image);  

    waitKey();  

    return 0;  
}  

Makefile:

CC  = arm-linux-g++
LFLAGS  = -Wno-psabi
LIBS    = -L/usr/local/opencv/install_opencv/lib/ -L/work/qt/my_qt/lib
CPPFLAGS    = -lQt5Widgets -lQt5Gui -lQt5Core -lpthread -lopencv_core -lopencv_highgui -lpthread -lrt
LINC     += -I/usr/local/opencv/install_opencv/include/opencv/
objs := open
out := open

$(out):$(objs).cpp
    ${CC} ${LFLAGS} ${LIBS} ${LINC} ${CPPFLAGS} -o $@ $^

clean:
    rm $(out)

还是那个老话,如果没有选择WITH_QT的话, 
-lQt5Widgets -lQt5Gui -lQt5Core和-L/work/qt/my_qt/lib 
可以不需要。 
这是girl.jpg图: 
girl 
这是fly.jpg图: 
fly

这是使用opencv合成的效果图: 
opencv 
效果非常棒,不愧是opencv!!!

最后,QT+opencv的例子:opencv+QT在嵌入式arm下显示图片


  • 9
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值