Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo

Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo📹

文章目录

更多精彩内容👉
个人内容分类汇总

👈

1、准备工作🎥

  • 看这里,下载官方编译的版本就可以了;

2、说明📺

  • 我写这个Demo的环境,但这个Demo不只局限于这个环境
  • 系统:Windows10
  • Qt版本:V5.12.5
  • OpenCV:opencv-4.6.0-vc14_vc15.exe(注意如果自己编译则要包含ffmpeg,否则部分功能不能使用)
  • 编译器:MSVC2017-64
  • Demo功能描述
  • 启动时获取所有可用摄像头名称;
  • 支持使用opencv打开本地摄像头,读取视频并显示;
  • 由于opencv包含ffmpeg,所以支持打开多种格式的本地视频文件并显示;
  • 支持打开多种协议的网络视频流并显示;
  • 支持传入显示QImage、QPixmap图片进行显示;
  • 支持图片的自适应窗口缩放,并保持纵横比。

3、关键代码🔍

  • VideoPlay.pro
opencv需要带有ffmpeg才可以打开本地视频或者网络视频流,否则只能打开图片和摄像头
win32:CONFIG(release, debug|release): LIBS += -LE:/lib/opencv_MSVC2/build/x64/vc15/lib/ -lopencv_world460
else:win32:CONFIG(debug, debug|release): LIBS += -LE:/lib/opencv_MSVC2/build/x64/vc15/lib/ -lopencv_world460d
INCLUDEPATH += E:/lib/opencv_MSVC2/build/include
DEPENDPATH += E:/lib/opencv_MSVC2/build/include
  • videodisplay.h
#ifndef VIDEODISPLAY_H
#define VIDEODISPLAY_H

#include
#include

using namespace cv;

namespace Ui {
class VideoDisplay;
}

class VideoDisplay : public QWidget
{
    Q_OBJECT

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

signals:
    void updateImage(QImage img);

private slots:
    void on_but_open_clicked();
    void readImage();
    void quitThread();
    QImage MatToQImage(const Mat& mat);

    void on_but_play_clicked();

    void on_but_file_clicked();

private:
    Ui::VideoDisplay *ui;

    VideoCapture* m_cap = nullptr;
    Mat mat;
    bool m_play = false;
};

#endif

  • videodisplay.cpp
#include "videodisplay.h"
#include "ui_videodisplay.h"
#include
#include
#include

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

    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    for(auto camera : cameras)
    {
        ui->com_cameras->addItem(camera.description());
    }

    m_cap = new VideoCapture();
    connect(this, &VideoDisplay::updateImage, ui->playImage, &PlayImage::updateImage);
}

VideoDisplay::~VideoDisplay()
{

    if(m_cap)
    {
        if(m_cap->isOpened())
        {
            quitThread();
        }
        delete m_cap;
    }
    delete ui;
}

void VideoDisplay::on_but_open_clicked()
{
    if(!m_cap->isOpened())
    {
        if(ui->com_cameras->count()  0) return;

        bool ret = m_cap->open(ui->com_cameras->currentIndex());
        if(ret)
        {
            m_play = true;
            ui->but_open->setText("关闭摄像头");
            QtConcurrent::run(this, &VideoDisplay::readImage);
        }
    }
    else
    {
        quitThread();
        m_cap->release();
        ui->but_open->setText("打开摄像头");
    }
}

void VideoDisplay::on_but_play_clicked()
{
    if(!m_cap->isOpened())
    {
        QString url = ui->line_url->text();
        if(url.isEmpty()) return;
        bool ret = m_cap->open(url.toStdString());
        if(ret)
        {
            m_play = true;
            ui->but_play->setText("停止播放");
            QtConcurrent::run(this, &VideoDisplay::readImage);
        }
    }
    else
    {
        quitThread();
        m_cap->release();
        ui->but_play->setText("开始播放");
    }
}

void VideoDisplay::on_but_file_clicked()
{
    QString str = QFileDialog::getOpenFileName(this, "视频文件", "./", "视频文件(*)");
    if(str.isNull()) return;

    ui->line_url->setText(str);
}

void VideoDisplay::quitThread()
{
    m_play = false;
    while (!m_play) {
        QThread::msleep(1);
    }
    m_play = false;
}

void VideoDisplay::readImage()
{
    while (m_play && m_cap->isOpened())
    {
        bool ret = m_cap->read(mat);
        if(ret)
        {
            emit this->updateImage(MatToQImage(mat));
        }

        QThread::msleep(1);
    }
    m_play = true;
}

QImage VideoDisplay::MatToQImage(const Mat &mat)
{
    switch (mat.type())
    {
    case CV_8UC1:
        {
            QImage img(mat.data, mat.cols, mat.rows, mat.cols, QImage::Format_Grayscale8);
            return img;
        }
    case CV_8UC3:
        {
            QImage img(mat.data, mat.cols, mat.rows, mat.cols * 3, QImage::Format_RGB888);
            return img.rgbSwapped();
        }
    case CV_8UC4:
        {
            QImage img(mat.data, mat.cols, mat.rows, mat.cols * 4, QImage::Format_ARGB32);
            return img;
        }
    default:
        {
            return QImage();
        }
    }
}

4、注意事项🔎

  • 如果opencv没有配置环境变量,则这个程序编译后无法运行;
  • 需要将opencv存放路径 E:\lib\OpenCV_MSVC2\build\x64\vc15\bin路径下的 opencv_videoio_ffmpeg460_64.dllopencv_videoio_msmf460_64.dllopencv_world460.dll三个文件拷贝到编译生成的可执行文件路径下;
  • 注意: 低版本的opencv没有 opencv_videoio_msmf460_64.dll这个文件。

5、实现效果

Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo

; 6、完整源代码💻

💡💡💡💡💡💡💡💡💡💡💡💡💡💡

Original: https://blog.csdn.net/qq_43627907/article/details/125668164
Author: mahuifa
Title: Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/636924/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球