PyQt界面里如何加载本地视频以及调用摄像头实时检测(小白入门必看)

news2025/1/18 3:46:57

目录

1.PyQt介绍

2.代码实现

 2.1实时调用摄像头

2.2 使用YOLOv5推理

2.3 代码中用到的主要函数 


1.PyQt介绍

PyQt是一个用于创建桌面应用程序的Python绑定库,它基于Qt框架。Qt是一个跨平台的C++应用程序开发框架,提供了丰富的图形界面、网络通信、数据库操作等功能。PyQt通过将Qt框架与Python语言结合起来,使得开发者可以使用Python语言来快速、简便地创建功能强大的桌面应用程序。

以下是PyQt的一些主要特点和功能:

  1. 跨平台支持:PyQt可以在多个主要操作系统(如Windows、Linux和macOS)上运行,实现了跨平台的应用程序开发。这意味着你可以使用相同的代码来创建适用于不同操作系统的应用程序。

  2. 丰富的GUI库:PyQt提供了包括窗口、对话框、按钮、文本输入框、表格、树形视图、绘图等在内的丰富的图形用户界面组件。这些组件使开发者能够创建出具有吸引力和交互性的用户界面。

  3. 事件驱动编程:PyQt采用了事件驱动的编程模型。开发者可以通过响应用户的输入、鼠标点击、键盘事件等来触发特定的代码逻辑。这种模型使得应用程序能够高效地处理用户交互。

  4. 信号与槽机制:PyQt支持Qt的信号与槽机制,这是一种强大的机制,用于在对象之间进行通信和交互。通过信号与槽机制,开发者可以将不同对象的动作、事件等连接起来,实现灵活而高效的编程。

  5. 数据库集成:PyQt提供了对常见数据库的支持,包括SQLite、MySQL和PostgreSQL等。开发者可以使用PyQt的数据库模块来执行数据库查询、增删改操作,并将数据库与应用程序进行集成。

  6. 支持多线程:PyQt提供了对多线程的支持,可以在应用程序中处理并发任务,提高程序的响应性能。

2.代码实现

安装PyQt

pip install PyQt

 2.1实时调用摄像头

程序中主要包含两个类:VideoProcessingThreadMainWindow

VideoProcessingThread类是一个继承自QThread的线程类,用于在后台处理视频流。在run方法中,打开摄像头并循环读取视频帧。对每一帧进行处理,包括计算帧率、调整图像大小,并通过信号update_frame发送给主窗口进行更新显示。通过stop方法可以停止线程的运行。

MainWindow类是主窗口类,继承自QMainWindow。在init_ui方法中初始化界面,包括添加开始和停止按钮以及结果显示的标签。start_video_processing方法用于点击开始按钮时创建并启动VideoProcessingThread线程。stop_video_processing方法用于点击停止按钮时停止线程的运行。update_frame方法接收到新的帧后,将其转换为QImage格式,并在标签上进行显示。在关闭窗口时,会调用closeEvent方法停止线程的运行。

在主程序中,创建一个QApplication实例,并实例化MainWindow类作为主窗口。最后调用app.exec_()启动应用程序的事件循环。

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal


import utlis
from ours import *

import cv2
import time

