Opencv源码交叉编译和移植到ARM

一、安装cmake-gui

OpenCV 2.0之后的版本,必须使用CMake创建Makefile。在终端输入cmake-gui之后,如果提示未安装,可以通过以下指令进行安装:

$ sudo apt-get install cmake-qt-gui

安装好之后,可以通过 cmake --version指令查看cmake的安装版本


二、利用cmake-gui配置Opencv,生产Makefile

首先创建交叉编译文件夹opencv-arm, 创建好之后,然后切换至root用户,运行cmake-gui,按照以下步骤进行配置:

   (1)选择源代码目录:/home/smz/work/opencv/OpenCV-2.3.1
    (2)选择Build目录:/home/smz/work/opencv/opencv-arm

   (3)点击Configure   
            (4)保持generator为Unix Makefiles
            (5)选择Specify options for cross-compiling
            (6)点击Next   
            (7)Operating System填写arm-inux(必填),其他可以不填
            (8)C Compilers填写/usr/local/arm/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin/arm-linux-gnueabihf-gcc

            (9)C++ Compilers填写/usr/local/arm/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin/arm-linux-gnueabihf-g++

           (10)程序库的Target Root填写/usr/local/arm/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin

           (11)点击Finish,即可开始配置

三、修改cmake的配置

cmake配置修改工作如下:

    (1)加上BUILD_PNG和BUILD_JPEG

    (2)去掉WITH_TIFF,WITH_OPENEXR和BUILD_EXAMPLES

    (3)修改CMAKE_BUILD_TYPE为Release

    (4)修改CMAKE_INSTALL_PREFIX为/usr/local/opencv-arm
然后重新Configure,观察红色是不是已经全部消失了!如果没有就继续Configure,直到没有红色,然后点击Generate,生成makefile文件。

四、修改编译配置

进入最初创建的opencv-arm文件夹,找到CmakeCache.txt文件,对其进行修改。

找到:

//Flags used by the linker.

CMake_EXE_LINKER_FLAGS:STRING='  '

修改为:

//Flags used by the linker.

CMake_EXE_LINKER_FLAGS:STRING= -lpthread -lrt -ldl

五、编译

    修改完,保存。然后在终端编译
# make


报错:

/usr/local/arm/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.7.3/../../../../arm-linux-gnueabihf/bin/ld: ../../3rdparty/lib/libzlib.a(inflate.c.obj): relocation R_ARM_THM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
../../3rdparty/lib/libzlib.a: could not read symbols: Bad value
collect2: error: ld returned 1 exit status
make[2]: *** [lib/libopencv_core.so] 错误 1
make[1]: *** [modules/core/CMakeFiles/opencv_core.dir/all] 错误 2
make: *** [all] 错误 2


原因:

目前Linux OS系统会推出32位和64位两个不同的版本,由于32位程序和64位程序可能不兼容,因此如果在32bit OS环境下编译获得的库文件,移植入64bit环境时会产生Could not read symbols错误,一般是64 位 电脑才会出现。

解决方法:

进入opencv目录下的3rdparty的对应目录CMakeFiles/ *.dir下,打开flags.make,在C_FLAGS = 后添加-O3 -fPIC用来支持在64位机上编译
                如../3rdparty/zlib/CMakeFiles/zlib.dir/flags.make
                修改C_FLAGS =  -W -Wall 为 C_FLAGS =  -O3 -fPIC  -W -Wall
                和
                修改CXX_FLAGS =  -W -Wall 为 C_FLAGS =  -O3 -fPIC  -W -Wall

六、安装

# make install

七、将交叉编译得到的库拷贝到开发板/lib

八、编写测试程序

利用Qt creator创建工程test

(1)编辑.pro:


QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = untitled
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    += mainwindow.ui

INCLUDEPATH += /usr/local/opencv-arm/include \
                /usr/local/opencv-arm/include/opencv \
                /usr/local/opencv-arm/include/opencv2

