PyQt5实现视频流的输出

        视频流输入可以利用cv2包读取,读取获得的是ret和frame,ret是一个布尔值(bool),frame是视频流的某一帧,所以最大我的问题就是建造一个Qwidget,在里面放入一个容器用来显示frame。

        首先使用Qwidget建造一个窗口,然后在里面放上一个QLabel,用cv2读取得到图片frame之后,将frame放在QLabel上面,并进行循环,就可以将图片连贯成视频。

        Qwidget的生成可以用Qtdesigner,在terminal输入pyqt5-tools.exe designer即可使用;或者手动定义一个类,后者具有较强的可操作性,前者具有较强的可视性,我推荐小项目自己手敲,较为复杂的界面使用Qtdesigner。

        cv2通过摄像头IP地址即可连接摄像头,笔记本电脑本地摄像头一般设为0,在读取之后会返回bool值和实时视频帧的信息,我们只需要将视频帧显示在QLabel上面即可。

        所以可以分为三个阶段:窗口绘制阶段,图片获得阶段,图片显示阶段。

        在窗口绘制阶段,使用initui方法,先将整体白板窗口放出来,再向上面添加布局,布局包括顶层的选项框、中间的按钮、以及两个空白label控件。

        在图片获得阶段,点击开启摄像头会将本地摄像头打开,获取bool值和实时视频帧,传输到计算机当中。

        在图片显示阶段,cv2读取的BGR格式的图片会被转码成RGB图片,并变成QImage的格式,再由Qt自带的QPixmap中的setPixmap对其进行绘制,显示在QLabel上面。后期会加入对关键帧的提取。

        代码如下:

        有问题可以私信问我,随时在线。

        


# -*- coding: utf-8 -*-
"""
@author:xiaoyangchicao2020
@time:2022-99-99
"""
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import cv2

