Linux环境下Qt+Opencv的视频采集


今天看MSP430看得有点烦,于是决定把好久以前没有完成的一个任务搞定---Linux环境下Qt+Opencv的视频采集,折腾了一个下午才搞定,吃了晚饭回来总算是搞定了其相应的代码如下:

#include <QWidget>
#include <QVBoxLayout>
#include "QOpenCVWidget.h"
#include <cv.h>
#include <highgui.h>
class MyCameraWindow : public QWidget
{
    Q_OBJECT
    private:
        QOpenCVWidget *cvwidget;
        CvCapture *camera;
        
    public:
        MyCameraWindow(CvCapture *cam, QWidget *parent=0);
         
    protected:
        void timerEvent(QTimerEvent*);        
};
#endif /*MYCAMERAWINDOW_H_*/

 

#include "MyCameraWindow.h"
MyCameraWindow::MyCameraWindow(CvCapture *cam, QWidget *parent) : QWidget(parent) {
    camera = cam;
    QVBoxLayout *layout = new QVBoxLayout;
    cvwidget = new QOpenCVWidget(this);
    layout->addWidget(cvwidget);
    setLayout(layout);
    resize(500, 400);
    startTimer(100);  // 0.1-second timer
 }
void MyCameraWindow::timerEvent(QTimerEvent*) {
    IplImage *image=cvQueryFrame(camera);
    cvwidget->putImage(image);
}
 
#ifndef QOPENCVWIDGET_H
#define QOPENCVWIDGET_H
#include <cv.h>
#include <QPixmap>
#include <QLabel>
#include <QWidget>
#include <QVBoxLayout>
#include <QImage>
class QOpenCVWidget : public QWidget {
    private:
        QLabel *imagelabel;
        QVBoxLayout *layout;
        
        QImage image;
        
    public:
        QOpenCVWidget(QWidget *parent = 0);
        ~QOpenCVWidget(void);
        void putImage(IplImage *);
        IplImage *cvimage_ford;
}; 
#endif

 

#include "QOpenCVWidget.h"
// Constructor
QOpenCVWidget::QOpenCVWidget(QWidget *parent) : QWidget(parent) {
    layout = new QVBoxLayout;
    imagelabel = new QLabel;
    QImage dummy(200,200,QImage::Format_RGB32);
    image = dummy;
    layout->addWidget(imagelabel);
    for (int x = 0; x < 100; x ++) {
        for (int y =0; y < 100; y++) {
            image.setPixel(x,y,qRgb(x, y, y));
        }
    }
    imagelabel->setPixmap(QPixmap::fromImage(image));
    setLayout(layout);
}
QOpenCVWidget::~QOpenCVWidget(void) {
    
}
void QOpenCVWidget::putImage(IplImage *cvimage) {
    int cvIndex, cvLineStart;
    cvimage_ford=cvimage;
    // switch between bit depths
    switch (cvimage->depth) {
        case IPL_DEPTH_8U:
            switch (cvimage->nChannels) {
                case 3:
                    if ( (cvimage->width != image.width()) || (cvimage->height != image.height()) ) {
                        QImage temp(cvimage->width, cvimage->height, QImage::Format_RGB32);
                        image = temp;
                    }
                    cvIndex = 0; cvLineStart = 0;
                    for (int y = cvimage->height; y > 0; y--) {
                        unsigned char red,green,blue;
                        cvIndex = cvLineStart;
                        for (int x =cvimage->width; x > 0 ; x--) {
                            // DO it
                            if (cvimage_ford->imageData[cvIndex+2]>cvimage->imageData[cvIndex+2])
                                red = cvimage_ford->imageData[cvIndex+2]-cvimage->imageData[cvIndex+2];
                            else
                                 red =cvimage->imageData[cvIndex+2] - cvimage_ford->imageData[cvIndex+2];
                            if (green = cvimage_ford->imageData[cvIndex+1]>cvimage->imageData[cvIndex+1])
                                green = cvimage_ford->imageData[cvIndex+1]-cvimage->imageData[cvIndex+1];
                            else
                                 green = (cvimage_ford->imageData[cvIndex+1]-cvimage->imageData[cvIndex+1])*(-1);
                            if ( blue =cvimage_ford->imageData[cvIndex+0]>cvimage->imageData[cvIndex+0])
                                blue =cvimage_ford->imageData[cvIndex+0]- cvimage->imageData[cvIndex+0];
                            else
                                 blue =-1*(cvimage_ford->imageData[cvIndex+0]- cvimage->imageData[cvIndex+0]);
                            
                            image.setPixel(x,y,qRgb(red, green, blue));
                            cvIndex += 3;
                        }
                        cvLineStart += cvimage->widthStep;                        
                    }
                    break;
                default:
//#printf("This number of channels is not supported\n");
                    break;
            }
            break;
        default:
            //printf("This type of IplImage is not implemented in QOpenCVWidget\n");
            break;
    }
    imagelabel->setPixmap(QPixmap::fromImage(image));    
}
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <assert.h>
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include "QOpenCVWidget.h"
#include "MyCameraWindow.h"
int main(int argc, char **argv) {
    CvCapture * camera = cvCreateCameraCapture(0);
    assert(camera);
    IplImage * image=cvQueryFrame(camera);
    assert(image);
    printf("Image depth=%i\n", image->depth);
    printf("Image nChannels=%i\n", image->nChannels);
    QApplication app(argc, argv);
    MyCameraWindow *mainWin = new MyCameraWindow(camera);
    mainWin->setWindowTitle("OpenCV --> QtImage");
    mainWin->show();
    int retval = app.exec();
    cvReleaseCapture(&camera);
    return retval;
}
对于其中的一些难点在此给出讲解吧,尤其是编译的时候可能会出现很多的问题。可以参看 与 。

相关内容