opencv 多线程读取和显示摄像头【python源码】

在Python中,使用OpenCV库实现多线程读取和显示摄像头通常涉及创建多个线程,每个线程负责从摄像头捕获视频帧并显示它们。但是,请注意,OpenCV本身并不直接支持多线程显示,因为cv2.imshow通常是在主线程中运行的。然而,你可以使用多线程来捕获视频帧,并将这些帧放入一个队列中,然后在主线程中处理并显示它们。

以下是一个使用Python的threading模块和OpenCV库来实现多线程摄像头捕获和显示的示例代码:

import cv2  
import threading  
import queue  
  
# 线程安全的队列  
q = queue.Queue()  
  
# 捕获摄像头的函数  
def capture_video(cap, q):  
    while True:  
        ret, frame = cap.read()  
        if not ret:  
            break  
        # 将捕获的帧放入队列  
        q.put(frame)  
    cap.release()  
  
# 显示视频的函数  
def show_video(q):  
    while True:  
        if not q.empty():  
            # 从队列中获取帧  
            frame = q.get()  
            cv2.imshow('Camera Feed', frame)  
              
            # 按 'q' 键退出  
            if cv2.waitKey(1) & 0xFF == ord('q'):  
                break  
        else:  
            # 如果没有帧,稍微等待一下  
            cv2.waitKey(1)  
    cv2.destroyAllWindows()  
  
# 主函数  
def main():  
    # 打开摄像头  
    cap = cv2.VideoCapture(0)  
    if not cap.isOpened():  
        print("Error: Could not open camera.")  
        return  
  
    # 创建捕获和显示视频的线程  
    capture_thread = threading.Thread(target=capture_video, args=(cap, q))  
    show_thread = threading.Thread(target=show_video, args=(q,))  
  
    # 启动线程  
    capture_thread.start()  
    show_thread.start()  
  
    # 等待线程结束  
    capture_thread.join()  
    show_thread.join()  
  
    cv2.destroyAllWindows()  
  
if __name__ == "__main__":  
    main()

在上面的代码中,capture_video函数负责从摄像头捕获视频帧,并将它们放入一个线程安全的队列中。show_video函数从队列中取出帧并在窗口中显示它们。两个函数分别在不同的线程中运行,通过队列来通信。

请注意,这段代码没有实现多个摄像头的同时捕获和显示。如果你需要同时显示来自多个摄像头的视频,你需要为每个摄像头创建一个捕获线程,并可能需要为每个摄像头创建不同的显示窗口。但是,由于cv2.imshow的限制,你可能需要实现更复杂的逻辑来在多个窗口中轮询显示视频帧。

在实际应用中,如果需要处理多个摄像头的视频流,并且希望每个摄像头都有自己的显示窗口,通常更好的做法是使用图形用户界面(GUI)库(如PyQt或Tkinter)来管理窗口和事件循环,而不是依赖OpenCV的imshow函数。这些GUI库通常提供了更灵活的多线程和多窗口支持。
在这里插入图片描述

拓展

主线程:界面显示、其他逻辑处理
#线程1:opencv读取摄像头到界面中
#线程2:采集数据显示到界面中
#逻辑:
from demo import Ui_MainWindow
点击按钮detect_Button则打开摄像头,再次点击detect_Button则关闭摄像头;
实时显示摄像头画面并且更新到主界面Ui_MainWindow中;
实时采集线程2中的数据,并且更新到主界面Ui_MainWindow中

要实现您描述的功能,我们需要用到Python的threading模块来创建和管理线程,以及OpenCV库来读取摄像头的视频流。首先,确保已经安装了OpenCV库,如果没有安装,可以通过以下命令安装:

bash
pip install opencv-python
接下来,我们需要编写主逻辑。这里假设您已经有了一个demo.py文件,其中包含了Ui_MainWindow类,这个类应该是一个基于Qt Designer生成的UI界面类。下面是一个简单的例子,演示了如何实现您的要求:

import sys  
import threading  
import cv2  
from PyQt5.QtWidgets import QApplication, QMainWindow  
from PyQt5.QtGui import QImage, QPixmap  
from PyQt5.QtCore import pyqtSignal, QThread  
from demo import Ui_MainWindow  
  
