我是靠谱客的博主 心灵美小蘑菇,这篇文章主要介绍Qt+OpenCV读取摄像头视频、本地视频、网络视频流DemoQt+OpenCV读取摄像头视频、本地视频、网络视频流Demo????,现在分享给大家,希望可以做个参考。
Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo????
文章目录
- Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo????
- @[toc]
- 1、准备工作????
- 2、说明????
- 3、关键代码????
- 4、注意事项????
- 5、实现效果
- 6、完整源代码????
文章目录
- Qt+OpenCV读取摄像头视频、本地视频、网络视频流Demo????
- @[toc]
- 1、准备工作????
- 2、说明????
- 3、关键代码????
- 4、注意事项????
- 5、实现效果
- 6、完整源代码????
更多精彩内容 |
---|
????个人内容分类汇总 ???? |
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
复制代码
1
2
3
4
5
6# 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
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#ifndef VIDEODISPLAY_H #define VIDEODISPLAY_H #include <QWidget> #include <opencv2/opencv.hpp> 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_H
- videodisplay.cpp
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159#include "videodisplay.h" #include "ui_videodisplay.h" #include <QtConcurrent> #include <QCameraInfo> #include <QFileDialog> 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; } /** * @brief 打开关闭摄像头 */ 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("打开摄像头"); } } /** * @brief 打开本地视频或者网络视流,如rtsp、rtmp */ 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); } /** * @brief 退出opencv读取线程 * 在一个线程打开关闭m_cap,在另一个线程异步读取需要先退出线程再关闭m_cap,否则可能导致m_cap关闭后又读取导致报错 */ void VideoDisplay::quitThread() { m_play = false; while (!m_play) { QThread::msleep(1); // 等待线程退出 } m_play = false; } /** * @brief 在线程中使用opencv读取图像 */ void VideoDisplay::readImage() { while (m_play && m_cap->isOpened()) { bool ret = m_cap->read(mat); if(ret) { emit this->updateImage(MatToQImage(mat)); // 将mat转换为Qimage并发送给显示界面 } QThread::msleep(1); // 防止频繁读取或者读取不到 } m_play = true; } /** * @brief Mat转QImage * @param mat * @return */ 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:libOpenCV_MSVC2buildx64vc15bin
路径下的opencv_videoio_ffmpeg460_64.dll
、opencv_videoio_msmf460_64.dll
、opencv_world460.dll
三个文件拷贝到编译生成的可执行文件路径下; - 注意: 低版本的opencv没有
opencv_videoio_msmf460_64.dll
这个文件。
5、实现效果
6、完整源代码????
- gitee
- github
????????????????????????????????????????????????????????
最后
以上就是心灵美小蘑菇最近收集整理的关于Qt+OpenCV读取摄像头视频、本地视频、网络视频流DemoQt+OpenCV读取摄像头视频、本地视频、网络视频流Demo????的全部内容,更多相关Qt+OpenCV读取摄像头视频、本地视频、网络视频流DemoQt+OpenCV读取摄像头视频、本地视频、网络视频流Demo内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复