class Example(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()  # 界面绘制交给InitUi方法

    def initUI(self):

        lb1 = QLabel(self)
        lb1.setGeometry(0, 0, 1280, 800)
        # lb1.setStyleSheet("border: 2px solid red")

        # 设置窗口的位置和大小
        self.setGeometry(300, 100, 700, 450)
        # 设置窗口的标题
        self.setWindowTitle('current window')

        # 显示窗口
        self.show()

class ListViewDemo(QMainWindow):
    def __init__(self, parent=None):
        super(ListViewDemo, self).__init__(parent)
        self.imgName = []
        self.resize(500, 300)
        HLayout = QHBoxLayout()
        VLayout = QVBoxLayout()
        self.lab1 = QLabel()
        self.lab2 = QLabel()
        #self.lab1.setPixmap(QPixmap(r'C:\Users\MI\Desktop\CJ.png'))
        HLayout.addWidget(self.lab1)
        HLayout.addWidget(self.lab2)
        self.listView = QListView()
        self.listView.setContextMenuPolicy(Qt.CustomContextMenu)  # 右键菜单
        self.listView.customContextMenuRequested[QtCore.QPoint].connect(self.rightMenuShow)

      
        self.btnOK = QPushButton("开启摄像头")
        self.checkBox1.setChecked(False)
        self.checkBox1.stateChanged.connect(lambda: self.btnstate(self.checkBox1))

        VLayout.addWidget(self.btnOK)
        VLayout.addWidget(self.selectbtn)
        VLayout.addWidget(self.saveimagbtn)
        #VLayout.addWidget(groupBox)
        VLayout.addWidget(self.listView)

        bar = self.menuBar()
        file = bar.addMenu("Start")
        edit = bar.addMenu("About")
        file.addAction("Open")
        file.addAction("Edit")
        file.addAction("Quit")
        self.listView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listView.customContextMenuRequested[QtCore.QPoint].connect(self.rightMenuShow)

        self.statusBar = QStatusBar()
        self.setStatusBar(self.statusBar)
        HLayout.addLayout(VLayout)
        main_frame = QWidget()
        main_frame.setLayout(HLayout)

        self.setWindowTitle('监控运行')
        self.selectbtn.clicked.connect(self.openimage)
        self.listView.doubleClicked.connect(self.clicked)
        self.listView.clicked.connect(self.clicked)
        self.btnOK.clicked.connect(self.camera)
        self.setCentralWidget(main_frame)

    def rightMenuShow(self):
        rightMenu = QtWidgets.QMenu(self.listView)
        removeAction = QtWidgets.QAction(u"Delete", self,
                                         triggered=self.removeimage)  # triggered 为右键菜单点击后的激活事件。这里slef.close调用的是系统自带的关闭事件。
        rightMenu.addAction(removeAction)
        rightMenu.exec_(QtGui.QCursor.pos())

    def processTrigger(self, q):
        if (q.text() == "show"):
            self.statusBar.showMessage(q.text() + " 菜单选项被点击了", 5000)

    def btnstate(self, btn):
        chk1Status = self.checkBox1.isChecked()
        print(chk1Status)
        if chk1Status:
            QMessageBox.information(self, "Tips", "是", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        else:
            QMessageBox.information(self, "Tips", "否")

    def clicked(self, qModelIndex):
        #QMessageBox.information(self, "QListView", "你选择了: "+ imgName[qModelIndex.row()])
        global path
        self.lab1.setPixmap(QPixmap(imgName[qModelIndex.row()]))
        path = imgName[qModelIndex.row()]

    def openimage(self):
        global imgName
        imgName, imgType = QtWidgets.QFileDialog.getOpenFileNames(self, "多文件选择", "/", "所有文件 (*);;文本文件 (*.txt)")
        slm = QStringListModel()
        slm.setStringList(imgName)
        self.listView.setModel(slm)

    def removeimage(self):
        selected = self.listView.selectedIndexes()
        itemmodel = self.listView.model()
        for i in selected:
            itemmodel.removeRow(i.row())

    def processimage(self):
        QMessageBox.information(self, "Tips", "Done!")

    def camera(self):

        # 打开USB摄像头
        cap = cv2.VideoCapture(0)

        #如果有其他摄像头的话
        # 摄像头的IP地址,http://用户名:密码@IP地址:端口/
        '''camera_url_ip = 'http://admin:admin@192.168.1.101:8081/'
        # 创建一个VideoCapture
        cap = cv2.VideoCapture(camera_url_ip)'''

        print('IP摄像头是否开启: {}'.format(cap.isOpened()))

        # 显示缓存数
        print(cap.get(cv2.CAP_PROP_BUFFERSIZE))
        # 设置缓存区的大小
        cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

        # 调节摄像头分辨率
        #cap.set(cv2.CAP_PROP_FRAME_WIDTH, w)
        #cap.set(cv2.CAP_PROP_FRAME_HEIGHT, h)
        print('width:', cap.get(cv2.CAP_PROP_FRAME_WIDTH))
        print('height:', cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

        # 设置FPS
        fps = 30
        print('FPS值为:', cap.set(cv2.CAP_PROP_FPS, fps))
        print(cap.get(cv2.CAP_PROP_FPS))
        self.c=1
        #framedata = 1
        #ex=Example()
        # codec = cv2.VideoWriter_fourcc(*'MJPG')
        # out = cv2.VideoWriter
        while (True):
            ret, self.frame = cap.read()
            cv2.waitKey(0)
            # gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            self.frame = cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR)
            self.img = QImage(self.frame.data, self.frame.shape[1], self.frame.shape[0], QImage.Format_RGB888)
            self.lab2.setPixmap(QPixmap(self.img))

        # 当一切结束后,释放VideoCapture对象
        cap.release()
        cv2.destroyAllWindows()




if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = ListViewDemo()
    win.show()
    sys.exit(app.exec_())

        最近学到了新的方法,不需要像我这样将部件一个个往上添加了,只需要先GUI编程托拉拽,再转码生成py文件,作为一个包直接导入,使用其中已经定义好的继承过来的新类即可。详细请看我的文章有写。

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyQt5是一个流行的Python GUI库,可用于开发跨平台的图形用户界面。在PyQt5中,可以使用QLabel类来显示图像和文本,并支持媒体文件的播放。如果想在PyQt5的QLabel中播放本地视频,则需要使用QMediaPlayer类和QVideoWidget类。 首先,在PyQt5中创建一个QLabel对象。然后,在QLabel对象中创建一个QVideoWidget对象,并将其设置为QLabel的子组件。接下来,创建一个QMediaPlayer对象,并将其与QVideoWidget对象连接起来。最后,将本地视频文件的路径传递给QMediaPlayer对象,并调用play()方法来启动视频播放。 下面是一段示例代码,演示如何在PyQt5实现在QLabel中播放本地视频: ```python from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout from PyQt5.QtMultimedia import QMediaPlayer, QVideoWidget from PyQt5.QtCore import QUrl class VideoPlayer(QWidget): def __init__(self): super().__init__() self.setWindowTitle('Video Player') self.setGeometry(100, 100, 720, 480) # 创建QLabel对象 self.label = QLabel(self) # 创建QVideoWidget对象并将其设置为QLabel的子组件 self.video_widget = QVideoWidget(self.label) self.video_widget.setGeometry(0, 0, 720, 480) # 创建QMediaPlayer对象,并将其与QVideoWidget对象连接起来 self.media_player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.media_player.setVideoOutput(self.video_widget) # 将本地视频文件的路径传递给QMediaPlayer对象 video_path = 'video.mp4' self.media_player.setMedia(QUrl.fromLocalFile(video_path)) # 启动视频播放 self.media_player.play() # 将QLabel对象添加到窗口中 layout = QVBoxLayout() layout.addWidget(self.label) self.setLayout(layout) if __name__ == '__main__': app = QApplication([]) player = VideoPlayer() player.show() app.exec_() ``` 这段代码创建了一个名为“Video Player”的窗口,并在其中播放了“video.mp4”文件。在该示例中,QLabel对象为窗口的主要部分,并且QVideoWidget对象作为QLabel的子组件用于显示视频内容。通过将QMediaPlayer对象连接到QVideoWidget对象的输出中,实现了本地视频文件的播放。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

♡小羊不吃草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值