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;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////