QT 利用opencv获取显示视频流预览

在QT中,如果我们想做一些关于读取摄像头视频里显示的操作,可以使用opencv非常方便的读取视频流,还可以对读取的帧数据进行一些特殊的处理,例如:灰白显示,边缘显示等等。下面是一个非常基础的使用opencv的demo

头文件:

#ifndef WIDGET_H
#define WIDGET_H

#include 

#include "opencv2/opencv.hpp"
#include "opencv2/highgui.hpp"
#include 
#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();

public slots:
    void readFarme();

private:
    Ui::Widget *ui;

    QTimer    *timer;
    cv::Mat _srcImge;
    cv::VideoCapture *_videocap;

    QImage cvMat2QImage(const cv::Mat& mat);
};

#endif // WIDGET_H

 源文件:

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    timer   = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(readFarme()));
    //_videocap = new cv::VideoCapture("http://192.168.31.166:8080/?action=stream?dummy=param.mjpg");//从网络数据流中获取
    _videocap = new cv::VideoCapture(0);// 读取/dev/video0获取

    timer->start(33);
}
QImage Widget::cvMat2QImage(const cv::Mat& mat)    // Mat 改成 QImage
{
    if (mat.type() == CV_8UC1) {// 单通道
        QImage image(mat.cols, mat.rows, QImage::Format_Indexed8);
        image.setColorCount(256);// 灰度级数256
        for (int i = 0; i < 256; i++) {
            image.setColor(i, qRgb(i, i, i));
        }
        uchar *pSrc = mat.data;// 复制mat数据
        for (int row = 0; row < mat.rows; row++) {
            uchar *pDest = image.scanLine(row);
            memcpy(pDest, pSrc, mat.cols);
            pSrc += mat.step;
        }
        return image;
    } else if (mat.type() == CV_8UC3) {// 3通道
        const uchar *pSrc = (const uchar*)mat.data;         // 复制像素
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);// R, G, B 对应 0,1,2
        return image.rgbSwapped();              // rgbSwapped是为了显示效果色彩好一些。
    } else if (mat.type() == CV_8UC4) {
        const uchar *pSrc = (const uchar*)mat.data;         // 复制像素
                                                            // Create QImage with same dimensions as input Mat
        QImage image(pSrc, mat.cols, mat.rows, mat.step, QImage::Format_ARGB32);// B,G,R,A 对应 0,1,2,3
        return image.copy();
    } else {
        return QImage();
    }
}

void Widget::readFarme()
{
//此处的两种方法获取显示视频流都是正确的,最好使用第二种
#if 0
    _videocap->read(_srcImge);//获取到一帧
    QImage imgg = cvMat2QImage(_srcImge);//自定义转换函数,麻烦
    QPixmap qpixmap = QPixmap::fromImage(imgg);
    ui->label->setPixmap(qpixmap);
#else
    _videocap->read(_srcImge);//获取到一帧
    cvtColor(_srcImge,_srcImge,CV_BGR2RGB);//这种更方便好用
    QImage image2=QImage((const unsigned char*)_srcImge.data,_srcImge.cols,_srcImge.rows,QImage::Format_RGB888);
    ui->label->setPixmap(QPixmap::fromImage(image2));
#endif
}


Widget::~Widget()
{
    delete ui;
}

 pro文件中添加opencv的库和头文件路径:

INCLUDEPATH += /usr/local/include
LIBS += -L/usr/local/lib -lopencv_core \
    -lopencv_imgproc -lopencv_imgcodecs -lopencv_highgui -lopencv_videoio

 

你可能感兴趣的:(QT,raspberrypi,qt,opencv,获取视频流,qt读取摄像头)