class VideoProcessingThread(QThread):
    update_frame = pyqtSignal(object)

    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url
        self.running = False

    def run(self):
        self.running = True

        cap= cv2.VideoCapture(0)
        pTime = 0
        while True:
            # n_stamp, img = HIK.read()
            success, img2 = cap.read()

            cTime = time.time()
            fps = 1 / (cTime - pTime)
            pTime = cTime
            cv2.putText(img2, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
            img2 = cv2.resize(img2,(480,360))
            # 在窗口中显示目标检测结果
            # cv2.imshow('result', img2)
            self.update_frame.emit(img2)
            # 等待用户按键,如果按下 'q' 键或者 Esc 键,则退出循环
            c = cv2.waitKey(1) & 0xFF
            if c == 27 or c == ord('q'):
                break
        cap.release()


    def stop(self):
        self.running = False

class MainWindow(QMainWindow):
    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url

        self.video_thread = None
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Video Processing')

        start_button = QPushButton('Start', self)
        start_button.setGeometry(10, 10, 100, 30)
        start_button.clicked.connect(self.start_video_processing)

        stop_button = QPushButton('Stop', self)
        stop_button.setGeometry(120, 10, 100, 30)
        stop_button.clicked.connect(self.stop_video_processing)

        self.result_label = QLabel(self)
        self.result_label.setGeometry(10, 50, 480, 360)

        self.setGeometry(100, 100, 500, 500)

    def start_video_processing(self):
        if self.video_thread is None or not self.video_thread.isRunning():
            self.video_thread = VideoProcessingThread(self.onnx_path, self.rtsp_url)
            self.video_thread.update_frame.connect(self.update_frame)
            self.video_thread.start()

    # def stop_video_processing(self):
    #     if self.video_thread is not None and self.video_thread.isRunning():
    #         self.video_thread.stop()
    #         self.video_thread.wait()
    def stop_video_processing(self):
        if self.video_thread is not None and self.video_thread.isRunning():
            self.video_thread.stop()
            

    def update_frame(self, frame):
        # 将cv2格式的帧转换为QImage格式
        qimg = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_BGR888)
        pixmap = QPixmap.fromImage(qimg)

        # 设置到QLabel控件上显示
        self.result_label.setPixmap(pixmap)

    def closeEvent(self, event):
        self.stop_video_processing()
        event.accept()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    onnx_path = 'yolov5s.onnx'
    rtsp_url = 'rtsp://admin:DING09503@192.168.1.64:554/h264/ch1/main/av_stream'
    main_window = MainWindow(onnx_path, rtsp_url)
    main_window.show()
    sys.exit(app.exec_())

 

代码详解

首先,导入所需的模块:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal
import cv2
import time

然后定义一个名为VideoProcessingThread的线程类,继承自QThread类。这个类用来处理视频流。

class VideoProcessingThread(QThread):
    update_frame = pyqtSignal(object)

    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url
        self.running = False

    def run(self):
        self.running = True

        cap= cv2.VideoCapture(0)
        pTime = 0
        while True:
            success, img2 = cap.read()

            cTime = time.time()
            fps = 1 / (cTime - pTime)
            pTime = cTime
            cv2.putText(img2, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
            img2 = cv2.resize(img2,(480,360))

            self.update_frame.emit(img2)

            c = cv2.waitKey(1) & 0xFF
            if c == 27 or c == ord('q'):
                break
        cap.release()


    def stop(self):
        self.running = False

VideoProcessingThread类中,我们定义了一个信号update_frame,它会在每一帧处理完毕后发射。

run方法是线程的主要执行逻辑。在这里,我们打开摄像头并循环读取视频帧。对每一帧进行处理,包括计算帧率、调整图像大小,并通过信号update_frame将图像发送给主窗口进行显示。我们还在窗口上显示了实时的帧率信息。同时,我们还检测按键事件,如果用户按下了'q'键或者Esc键,则退出循环。

stop方法用于停止线程的运行,将running标志设置为False。

接下来,定义一个名为MainWindow的主窗口类,继承自QMainWindow类。

class MainWindow(QMainWindow):
    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url

        self.video_thread = None
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Video Processing')

        start_button = QPushButton('Start', self)
        start_button.setGeometry(10, 10, 100, 30)
        start_button.clicked.connect(self.start_video_processing)

        stop_button = QPushButton('Stop', self)
        stop_button.setGeometry(120, 10, 100, 30)
        stop_button.clicked.connect(self.stop_video_processing)

        self.result_label = QLabel(self)
        self.result_label.setGeometry(10, 50, 480, 360)

        self.setGeometry(100, 100, 500, 500)

MainWindow类中,我们首先定义了构造函数,接收两个参数onnx_pathrtsp_url,分别表示ONNX模型的路径和视频流的URL。

init_ui方法用于初始化用户界面。我们设置了窗口标题为"Video Processing",创建了开始和停止按钮,并将其与对应的槽函数连接起来。我们还创建了一个标签用于显示视频帧的结果,并设置了标签的位置和尺寸。最后,我们设置了窗口的位置和尺寸。

    def start_video_processing(self):
        if self.video_thread is None or not self.video_thread.isRunning():
            self.video_thread = VideoProcessingThread(self.onnx_path, self.rtsp_url)
            self.video_thread.update_frame.connect(self.update_frame)
            self.video_thread.start()

    def stop_video_processing(self):
        if self.video_thread is not None and self.video_thread.isRunning():
            self.video_thread.stop()

start_video_processing方法在点击开始按钮时被调用。它首先检查线程是否已经存在或者正在运行,如果不是的话,就创建一个新的VideoProcessingThread线程,并将其与update_frame信号连接起来,然后启动线程。

stop_video_processing方法在点击停止按钮时被调用。它检查线程是否存在并且正在运行,如果是的话,就调用线程的stop方法停止线程的运行。

    def update_frame(self, frame):
        qimg = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_BGR888)
        pixmap = QPixmap.fromImage(qimg)
        self.result_label.setPixmap(pixmap)

    def closeEvent(self, event):
        self.stop_video_processing()
        event.accept()