class CameraThread(QThread):  
    # 定义一个信号,用来发送图像数据到主线程  
    update_image_signal = pyqtSignal(QImage)  
  
    def __init__(self, camera_id):  
        super(CameraThread, self).__init__()  
        self.camera_id = camera_id  
        self.cap = None  
  
    def run(self):  
        self.cap = cv2.VideoCapture(self.camera_id)  
        if not self.cap.isOpened():  
            print("Error: Could not open video device")  
            return  
  
        while True:  
            ret, frame = self.cap.read()  
            if ret:  
                # 将OpenCV图像转换为Qt图像  
                rgb_image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  
                h, w, ch = rgb_image.shape  
                bytes_per_line = ch * w  
                qimg = QImage(rgb_image.data, w, h, bytes_per_line, QImage.Format_RGB888)  
                self.update_image_signal.emit(qimg)  
  
    def stop(self):  
        self.requestInterruption()  
        self.wait()  
        if self.cap:  
            self.cap.release()  
  
class DataCollectionThread(QThread):  
    # 定义一个信号,用来发送采集的数据到主线程  
    update_data_signal = pyqtSignal(str)  
  
    def __init__(self):  
        super(DataCollectionThread, self).__init__()  
  
    def run(self):  
        while True:  
            # 这里模拟数据采集,您可以替换为实际的数据采集代码  
            data = "模拟数据: " + str(round(random.random(), 2))  
            self.update_data_signal.emit(data)  
            # 假设每秒更新一次数据  
            self.sleep(1)  
  
    def stop(self):  
        self.requestInterruption()  
        self.wait()  
  
class MainWindow(QMainWindow, Ui_MainWindow):  
    def __init__(self):  
        super(MainWindow, self).__init__()  
        self.setupUi(self)  
        self.camera_thread = CameraThread(0)  # 假设使用摄像头0  
        self.data_collection_thread = DataCollectionThread()  
        self.camera_thread.update_image_signal.connect(self.update_image)  
        self.data_collection_thread.update_data_signal.connect(self.update_data_label)  
        self.detect_Button.clicked.connect(self.toggle_camera)  
        self.camera_running = False  
  
    def toggle_camera(self):  
        if self.camera_running:  
            self.camera_thread.stop()  
            self.data_collection_thread.stop()  
            self.camera_running = False  
        else:  
            self.camera_thread.start()  
            self.data_collection_thread.start()  
            self.camera_running = True  
  
    def update_image(self, image):  
        self.label_image.setPixmap(QPixmap.fromImage(image))  
  
    def update_data_label(self, data):  
        self.label_data.setText(data)  
  
if __name__ == '__main__':  
    app = QApplication(sys.argv)  
    window = MainWindow()  
    window.show()  
    sys.exit(app.exec_())

在这个例子中,我们创建了两个线程类CameraThread和DataCollectionThread。CameraThread负责读取摄像头并发送图像信号,而DataCollectionThread

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++ STL序列容器】deque 双端队列

文章目录 【 1. 基本原理 】【 1. deque 的创建 】1.1 创建一个空的 deque1.2 创建一个 n 个默认值的 deque1.3 创建一个 n 个指定值的 deque1.4 通过一个 deque 初始化另一个 deque1.5 通过基础容器来初始化 queue 容器适配器 【 3. deque 支持的成员函数 】 【 1. 基本原理 】…

什么是HW,企业如何进行HW保障?

文章目录 一、什么是HW二、HW行动具体采取了哪些攻防演练措施三、攻击方一般的攻击流程和方法四、企业HW保障方案1.建意识2.摸家底3.固城池4.配神器5.增值守 一、什么是HW 网络安全形势近年出现新变化,网络安全态势变得越来越复杂,黑客攻击入侵、勒索病…

【C语言】双向链表详解

文章目录 关于双向链表双向链表的初始化双向链表的打印双向链表方法调用 - 尾删为例双向链表的查找 - 指定位置之后插入为例双向链表结束 - 链表的销毁小结及整体代码实现 关于双向链表 首先链表有8种基本分法 其中在笔者之前文章种详细介绍的 单链表 是不带头单项不循环链表…

Leetcode算法训练日记 | day24

一、组合问题 1.题目 Leetcode:第 77 题 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4…

别人起诉你你不服,到底是写上诉状还是反诉状?李秘书讲写作讲给你听!

别人起诉你你不服,到底是写上诉状还是反诉状?李秘书讲写作讲给你听! 别人向法院告了你,你不服气,这时你可能想到要申辩或“报复”,但又不知是写上诉状呢还是写反诉状呢?#李秘书讲写作#这节就讲…

深度学习入门(2)

一。Matplotlib模块添加 Matplotlib是用于绘制图形的库,使用 Matplotlib 可以轻松地绘制图形和实现数据的可视化。 pip install matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple 二、绘制简单图形 import numpy as np import matplotlib.pyplot as plt #…

【电控笔记7】速度回路+系统延迟

2.3.1速度回路pi控制器设计 Tl:负载转矩

ubuntu16.04安装Eclipse C/C++

