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.dll
、opencv_videoio_msmf460_64.dll
、opencv_world460.dll
三个文件拷贝到编译生成的可执行文件路径下; - 注意: 低版本的opencv没有
opencv_videoio_msmf460_64.dll
这个文件。
5、实现效果
; 6、完整源代码💻
💡💡💡💡💡💡💡💡💡💡💡💡💡💡
Original: https://blog.csdn.net/qq_43627907/article/details/125668164
Author: mahuifa
Title: Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/636924/
转载文章受原作者版权保护。转载请注明原作者出处!