日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

QT与openCV,与PCL结合!

發布時間:2023/12/31 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 QT与openCV,与PCL结合! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
(1):詳解QT多媒體框架:給予視頻播放器

原文鏈接:http://mobile.51cto.com/symbian-271123.htm

? ?

? ?對于使用主框架的QT程序,實現Qimage的轉換可借鑒下面程序段:

void MainWindow::on_openButton_clicked() {//第3個參數表示查找文件時從哪個目錄開始,如果為"."的話,表示從該工程目錄開始查找,最后那個參數的過濾器的名字之間//要用空格,否則識別不出來QString img_name = QFileDialog::getOpenFileName( this, tr("Open Image"), ".",tr("Image Files(*.png *.jpg *.jpeg *.bmp)"));//toAscii()返回8位描述的string,為QByteArray,data()表示返回QByteArray的指針,QByteArray為字節指針Mat src = imread( img_name.toAscii().data() );cvtColor( src, src, CV_BGR2RGB );QImage img = QImage( (const unsigned char*)(src.data), src.cols, src.rows, QImage::Format_RGB888 ); // namedWindow( "Image_Show", WINDOW_AUTOSIZE ); // imshow( "Image_Show", src );ui->label->setPixmap( QPixmap::fromImage(img) );// ui->label->resize( ui->label->pixmap()->size() );}

(2):詳解QT 快速應用OPENCV ,圖片示例:基于widget!!!

原文鏈接:http://mobile.51cto.com/symbian-271260.htm


QT 框架中快速應用OpenCV?是本文要結束的內容,和MFC比較起來,QT的信號槽機制比MFC的信號機制慢,但是因為能很好的實現跨平臺,所以我在這里總結一下可能對一些人有點用。OpenCV.China論壇上有一個帖子叫做《在MFC框架中快速應用OpenCV》看了后就想結合QT寫一下。

0搭建環境:OpenCV + QT 4.6

我的實驗是基于VS2008來做的,QT官方雖然提供了VS2008-add-in的插件,我沒有用。直接下載器編譯好的庫文件進行配置,OpenCV的在VS2008下面的配置方法Google一下到處都是,這里不再補充。首先需要做的是在VS2008里面你需要使QT下和OpenCV的程序能分別跑起來。對于QT在VS的配置其實挺簡單,有頭文件和相應的鏈接庫,保證調用的時候路徑正確,一般就沒有問題了。常用命令行make程序的人應該會很清楚那些IDE只不過是層畫皮。

.pro配置:

[cpp] view plaincopy

INCLUDEPATH += d:\opencv\build\include\ INCLUDEPATH += d:\opencv\build\include\opencv\ INCLUDEPATH += d:\opencv\build\include\opencv2\ CONFIG(debug,debug|release) { LIBS += -Ld:\opencv\build\x86\vc10\lib \ -lopencv_core243d \ -lopencv_highgui243d \ -lopencv_imgproc243d \ -lopencv_features2d243d \ -lopencv_calib3d243d } else { LIBS += -Ld:\opencv\build\x86\vc10\lib \ -lopencv_core243 \ -lopencv_highgui243 \ -lopencv_imgproc243 \ -lopencv_features2d243 \ -lopencv_calib3d243 } 1.顯示圖像

QWidget是QObject下的第一個子類,使用它顯示圖像會減少不必要的開銷。首先定制一個自己需要的QWidget:

  • class?myWidget?:?public?QWidget ?
  • { ?
  • ??Q_OBJECT ?
  • ??public: ?
  • ????myWidget(const?IplImage?*img,QWidget?*parent?=?0); ?
  • ????~myWidget(); ?
  • ??protected: ?
  • ????void?paintEvent(QPaintEvent?*e); ?
  • ??private: ?
  • ????IplImage*?iplImg; ?
  • ????QImage?*qImg; ?
  • };?
  • 需要繪制一個圖像,我重載paintEvent(QpaintEvent *e),我在這里面使用QPainter進行繪制。

  • void?myWidget::paintEvent(QPaintEvent?*e) ?
  • { ?
  • ????QPainter?painter(this); ?
  • ????painter.drawImage(QPoint(5,5),*qImg); ?
  • }?
  • rawImage(QPoint(5,5),qImg);的作用是將qImg繪制在左上頂點位于QPoint(5,5)處。

    這里面有可能兩個問題,第一個問題是要顯示的圖片太小,創建的Widget太大,最后顯示比較丑陋。這時可以在此函數里面獲得qImg的寬高,然后resize一下就好了。另外一個問題是:繪制的時候使用的是QImage,不是IplImage類型。關于這個問題論壇上有人專門寫了IplImage <-> QImage的轉換代碼,我在這里不重復那個做法,一是有人已經做了,另外處于效率考慮,這里提供另一種方法。

    通常同學們都是用cvLoadImage來讀圖片,保存在IplImage里面,在這里這個圖片我們保存在img里面,然后通過img傳進QWidget,然后我new一個QImage

  • qImg?=?new?QImage(QSize(img->width,img->height),QImage::Format_RGB888);?
  • 我這里假設iplImg是RGB格式,且每個通道大小為8。然后創建一個IplImage 的文件頭

  • iplImg?=?cvCreateImageHeader(cvSize(img.width(),img.height()),8,3);?
  • 此iplImage和QImage的不同之處在于QImage沒有直接提供創建文件頭的方法,可以通過如下方式創建只有文件頭數據的QImage

  • qImg?=?new?QImage(QSize(0,0),QImage::Format_RGB888);?
  • 另外兩者的圖像矩陣像素排列有點不同,比如IplImage中的BGR到了QImage中應該是RGB,當然單通道的灰度圖是一樣的,值得慶幸的是兩者的像素矩陣都是形狀相同的多維數組。這樣我們可以通過指針共享這部分數據,一種方法如下:

  • iplImg->imageData?=?(char*)qImg.bits();?
  • 將iplImg的圖像矩陣指到qImg那里,以后我們只需要對IplImage運用opencv里面的函數進行處理,其實就直接在處理qImg里面的數據了。但是現在的圖像數據還在img里面,首先得把數據搞到手,然后放到iplImg和qImg的共享區中去,另外將顏色排列以QImage中的RGB順序為標準。

  • if?(img->origin?==?IPL_ORIGIN_TL) ?
  • { ?
  • ?cvCopy(img,iplImg,0); ?
  • } ?
  • else ?
  • { ?
  • ?cvFlip(img,iplImg,0); ?
  • } ?
  • cvCvtColor(iplImg,iplImg,CV_BGR2RGB);?
  • 實際上只要做到這里圖片就能顯示了。如下圖所示

    給出myWidget.cpp完整代碼

  • #include?"myWidget.h" ?
  • #include?<QtGui\QPainter>?
  • #include?<QtCore\QPoint>?
  • ?
  • myWidget::myWidget(const?IplImage?*img,QWidget?*parent?/*?=?0?*/)?:?QWidget(parent) ?
  • { ?
  • ??qImg?=?new?QImage(QSize(img->width,img->height), ?
  • ???QImage::Format_RGB888); ?
  • ?iplImg?=?cvCreateImageHeader(cvSize(img->width,img->height), ?
  • ??8,3); ?
  • ?iplImg->imageData?=?(char*)qImg->bits(); ?
  • ?
  • ?if?(img->origin?==?IPL_ORIGIN_TL) ?
  • ?{ ?
  • ??cvCopy(img,iplImg,0); ?
  • ?} ?
  • ?else ?
  • ?{ ?
  • ??cvFlip(img,iplImg,0); ?
  • ?} ?
  • ?cvCvtColor(iplImg,iplImg,CV_BGR2RGB); ?
  • ?this->resize(img->width,img->height); ?
  • } ?
  • myWidget::~myWidget() ?
  • { ?
  • ?cvReleaseImage(&iplImg); ?
  • ?delete?qImg; ?
  • } ?
  • void?myWidget::paintEvent(QPaintEvent?*e) ?
  • { ?
  • ?QPainter?painter(this); ?
  • ?painter.drawImage(QPoint(0,0),*qImg); ?
  • }?
  • 調用的代碼很簡單:

  • int?main(int?argc,char*?argv[]) ?
  • { ?
  • ?QApplication?app(argc,argv); ?
  • ?
  • ?IplImage?*img?=?cvLoadImage("460.jpg",1); ?
  • ?if?(img) ?
  • ?{ ?
  • ??myWidget?*mw?=?new?myWidget(img); ?
  • ??mw->show(); ?
  • ?} ?
  • ?int?re?=?app.exec(); ?
  • ?cvReleaseImage(&img); ?
  • ?return?re; ?
  • }?
  • 小結:關于詳解?QT 框架中快速應用OpenCV?上篇內容介紹完了




    (3):利用Qt與OpenCV簡單實現攝像頭圖像捕捉

    原文鏈接:http://blog.const.net.cn/a/8763.htm


    為了pro工程文件看起來簡單點,創建一個pri文件,包含opencv相關信息。分別為VS2008、Mingw和Linux設置OpenCV頭文件和庫的路徑。OPENCVPATH_MSVC=D:/Qt/OpenCV-2.1....


    為了pro工程文件看起來簡單點,創建一個 pri 文件,包含 opencv相關信息。

    分別為 VS2008、Mingw和Linux設置OpenCV頭文件和庫的路徑。

    OPENCVPATH_MSVC = D:/Qt/OpenCV-2.1.0-vs2008win32-msvc*{INCLUDEPATH += $${OPENCVPATH_MSVC}/includeCONFIG(debug, debug|release) {LIBS+=-L$${OPENCVPATH_MSVC}/lib/debug -lcxcore210d -lhighgui210d} else {LIBS += -L$${OPENCVPATH_MSVC}/lib/release -lcxcore210 -lhighgui210} }OPENCVPATH_MINGW = D:/Qt/OpenCV-2.1.0-mingw win32-g++{INCLUDEPATH += $${OPENCVPATH_MINGW}/includeLIBS += -L$${OPENCVPATH_MINGW}/lib -lcxcore210 -lhighgui210 }unix:LIBS += -lcv -lhighgui

    讀取類

    創建一個視頻捕捉類,提供start和stop槽來控制攝像頭打開和關閉,通過定時器定時捕捉圖像,并通過信號將圖片傳出。

    //cameradevice.h #ifndef CAMERADEVICE_H #define CAMERADEVICE_H#include <QtCore/QObject>QT_BEGIN_NAMESPACE class QTimer; class QImage; QT_END_NAMESPACEnamespace cv{ class VideoCapture; class Mat; }class CameraDevice : public QObject { Q_OBJECT public: explicit CameraDevice(QObject *parent = 0); ~CameraDevice();signals: void imageReady(const QImage& image);public slots: bool start(); bool stop();private slots: void onTimeout();private: QImage imageFromMat(const cv::Mat& frame); cv::VideoCapture * m_capture; QTimer * m_timer; };#endif // CAMERADEVICE_H //cameradevice.cpp #include <QtCore/QTimer> #include <QtGui/QImage> #include "opencv/cv.h" #include "opencv/highgui.h" #include "cameradevice.h"CameraDevice::CameraDevice(QObject *parent) : QObject(parent) { m_capture = new cv::VideoCapture; m_timer = new QTimer(this); connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeout())); }CameraDevice::~CameraDevice() { delete m_capture; m_capture = NULL; }bool CameraDevice::start() { if (m_capture->isOpened()) { return true; } m_capture->open(CV_CAP_ANY); if (m_capture->isOpened()) { m_timer->start(40); } return m_capture->isOpened(); }bool CameraDevice::stop() { if (m_capture->isOpened()) { m_capture->release(); } return true; }void CameraDevice::onTimeout() { if (!m_capture->isOpened()) { return; } static cv::Mat frame; *m_capture >> frame; if (frame.cols) { emit imageReady(imageFromMat(frame)); } }QImage CameraDevice::imageFromMat(const cv::Mat &frame) { const unsigned char* src = frame.ptr(); QImage image(frame.cols, frame.rows, QImage::Format_RGB32); unsigned char * des = image.bits(); unsigned long count = frame.cols * frame.rows; for (unsigned long i = 0; i < count; ++i) { *des++ = *src++; *des++ = *src++; *des++ = *src++; *des++ = 0xff; } return image; }

    界面類

    對話框類就簡單了,只需要一個 label 來顯示圖像,兩個按鈕來控制開啟與關閉即可

    //dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QtGui/QDialog>namespace Ui { class Dialog; }class CameraDevice;class Dialog : public QDialog { Q_OBJECTpublic: explicit Dialog(QWidget *parent = 0); ~Dialog();private slots: void onImageArrival(const QImage & image);private: Ui::Dialog *ui; CameraDevice * m_camera; };#endif // DIALOG_H[喝小酒的網摘]http://blog.const.net.cn/a/8763.htm //dialog.cpp #include "dialog.h" #include "ui_dialog.h" #include "cameradevice.h"Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog), m_camera(new CameraDevice(this)) { ui->setupUi(this); connect(m_camera, SIGNAL(imageReady(QImage)), this, SLOT(onImageArrival(QImage))); connect(ui->startButton, SIGNAL(clicked()), m_camera, SLOT(start())); connect(ui->stopButton, SIGNAL(clicked()), m_camera, SLOT(stop())); }Dialog::~Dialog() { delete ui; }void Dialog::onImageArrival(const QImage &image) { ui->view->setPixmap(QPixmap::fromImage(image)); }

    主程序

    //main.cpp #include <QtGui/QApplication> #include "dialog.h"int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }

    問題

    用一個定時器來做似乎存在些問題,反復打開關閉,在windows下可發現資源泄漏。不清楚是什么原因。

    簡單調整幾行代碼,改為多線程程序后,該問題似乎消失了。

    • 改動主要在對話框類中:
    #include <QtCore/QThread> #include "dialog.h" #include "ui_dialog.h" #include "cameradevice.h"Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog), m_camera(new CameraDevice) { ui->setupUi(this); QThread * thread = new QThread(this); m_camera->moveToThread(thread); thread->start(); connect(m_camera, SIGNAL(imageReady(QImage)), this, SLOT(onImageArrival(QImage))); connect(ui->startButton, SIGNAL(clicked()), m_camera, SLOT(start())); connect(ui->stopButton, SIGNAL(clicked()), m_camera, SLOT(stop())); }Dialog::~Dialog() { m_camera->deleteLater(); delete ui; }void Dialog::onImageArrival(const QImage &image) { ui->view->setPixmap(QPixmap::fromImage(image)); }

    改為多線程后,可將捕捉類中的定時器的時間設為 0





    (4):QThread的使用方法


    昨天不小心看到Qt開發人員( Bradley T. Hughes)Blog中的一片文章?you are-doing-it-wrong?。 結果看得頭昏腦脹:好歹也自學了近1年的Qt,也一直很小心、很認真地閱讀Qt和manual和例子等資料,卻被突然告知,QThread的正確使用方法 是一種自己從沒見過,而且Qt manual、example、書籍中都沒有提到過的一種方法。到底怎么了...?[喝小酒的網摘]http://blog.const.net.cn/a/8760.htm

    莫非manual、exmaple以及資料中的介紹都是錯的??

    認真看看其他的人的評論,總算理清了一點頭緒。所有事情源于 QThread 的事件循環!


    QThread 的兩種使用方法


    1. 不使用事件循環。這是官方的 Manual 、example 以及相關書籍中都介紹的一種的方法。
    a. 子類化 QThread
    b. 重載 run 函數,run函數內有一個 while 或 for 的死循環
    c. 設置一個標記為來控制死循環的退出。

    2. 使用事件循環。(博客?you are-doing-it-wrong?批駁的就是這種情況下的 一種用法。)

    a. 子類化 QThread,
    b. 重載 run 使其調用 QThread::exec()?
    c. 并為該類定義信號和槽,這樣一來,由于槽函數并不會在新開的 thread 運行,很多人為了解決這個問題在構造函數中調用?moveToThread(this);?

    而爭論和不解正是這樣的一條語句造成的。

    Bradley T. Hughes 給出說明是?QThread 應該被看做是操作系統線程的接口或控制點,而不應該包含需要在新線程中運行的代碼。需要運行的代碼應該放到一個QObject的子類中,然后將該子類的對象moveToThread到新線程中。

    另外:
    在Qt4.3(包括)之前,run 是虛函數,必須子類化QThread來實現run函數。
    而從Qt4.4開始,qthreads-no-longer-abstract??? ,run 默認調用 QThread::exec() 。這樣一來不需要子類化 QThread 了,只需要子類化一個 QObject 就夠了,這正是被 Bradley T. Hughes推薦的方法。


    終于看懂了,但
    不管怎么說,都應該是 QThread 當初的設計導致的這種問題,而所有文檔和例子中都沒有提到該如何使用Qthread 進一步加劇了對QThread的這種誤用。

    相關鏈接:

    http://labs.qt.nokia.com/blogs/2010/06/17/youre-doing-it-wrong/
    http://labs.qt.nokia.com/blogs/2006/12/04/threading-without-the-headache/
    http://labs.qt.nokia.com/blogs/2007/07/05/qthreads-no-longer-abstract/
    http://gitorious.org/qthreadhowto/qthreadhowto/trees/master
    http://blog.exys.org/entries/2010/QThread_affinity.html
    http://thesmithfam.org/blog/2010/02/07/talking-to-qt-threads/[喝小酒的網摘]http://blog.const.net.cn/a/8760.htm



    (5):使用opencv和QT實現攝像頭采集


    在網上收羅了很多資料,QT沒有專門操作攝像頭的類,這個得自己寫。網上也有很多關務openCV和V4l的一些介紹,由于我項目要在window下開發,所以就選擇了openCV。由于以前沒有用過openCV,所以就只看了關于openCVS攝像頭操作的這部分,其他的還沒時間去看。

    openCV :?http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/ ?

    剛開始下載的是2.3.1的,安裝后發現沒有lib庫所以后面選擇了2.1的

    openCV中文學習 pdf ?:

    現在,開始詳細的介紹如何在QT中實時的采集攝像頭數據。

    打開QTcreator (我用的是QT 2.3的 中文版)

    新建一個widget工程


    界面上放兩個label 分別用來顯示攝像頭采集到的數據和照的照片。




    編輯camaraget.h 文件

    [cpp]?view plaincopy? #ifndef CAMARAGET_H #define CAMARAGET_H #include <QWidget> #include <QImage> #include <QTimer> // 設置采集數據的間隔時間 #include <highgui.h> //包含opencv庫頭文件 #include <cv.h> namespace Ui { class camaraGet; } class camaraGet : public QWidget { Q_OBJECT public: explicit camaraGet(QWidget *parent = 0); ~camaraGet(); private slots: void openCamara(); // 打開攝像頭 void readFarme(); // 讀取當前幀信息 void closeCamara(); // 關閉攝像頭。 void takingPictures(); // 拍照 private: Ui::camaraGet *ui; QTimer *timer; QImage *imag; CvCapture *cam;// 視頻獲取結構, 用來作為視頻獲取函數的一個參數 IplImage *frame;//申請IplImage類型指針,就是申請內存空間來存放每一幀圖像 }; #endif // CAMARAGET_H

    編輯 camaraget .cpp

    [cpp]?view plaincopy? #include "camaraget.h" #include "ui_camaraget.h" camaraGet::camaraGet(QWidget *parent) : QWidget(parent), ui(new Ui::camaraGet) { ui->setupUi(this); cam = NULL; timer = new QTimer(this); imag = new QImage(); // 初始化 /*信號和槽*/ connect(timer, SIGNAL(timeout()), this, SLOT(readFarme())); // 時間到,讀取當前攝像頭信息 connect(ui->open, SIGNAL(clicked()), this, SLOT(openCamara())); connect(ui->pic, SIGNAL(clicked()), this, SLOT(takingPictures())); connect(ui->closeCam, SIGNAL(clicked()), this, SLOT(closeCamara())); } /****************************** ********* 打開攝像頭 *********** *******************************/ void camaraGet::openCamara() { cam = cvCreateCameraCapture(0);//打開攝像頭,從攝像頭中獲取視頻 timer->start(33); // 開始計時,超時則發出timeout()信號 } /********************************* ********* 讀取攝像頭信息 *********** **********************************/ void camaraGet::readFarme() { frame = cvQueryFrame(cam);// 從攝像頭中抓取并返回每一幀 // 將抓取到的幀,轉換為QImage格式。QImage::Format_RGB888不同的攝像頭用不同的格式。 QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888); ui->label->setPixmap(QPixmap::fromImage(image)); // 將圖片顯示到label上 } /************************* ********* 拍照 *********** **************************/ void camaraGet::takingPictures() { frame = cvQueryFrame(cam);// 從攝像頭中抓取并返回每一幀 // 將抓取到的幀,轉換為QImage格式。QImage::Format_RGB888不同的攝像頭用不同的格式。 QImage image((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888); ui->label_2->setPixmap(QPixmap::fromImage(image)); // 將圖片顯示到label上 } /******************************* ***關閉攝像頭,釋放資源,必須釋放*** ********************************/ void camaraGet::closeCamara() { timer->stop(); // 停止讀取數據。 cvReleaseCapture(&cam);//釋放內存; } camaraGet::~camaraGet() { delete ui; }
    好了,全部代碼都OK了(當然,創建工程時,會生成main.cpp,不必去改動它),但現在你點運行,依然會產生錯誤,為什么呢?因為還沒有把openCV的庫包含進去。

    在*.pro 文件中 加入:

    INCLUDEPATH+=C:\OpenCV2.1\include\opencv

    LIBS += C:\OpenCV2.1\lib\highgui210.lib \ C:\OpenCV2.1\lib\cxcore210.lib \ C:\OpenCV2.1\lib\cv210.lib OK,大功告成,運行后,在widget中點擊打開攝像頭,就可以看到自己了。運行后的效果:




    后來我發現這個效果不怎么好,就改了一下:改了以后的運行效果也貼出來:


    就改了一句:

    [cpp]?view plaincopy?
  • QImage?image((const?uchar*)frame->imageData,?frame->width,?frame->height,?QImage::Format_RGB888);??
  • [cpp]?view plaincopy?
  • 改為了?QImage?image?=?QImage((const?uchar*)frame->imageData,?frame->width,?frame->height,?QImage::Format_RGB888).rgbSwapped();??



  • (6):求道勿遠,求心勿近 的一個博客:Qt Opencv 在Linux下攝像頭簡單示例v1.0

    ?? 原文鏈接:http://blog.chinaunix.net/uid-24641004-id-3459705.html


    下面寫的文章也許網上也有類似的,但是大多數都沒有給出思路及背景,讓初學者每次都只能學到一點皮毛,不少知識需要大量搜索零碎地拼湊起來。題外話,雖然現在是碎片化信息時代,但正是這樣信息整合能力也顯得非常重要,為讀者提供高質量的文章是我以后的目標。我以后會注意分析應用背景及些過程的解析。

    不想看下面筆者對編譯環境的理解的,可以直接在本頁Ctrl+F查找“編譯過程”看,因為下面有很大段筆者心酸的回憶,嘻嘻。

    資源介紹

    opencv是一個非常優秀的圖形圖像處理類庫,里面的類或者結構體,封裝了很多實用的圖像處理算法,調用其提供的API,等于使用一些復雜的圖像處理算法,真是解放生產力啊。這里筆者用的是linux版本的opencv2.2源碼,幾十M,穩定版本夠用即可,沒必要時刻追著新版本。不過在linux上的opencv各種版本都是如筆者那樣編譯即可用。

    思考一下,為什么我們要下源碼來編譯?不是像windows上的直接發布一個壓縮包即可用么?我們這次編譯為是得到什么?其實很簡單,opencv里有專門處理攝像頭的API,我們要用它,就得有它的頭文件及動態庫(或靜態庫)。而我們拿到源碼往往不是為了去研究其代碼(如果是做這算法方面的研究便是例外了),而是拿到“本地”編譯。至于為何,筆者認為是大家內核版本版本的不統一,編譯器版本也不統一導致這樣做的的。如果使用Ubuntu之類的,很簡單,一個apt-get什么都不用管,因為Ubuntu提供了適應你的內核版本編譯器編譯的庫。知道的同學希望指教一下。

    下載請移步:http://www.opencv.org.cn/index.php/Download

    虛擬機上的攝像頭,一般都是用USB連接,如果是筆記本自帶的,也是把虛擬機里的connect上即可。連接外設的方法:在虛擬機頂欄菜單,VM->Removable?Devices->XX?WebCam->connect??&&?show?in?status?Bar(前者把設備從win環境解除,連接到虛擬機環境,后者是顯示在虛擬機右下角的狀態欄)。

    具體看下圖:

    ???QT,版本其實與opencv版本沒有什么關系,因為代碼編譯出來,最終都是翻譯成機器碼,QT源碼是C++寫的,OPENCV源碼也是C/C++寫的,編譯器認識他們即可。筆者一起也是擔心版本問題,網上的文章往往都是寫著qt4.7.2+opencv2.0XXX,或者qtcreator2.0+opencv2.3.1在Ubuntu11上編譯成功之類的文章,我那時就很擔心,又要確定QT版本,又要確定opencv版本,還得確定linux版本嗎?linux怎么那么復雜啊?就是他們的標題及其內容都沒有明確指出他們方法的通用性。筆者在這里就說明一下:這文章在linux上的適用,QT版本(4.6,4.7,5.0等無論什么版本都可以,whatever),opencv版本(1.0,2.0,2.2,2.3,2.4,whatever都可以),linux(各種發行版本(內核是2.6以上的),只要別用2.4的內核就好。)

    編譯過程:

    攝像頭在虛擬機上(當然,從物理上說你還是得有攝像頭才行)安裝上面的圖看一下即可。下面主要是opencv的編譯:主要參考opencv中文論壇的文章

  • ./configure//頭文件和庫文件一般都是默認安裝到/usr/local/include/usr/local/lib內

  • make

  • make install
  • 具體代碼:

    先講最終要實現什么,很簡單,一個窗口,里面有一個label顯示攝像頭的圖像。

    然后講講原理:每隔一段時間我們就去攝像頭抓取一幀圖像,然后放到ui->label上面,如果取的時間快,就造成“視頻”的感覺了。(可以想到,其實攝像頭拍照也是很簡單,我們就把其中一幀取出來即可。)

    新建一個工程,繼承QDialog(用什么窗體都可以),在UI上拖出一個label放在中間,

    拉到適當大小。

    在工程xxx.pro里面添加必要的庫及頭文件的路徑:


    ?

    INCLUDEPATH +=/usr/local/include/opencvLIBS +=/usr/local/lib/libcv.so\/usr/local/lib/libhighgui.so\/usr/local/lib/libcxcore.so\//dialog.h#ifndef DIALOG_H#define DIALOG_H#include <QDialog>#include <cv.h>#include <highgui.h>#include <QTimer>#include <QPixmap>namespace Ui {class Dialog;}class Dialog :public QDialog{Q_OBJECTpublic:explicit Dialog(QWidget*parent= 0);~Dialog();private:Ui::Dialog*ui;CvCapture *capture;//highgui 里提供的一個專門處理攝像頭圖像的結構體IplImage *frame;//攝像頭每次抓取的圖像為一幀,使用該指針指向一幀圖像的內存空間QTimer *timer;//定時器用于定時取幀,上面說的隔一段時間就去取就是用這個實現。private slots:void getFrame();//實現定時從攝像頭取圖并顯示在label上的功能。};#endif // DIALOG_H//dialog.cpp#include "dialog.h"#include "ui_dialog.h"#include <QDebug>Dialog::Dialog(QWidget*parent):QDialog(parent),ui(new Ui::Dialog){ui->setupUi(this);timer = new QTimer(this);capture = cvCaptureFromCAM(0);//cvCaptureFromCAM其實是一個宏,就是cvCreateCameraCapture的別名,0代表第一個攝像頭。-1代表默認攝像頭。if(capture==NULL){qDebug()<<"error!";}timer->start(50);//1000為1秒,50毫秒去取一幀connect(timer,SIGNAL(timeout()),this,SLOT(getFrame()));//超時就去取}void Dialog::getFrame(){frame = cvQueryFrame(capture);//從攝像頭取幀QImage image = QImage((const uchar*)frame->imageData, frame->width, frame->height, QImage::Format_RGB888).rgbSwapped();//簡單地轉換一下為Image對象,rgbSwapped是為了顯示效果色彩好一些。ui->label->setPixmap(QPixmap::fromImage(image));}Dialog::~Dialog(){timer->stop();//停止取幀cvReleaseCapture(&capture);//釋放資源是個好習慣delete ui;}

    本文參考資料:

    源碼編譯:

    http://www.opencv.org.cn/index.php/%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91

    QT中使用OPENCV庫

    http://www.opencv.org.cn/index.php/%E5%9C%A8Qt%E4%B8%AD%E4%BD%BF%E7%94%A8OpenCV%E5%BA%93

    Debian/Ubuntu

    http://www.opencv.org.cn/index.php/Debian%E4%B8%8B%E5%AE%89%E8%A3%85



    總結

    以上是生活随笔為你收集整理的QT与openCV,与PCL结合!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。