1.安装 JDK 官网源码安装 首先打开JDK官网,JDK1.8的下载网址为:https://www.oracle.com/cn/java/technologies/downloads/#java8-windows,进入到网址如下图所示: 向下滑动到 JDK1.8的下载界面,如下图所示&#xff1a…

面试题:重写equals(),为什么还要重写hashcode()

认识equals(): Object类中的equals; public boolean equals(Object obj) {return (this obj);}当我们没有重写equals(),我们是调用父类object中的方法,比较的是对象的内存地址 重写equals后, public class Student…

【群智能算法改进】一种改进的鹦鹉优化算法 改进鹦鹉优化器 IPO算法【Matlab代码#73】

文章目录 【获取资源请见文章第5节:资源获取】1. 原始鹦鹉优化算法PO2. 改进后的IPO算法2.1 自适应切换因子2.2 混合柯西和高斯变异 3. 部分代码展示4. 仿真结果展示5. 资源获取 【获取资源请见文章第5节:资源获取】 1. 原始鹦鹉优化算法PO 鹦鹉优化算法…

java程序 .exe启动nginx防止重复启动,已解决

java代码生成好的.exe启动nginx服务程序 根据nginx占用端口来解决nginx服务重复启动问题(下面代码了解代码逻辑后根据自己的业务需求修改即可) 代码: package org.example;import javax.swing.*; import java.awt.*; import java.io.*; …

6.Burp Suite 入门篇 —— Burp Scanner 漏洞扫描

目录 前言 扫描网站 打开扫描启动页面 填写目标网站地址 配置扫描参数 开始扫描 查看网站结构 查看扫描结果 生成漏洞扫描报告 选择扫描结果 配置报告选项 生成并保存报告 查看或分享报告 前言 Burp Scanner 既可以是独立的全自动扫描器,也可以在手动…

约瑟夫问题---C++

今天来讲一道饶有名气的题目,约瑟夫问题 约瑟夫问题 这道题目有许多大佬用队列、递归、链表来解这道题目而这题的难度也确实非同小可! 可是你们难道没有想过?用数组去解决吗?没错一维数组!为了想出解决办法我掉了23根头…

福建单航次最大批量汽车“出海”

3月12日这一天,在福州海关的严密监管下,共有4000辆上汽名爵品牌的汽车被高效有序地装载到“安吉智慧”号滚装船上,这批车辆即将启程前往荷兰、埃及、英国等多个海外市场。在这批出口汽车中,新能源车型占据了显著的比例&#xff0c…

飞书api增加权限

1,进入飞书开发者后台:飞书开放平台 给应用增加权限 2,进入飞书管理后台 https://fw5slkpbyb3.feishu.cn/admin/appCenter/audit 审核最新发布的版本 如果还是不行,则需要修改数据权限,修改为全部成员可修改。 改完…

【避坑NOC】关于举办2023-2024学年全国中小学信息技术创新与实践大赛的通知

01-关于2024年赛事信息 2024年NOC比赛已经可以开始报名了,今年的报名比去年提前了接近2个月,这项白名单赛事去年问题比较多,推荐指数不高,当然,如果愿意参加的,下面老师还有一些避坑信息,参加的同学和机构老师必须要了解。先来看一下完整的通知: 02-比赛类别 共设有三…

CMD命令窗口提示文字乱码

我下面说的是日文版系统,中文版会有差异。 一般情况下是 Shiftjis 通常我是用sakura editor来写bat,但是运行后会在cmd窗口出现乱码 test.bat set HENSU这是一个变数 echo %HENSU% pause 执行后出现乱码 原因是不做设置时,command prom…

多线程java

多线程的创建 前两种方法无法返回直接结果,而有的线程执行完毕后需要返回结果 方式一:java是通过java.lang.Thread类的对象来代表线程的 启动线程必须调用strat方法,不是调用run方法不要把主线程任务放在启动子线程之前 //1.让子类继承Thread线程类 public class MyThread …

数据库体系概述:详述其基本概念、多样分类、关键作用及核心特性

数据库是一个用于存储、管理和检索数据的系统,它按照特定的数据结构和模式组织数据,确保数据的一致性、安全性和高效访问。 数据库(Database, DB)是一个长期存储在计算机内,用来组织、存储和管理大量数据的集合。数据…

spispi

数据手册里面有这么一段解释,就是说如果我们开启了看门狗,那么LSI就会跟随强制打开,等待LSI稳定之后就可以自动为独立看门狗提供时钟了。所以这里的第一步开启时钟不需要我们写代码来执行 2.写入预分频器和重装寄存器 在写入这两个寄存器之前…