LIBS += /usr/local/opencv-arm/lib/libopencv_highgui.so \
        /usr/local/opencv-arm/lib/libopencv_core.so    \
        /usr/local/opencv-arm/lib/libopencv_imgproc.so

(2)编辑mian.cpp:


#include
#include
#include
#include
using namespace cv;
using namespace std;

int main()
{
        namedWindow( "src");
        Mat img = imread( "1.jpg" );

        if(!img.data) {
            cout<<"file not fount"<             return 1;
        }
        else {
            imshow( "src", img );
            waitKey();
            return 0;
        }
}

交叉编译后得到可执行程序,拷贝到开发板,并执行。


报错:

OpenCV Error: Unspecified error (The function is not implemented. Rebuild the l5
terminate called after throwing an instance of 'cv::Exception'                  
  what():  /home/smz/work/opencv/OpenCV-2.3.1/modules/highgui/src/window.cpp:27w

原因:

因为ARM板子上没有可以用于图像显示界面的库,比如GTK或Qt等,ARM不支持用Opencv的highgui模块来显示图像。

解决办法:程序改写为使用Qt窗口部件类来显示图像。

创建一个简单的Qt应用程序,继承自Qwidget。然后改写构造函数:

(1)编辑.pro:


QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = test6
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

INCLUDEPATH += /usr/local/opencv-arm/include/
INCLUDEPATH += /usr/local/opencv-arm/include/opencv
INCLUDEPATH += /usr/local/opencv-arm/include/opencv2

LIBS += /usr/local/opencv-arm/lib/libopencv_calib3d.so
LIBS += /usr/local/opencv-arm/lib/libopencv_core.so
LIBS += /usr/local/opencv-arm/lib/libopencv_contrib.so
LIBS += /usr/local/opencv-arm/lib/libopencv_features2d.so
LIBS += /usr/local/opencv-arm/lib/libopencv_flann.so
LIBS += /usr/local/opencv-arm/lib/libopencv_gpu.so
LIBS +=/usr/local/opencv-arm/lib/libopencv_highgui.so
LIBS += /usr/local/opencv-arm/lib/libopencv_imgproc.so
LIBS += /usr/local/opencv-arm/lib/libopencv_legacy.so
LIBS += /usr/local/opencv-arm/lib/libopencv_ml.so
LIBS += /usr/local/opencv-arm/lib/libopencv_objdetect.so
LIBS += /usr/local/opencv-arm/lib/libopencv_ts.so
LIBS +=/usr/local/opencv-arm/lib/libopencv_video.so


(2)widget.cpp:


#include "widget.h"

#include "ui_widget.h"

#include

#include "widget.h"

#include

#include

#include

using namespace cv;



Widget::Widget(QWidget *parent) :

   QWidget(parent),

   ui(new Ui::Widget)

{

   ui->setupUi(this);

   Mat srcImage1= imread("1.jpg");//加载图片

   Mat rgbImage;

   cvtColor(srcImage1,rgbImage,CV_BGR2RGB);//转换颜色空间

   QImage img=QImage((const unsigned char *)(rgbImage.data),rgbImage.cols,

                     rgbImage.rows,rgbImage.cols*rgbImage.channels(),QImage::Format_RGB888);//创建QImage对象

   ui->label->setPixmap(QPixmap(QPixmap::fromImage(img)));

   ui->label->resize(ui->label->pixmap()->size());

   ui->label->move(0,0);

}



Widget::~Widget()

{

   delete ui;

}

(3)widget.ui:


拖拉一个label


再次交叉编译后得到可执行程序,拷贝到开发板,并执行,运行正常,LCD显示目标图像。





参考资料:

http://bbs.elecfans.com/jishu_528480_1_1.html

http://blog.csdn.net/bizer_csdn/article/details/51707013

http://blog.csdn.net/u013752202/article/details/47358389

你可能感兴趣的:(linux,ubuntu,arm,qt,opencv)