Linux环境:Red Hat 5
交叉编译:4.1.2
ARM9板:LT2440
Opencv移植应用于Qt
———————————————————————————————————
下面是参考网上资料结合实际的移植过程,opencv移植时我将所有所需的库
同一目下“/opt/ruanjian/Trolltech/qt-4.6.3”。
这个过程是我没能将ffmpeg和Opencv依赖(但必须要有ffmpeg的相关库,这个过程我是将ffmpeg和Opencv放于同一目录下它们之间没能建立起依赖,但不在同一目录就可建立依赖,但存在一个问题就是将移植所需库烧到ARM板,运行程序时却提示缺少“libavformat.so”,实际上我将这个库也烧到ARM板而且用LD-LIBRARY-PATH指定了ffmpeg的相关库,还不知道为什么有待研究。)的非完整版本,这个版本是重复移植多次后成功了的能过使用摄像头进行实时监控但不能保存视频。
———————————————————————————————————
下面是所用到的库:
我使用Qt库是qt-4.6.3其中包含了libz1.2.5所以这个库不用安装。
1、jpegsrc.v8b.tar.gz
2、libpng-1.2.18.tar.gz
3、yasm-0.7.2.tar.gz
4、ffmpeg-0.9.2.tar.bz2
5、OpenCV-2.0.0.tar.bz2
免费资源下载地址:http://download.csdn.net/user/pk124729136
———————————————————————————————————
1, libjpeg的交叉编译:
解压后进入jpeg-8b的目录:
# CC=arm-linux-gcc ./configure --prefix=/opt/ruanjian/Trolltech/qt-4.6.3 --enable-shared
#make
make之后如果出现这样的错误:”
./libtool --mode=compile arm-linux-gcc -O2 -I. -c ./jcapimin.c
make: ./libtool: Command not found
make: *** [jcapimin.lo] Error 127
解决办法:检查自己系统下有没有libtool,如果没有那么自己装一个;装完之后把config.guess &&config.sub复制到jpeg目录下:
#cd /usr/share/libtool/config/config.sub ./
#cd /usr/share/libtool/config/config.guess ./
然后执行
#make install
2, libpng的交叉编译
解压后进入libpng-1.2.18的目录:
# CC=arm-linux-gcc ./configure --prefix=/opt/ruanjian/Trolltech/qt-4.6.3 --enable-shared --host=arm-linux
#make
#make install
4, yasm的交叉编译:
解压后进入yasm-0.7.2目录
# CC=arm-linux-gcc ./configure --prefix=/opt/ruanjian/Trolltech/qt-4.6.3--enable-shared --host=arm-linux
#make
#make install
7, ffmpeg的交叉编译:
解压后进入ffmpeg-0.9.2目录:
注:ffmpeg使用x264时会存在一些问题,如“ERROR: x264 not found”
这种问题就将x264安装在交叉编译器里,另外这里ffmpeg也最好用最新版本的
#./configure --prefix=/opt/ruanjian/Trolltech/qt-4.6.3 --enable-shared --disable-static --enable-gpl --enable-cross-compile --arch=arm --disable-stripping --target-os=linux --cc=arm-linux-gcc --enable-swscale
#make
#make install
9, opencv2.0.0的交叉编译:
解压后进入opencv2.0.0目录:首先,修改configure文件:
#gedit configure
搜索-lavcodec,定位到大概18182行的位置,在“FFMPEGLIBS="-lavcodec -lavformat” 后添加 “-lswscale”,修改之后变为:“FFMPEGLIBS="-lavcodec -lavformat -lswscale $FFMPEG_SWSCALE_LIBS"”,然后保存退出。
#./configure --prefix=/opt/ruanjian/Trolltech/qt-4.6.3 --host=arm-linux --without-gtk --without-carbon --without-quicktime --without-1394libs --without-python --without-swig --enable-static --enable-shared --disable-apps CXX=arm-linux-g++ CPPFLAGS=-I/opt/ruanjian/Trolltech/qt-4.6.3/include LDFLAGS=-L/opt/ruanjian/Trolltech/qt-4.6.3/lib --with-v4l
#make
#make install
编译过程如果遇到libz.la、libz.so、libz.so.1、libz.so.1.2.3文件没有可到交叉编译器“arm-none-linux-gnueabi”目下找libz.la,在第一步骤下编译的libz所安装的目录下找。这时候要对“/usr/lib”中的“libz.so、libz.so.1、libz.so.1.2.3”进行备份,因为make Opencv时用到的“libz.so、libz.so.1、libz.so.1.2.3”需要用arm-linux-gcc交叉编译器编译的。编译完后进行删除然后还原备份不然不能正常启动编译过程如果遇到libz.la、libz.so、libz.so.1、libz.so.1.2.3文件没有可到交叉编译器“arm-none-linux-gnueabi”目下找libz.la,在第一步骤下编译的libz所安装的目录下找。这时候要对“/usr/lib”中的“libz.so、libz.so.1、libz.so.1.2.3”进行备份,因为make Opencv时用到的“libz.so、libz.so.1、libz.so.1.2.3”需要用arm-linux-gcc交叉编译器编译的。编译完后进行删除然后还原备份不然不能正常启动。
在建立工程时在xxx.pro文件中加入下面语句即可。
LIBS +=/opt/ruanjian/Trolltech/qt-4.6.3/lib/libcv.so\
/opt/ruanjian/Trolltech/qt-4.6.3/lib/libcvaux.so \
/opt/ruanjian/Trolltech/qt-4.6.3/lib/libcxcore.so\
/opt/ruanjian/Trolltech/qt-4.6.3/lib/libhighgui.so \
/opt/ruanjian/Trolltech/qt-4.6.3/lib/libml.so
注:如果是用qt开发opencv,使用上述配置后如果出现“:-1: error: collect2: ld returned 1 exit status”错误,就将编译好的库加入到qt库里面去,这种情况将库烧入到arm板时最后重新加入qt库(包含opencv等在opencv移植时所用到的库)。
———————————————————————————————————
到此,opencv-2.0.0的移植算是成功了。接下来编写一个Qt程序烧到开发板上运行(此程序在图形界面上是有一个label控件)。
程序代码:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QTimer>
#include<QImage>
#include<opencv/cv.h>
#include<opencv/highgui.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
CvCapture *capture;
CvSize size;
CvVideoWriter *videoWrite;
QTimer *timer;
QImage *image;
protected:
void changeEvent(QEvent *e);
void init();
private:
Ui::MainWindow *ui;
private slots:
void displayPicture();
};
#endif // MAINWINDOW_H
//
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
init();
}
MainWindow::~MainWindow()
{
delete ui;
cvReleaseVideoWriter(&videoWrite);
}
void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void MainWindow::init()
{
timer = new QTimer;
capture = cvCreateCameraCapture(0);
size = cvSize(320,240);
videoWrite = cvCreateVideoWriter("test.avi",CV_FOURCC('M','J','P','G'),10,size,1);
connect(timer,SIGNAL(timeout()),this,SLOT(displayPicture()));
timer->start(30);
}
void MainWindow::displayPicture()
{
IplImage *frame = cvQueryFrame(capture);
cvCvtColor(frame,frame,CV_BGR2RGB);
image = new QImage((unsigned char*)frame->imageData,frame->width,frame->height,frame->widthStep,QImage::Format_RGB888);
ui->label->setScaledContents(true);
ui->label->setPixmap(QPixmap::fromImage(*image,Qt::AutoColor));
cvWriteFrame(videoWrite,frame);
delete image;
}
//