update_frame方法用于更新显示的视频帧。它接收到一帧图像后,将其转换为QImage格式,并创建一个QPixmap对象。然后将该QPixmap对象设置到标签上进行显示。

closeEvent方法在窗口关闭时被调用。我们在这里停止视频处理线程,并接受窗口关闭事件。

最后,在主程序中创建一个QApplication实例,并实例化MainWindow类作为主窗口。最后调用app.exec_()启动应用程序的事件循环。

它实现了一个简单的视频处理应用程序,可以通过界面显示摄像头捕获到的实时视频流。你可以根据需要进行修改和扩展。

2.2 使用YOLOv5推理


from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal

from example1 import *
import utlis
from ours import *

import cv2
import time

class VideoProcessingThread(QThread):
    update_frame = pyqtSignal(object)

    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url
        self.running = False

    def run(self):
        self.running = True
        onnx_path = 'yolov5s.onnx'
        model = Yolov5ONNX(onnx_path)
        cap= cv2.VideoCapture(0)
        pTime = 0
        while True:
            t0 = time.time()
            # n_stamp, img = HIK.read()
            success, img = cap.read()
            img2, box_coords = model.detect(img)
            cTime = time.time()
            fps = 1 / (cTime - pTime)
            pTime = cTime
            cv2.putText(img2, str(int(fps)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)

            img2 = cv2.resize(img2,(480,360))
            # 在窗口中显示目标检测结果
            # cv2.imshow('result', img2)
            self.update_frame.emit(img2)
            # 等待用户按键,如果按下 'q' 键或者 Esc 键,则退出循环
            c = cv2.waitKey(1) & 0xFF
            if c == 27 or c == ord('q'):
                break
        HIK.release()


    def stop(self):
        self.running = False

class MainWindow(QMainWindow):
    def __init__(self, onnx_path, rtsp_url):
        super().__init__()
        self.onnx_path = onnx_path
        self.rtsp_url = rtsp_url

        self.video_thread = None
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('Video Processing')

        start_button = QPushButton('Start', self)
        start_button.setGeometry(10, 10, 100, 30)
        start_button.clicked.connect(self.start_video_processing)

        stop_button = QPushButton('Stop', self)
        stop_button.setGeometry(120, 10, 100, 30)
        stop_button.clicked.connect(self.stop_video_processing)

        self.result_label = QLabel(self)
        self.result_label.setGeometry(10, 50, 480, 360)

        self.setGeometry(100, 100, 500, 500)

    def start_video_processing(self):
        if self.video_thread is None or not self.video_thread.isRunning():
            self.video_thread = VideoProcessingThread(self.onnx_path, self.rtsp_url)
            self.video_thread.update_frame.connect(self.update_frame)
            self.video_thread.start()

    def stop_video_processing(self):
        if self.video_thread is not None and self.video_thread.isRunning():
            self.video_thread.stop()
            self.video_thread.wait()
    # def stop_video_processing(self):
    #     if self.video_thread is not None and self.video_thread.isRunning():
    #         self.video_thread.stop()

    def update_frame(self, frame):
        # 将cv2格式的帧转换为QImage格式
        qimg = QImage(frame.data, frame.shape[1], frame.shape[0], QImage.Format_BGR888)
        pixmap = QPixmap.fromImage(qimg)

        # 设置到QLabel控件上显示
        self.result_label.setPixmap(pixmap)

    def closeEvent(self, event):
        self.stop_video_processing()
        event.accept()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    onnx_path = 'yolov5s.onnx'
    rtsp_url = 'rtsp://admin:DING09503@192.168.1.64:554/h264/ch1/main/av_stream'
    main_window = MainWindow(onnx_path, rtsp_url)
    main_window.show()
    sys.exit(app.exec_())

2.3 代码中用到的主要函数 

cv2.VideoCapture: 用于打开视频文件或者设备,返回一个cv2.VideoCapture对象。

  • cap = cv2.VideoCapture(0)
    
  • cv2.cvtColor: 用于将图像从一个颜色空间转换为另一个颜色空间。

  • img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
  • cv2.resize: 用于调整图像的大小。

  • img_resized = cv2.resize(img, (width, height))
    
  • cv2.putText: 用于在图像上绘制文本。

  • cv2.putText(img, text, (x, y), font, size, color, thickness)
    
  • cv2.imshow: 用于在窗口中显示图像。

  • cv2.imshow('image', img)
    
  • cv2.waitKey: 用于等待键盘事件。

  • key = cv2.waitKey(delay)
    
  • cv2.destroyAllWindows: 用于关闭所有窗口。

  • cv2.destroyAllWindows()
    
  • QApplication: 用于创建Qt应用程序对象。

  • app = QApplication(sys.argv)
    
  • QMainWindow: 用于创建Qt主窗口。

  • class MainWindow(QMainWindow):
        def __init__(self):
            super().__init__()
            # ...
    
  • QPushButton: 用于创建Qt按钮对象。

  • start_button = QPushButton('Start', self)
    
  • QLabel: 用于创建Qt标签对象,用于显示图像、文本等内容。

  • self.result_label = QLabel(self)
    self.result_label.setGeometry(10, 50, 480, 360)
    
  • QThread: 用于创建Qt线程对象。

class VideoProcessingThread(QThread):

觉得有用朋友点个赞!

万分感谢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1096040.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Qt项目通过.pri文件将众多文件按功能模块分类显示,开发大型项目必备

Qt项目通过.pri文件将众多文件按功能模块分类显示,开发大型项目必备 Chapter1 Qt项目通过.pri文件将众多文件按功能模块分类显示,开发大型项目必备($$$)Chapter2 在Qt项目中添加pri文件前言创建pri文件的步骤一、创建Qt项目二、创建pri空文件三、调试 Ch…

SpringCloud学习笔记-Nacos服务分级存储模型

Nacos服务分级存储模型 一级是服务,例如userservice二级是集群,例如杭州或上海三级是实例,例如杭州机房的某台部署了userservice的服务器 微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集…

创新YOLOv8改进:结合全新可变形大核注意力(D-LKA Attention)实现多尺度目标涨点

🔥🔥🔥 提升多尺度目标检测,创新提升 🔥🔥🔥 🔥🔥🔥 捕捉图像特征和处理复杂图像特征 🔥🔥🔥 👉👉👉: 本专栏包含大量的新设计的创新想法,包含详细的代码和说明,具备有效的创新组合,可以有效应用到改进创新当中 👉👉👉: 🐤🐤�…

寻找AI时代的关键拼图,从美国橡树岭国家实验室读懂AI存力信标

超算,是计算产业的明珠,是人类探索未知的航船。超算的发展与变化,不仅代表着各个国家与地区间的科技竞争力,更将作为趋势风向标,影响整个数字化体系的走向。 在目前阶段,超算与AI计算的融合是大势所趋。为了…

C# GPEN-BFR 图像修复

效果 项目 代码 using Microsoft.ML.OnnxRuntime; using Microsoft.ML.OnnxRuntime.Tensors; using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Windows.Forms;namespace 图像修复 {pu…

【部署】Linux Shell脚本部署java程序 (jar包)

文章目录 前言 前言 #!/usr/bin/env bash #可变参数变量#部署磁盘路径 baseDirPath/data/apps/java/smj-exchange-upload #jar包名称 packageNamesmj-exchange-upload.jar #命令启动包名 xx.jar的xxpid #进程pid#检测pid getPid(){echo "检测状态-----------------------…

Python爬虫:某书平台的Authorization参数js逆向

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…

深势科技基于 Serverless 容器为科研人员打造高效的开发平台

作者:李样兵、刘杉、木环、玖宇、鼎岳 云端的科学研究,AI for Science 新范式 以往科学家们的科研工作需要经过大量实验的重复验证、复杂数学计算,以及长年累月的不断试错和苦苦探索。云计算基础服务的发展和人工智能技术 AI 的兴起&#x…

自动驾驶学习笔记(五)——绕行距离调试

#Apollo开发者# 学习课程的传送门如下,当您也准备学习自动驾驶时,可以和我一同前往: 《自动驾驶新人之旅》免费课程—> 传送门 《2023星火培训【感知专项营】》免费课程—>传送门 文章目录 前言 调试内容 打开在线编辑器 打开pl…

【Docker 内核详解】namespace 资源隔离(五):User namespaces

【Docker 内核详解 - namespace 资源隔离】系列包含: namespace 资源隔离(一):进行 namespace API 操作的 4 种方式namespace 资源隔离(二):UTS namespace & IPC namespacenamespace 资源隔…

narak靶机

信息搜集 主机发现 端口扫描 靶机开放了22/ssh , 80/http端口服务 UDP协议扫描端口 没有啥发现 综合扫描 web渗透 web页面 登陆80web页面,进行信息收集,在源代码和页面中似乎都没发现什么信息 web目录扫描 其中webdav很有意思,我们看看…

AutoSar CP学习概要

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦!!! 现在的一切都是为将来的梦想编织翅膀,让梦想在现实中展翅高飞。 Now everythi…

每个后端都应该了解的OpenResty入门以及网关安全实战

简介 在官网上对 OpenResty 是这样介绍的(http://openresty.org): “OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩…

CV计算机视觉每日开源代码Paper with code速览-2023.10.13

精华置顶 墙裂推荐!小白如何1个月系统学习CV核心知识:链接 点击CV计算机视觉,关注更多CV干货 论文已打包,点击进入—>下载界面 点击加入—>CV计算机视觉交流群 1.【基础网络架构】CHIP: Contrastive Hierarchical Image …

计算机系统概述(机组第一章)

补充: 1.1.1 计算机软硬件概念&&计算机系统的层次结构 思维导图 除了思维导图中的三个层级以外还包括两个层级 在实际机器下还可以延伸一级微程序机器,即将实际机器执行的指令翻译成一组微指令构成一个微程序。为程序机器执行完一个微程序在进…

Android MediaCodec 框架 基于codec2

系列文章的目的是什么? 粗略: 解码需要哪些基础的服务?标准解码的调用流程?各个流程的作用是什么?解码框架的层次?各个层次的作用? 细化: 解码参数的配置?解码输入数…

【iOS】——用单例类封装网络请求

文章目录 一、JSONModel1.JSONModel的简单介绍2.JSONModel的使用 二、单例类和Block传值 一、JSONModel 1.JSONModel的简单介绍 JSONModel一个第三方库,这个库用来将网络请求到的JSON格式的数据转化成Foundation框架下的Model类的属性,这样我们就可以直…

冠军方案!2023第二届广州·琶洲算法大赛

Datawhale干货 作者:唐楚柳,算法工程师,冠军选手 1.简介 大家好我是‍Alex‍,31岁,现为一名图像算法工程师,主要研究方向是计算机视觉图像识别。工作之余的研究兴趣包括ocr,aigc,ll…

[自学记录06|*Animation]四元数、死锁与方位插值

一、前言 还记得在很久以前不知道什么时候,看到过一个TA的面经,里面提到了四元数和万向锁,当时自己也查了一些资料,但是看的也是云里雾里,恰巧这两天学校的动画原理课讲到了这,打算整理一下做个小结。 二、…

【Linux学习笔记】 - 项目自动化工具make/Makefile的使用

一、背景知识 会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中。makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需…