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

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

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

相关文章

明明设置数字居中对齐,为什么excel的数字却不居中?

有时候在excel里,选中数据,设置对齐方式 左右居中,然而,数字却怎么都不居中,为什么呢? 1.按快捷键Ctrl1,打开单元格自定义格式对话框,看到是初始界面是在数字的会计专用,…

蓝桥杯python速成

总写C,脑子一热,报了个Python(有一点想锤死自己),临时抱佛脚了 1.list的插入删除 append extend insert(在索引位插入99)---忘记用法别慌,用help查询 remove(去掉第一个3…

【测试开发学习历程】python类的继承

目录 1 继承的概念 2 继承的写法 3 子类继承父类的属性和方法 4 子类新增父类没有的属性和方法 5 子类重写父类的属性和方法 6 super超类的使用 7 多继承 1 继承的概念 继承是类与类之间的一种关系,子类继承父类。通过继承可以使得子类能够拥有父类的属性和方…

scanf()返回转换成功的个数

一、概要 1、scanf()的读取与返回 scanf(),敲下回车进行一次读取,如果没有读到或没有读够,就继续等待输入 scanf()一次可以读取一个,也可以读取多个,多个之间用空格隔开 读取的数据按照%后面的字符格式进行转换&am…

【CSS面试题】Flex实现九宫格

考察知识&#xff1a; flex布局 水平垂直居中的实现 初始效果 代码关键&#xff1a;给父盒子添加以下属性 flex-wrap: wrap; /* 允许换行 */justify-content: space-around; /* 主轴对齐方式 */align-content: space-around; /* 多行在侧轴上的对齐方式 */<!DOCTYPE html&…

Java 自定義 List<T> 分頁工具

Java 自定義 List 分頁工具 PS: T可修改为对应的实体 rt com.google.common.collect.Lists;import java.util.Arrays; import java.util.Collections; import java.util.List;/*** ClassName: MyPageHelper* Descripution: List<T>分頁工具**/ public class MyPageHelp…

10BASE-T1S架构助力车载E/E领域,引领汽车产业迈向智能化新纪元!

汽车架构的发展 如今&#xff0c;汽车已不仅仅满足消费者的代步需求&#xff0c;而是向所谓的ACES&#xff08;Autonomous, Connected, Electrification, Shared Source&#xff09;方向发展&#xff0c;全自动驾驶和网联化将成为最终目标。由此带来的高算力和高数据吞吐量问题…

政安晨:【Keras机器学习实践要点】(二十八)—— 使用Reptile进行小样本学习

目录 介绍 定义超参数 准备数据 可视化数据集中的一些示例 建立模型 训练模型 可视化结果 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&#xff0c;如有不足之处…

数据库练习

insert into employee(empno,ename,job,mgr,hiredate,sal,comm,deptno) values (1001,甘宁,文员,1013,2000-12-17,8000.00,NULL,20), (1002,黛绮丝,销售员,1006,2001-02-20,16000.00,3000.00,30), (1003,殷天正,销售员,1006,2001-02-22,12500.00,5000.00,30), (1004,刘备,经理,…

kimichat使用技巧:用语音对话聊天

kimichat之前是只能用文字聊天的&#xff0c;不过最近推出了语音新功能&#xff0c;也可以用语音畅快的对话聊天了。 这个功能目前支持手机app版本&#xff0c;所以首先要在手机上下载安装kimi智能助手。已经安装的&#xff0c;要点击检查更新&#xff0c;更新到最新的版本。 …

Ubuntu 20.04 设置开启 root 远程登录连接

Ubuntu默认不设置 root 帐户和密码 Ubuntu默认不设置 root 帐户和密码 Ubuntu默认不设置 root 帐户和密码 如有需要&#xff0c;可在设置中开启允许 root 用户登录。具体操作步骤如下&#xff1a; 操作步骤 1、首先使用普通用户登录 2、设置root密码 macw:~$ sudo passwd …

Llama2模型本地部署(Mac M1 16G)

环境准备 环境&#xff1a;Mac M1 16G、Conda Conda创建环境配置 使用Anaconda-Navigator创建python 3.8环境 切换到新建的conda环境&#xff1a; conda activate llama38 llama.cpp 找一个目录&#xff0c;下载llama.cpp git clone https://github.com/ggerganov/llama.…

读所罗门的密码笔记18_大宪章

1. 大宪章 1.1. 1215年会议开启了一个艰难的谈判过程&#xff0c;充满了紧张和对权力与道德权威的争夺 1.1.1. 这部宪章会赋予各方一系列的权力&#xff0c;对国王的自由裁量权进行制衡 1.2. 《大宪章》还需要300多年的时间和多次迭代&#xff0c;才能成为财产权、公平税收、…

STM32 DCMI 的带宽与性能介绍

1. 引言 随着市场对更高图像质量的需求不断增加&#xff0c;成像技术持续发展&#xff0c;各种新兴技术&#xff08;例如3D、计算、运动和红外线&#xff09;的不断涌现。如今的成像应用对高质量、易用性、能耗效率、高集成度、快速上市和成本效益提出了全面要求。为了满足这些…

【算法一则】做算法学数据结构 - 简化路径 - 【栈】

目录 题目栈代码题解 题目 给你一个字符串 path &#xff0c;表示指向某一文件或目录的 Unix 风格 绝对路径 &#xff08;以 ‘/’ 开头&#xff09;&#xff0c;请你将其转化为更加简洁的规范路径。 在 Unix 风格的文件系统中&#xff0c;一个点&#xff08;.&#xff09;表…

Cesium 无人机航线规划

鉴于大疆司空平台和大疆无人机app高度绑定&#xff0c;导致很多东西没办法定制化。 从去年的时候就打算仿大疆开发一套完整的平台&#xff0c;包括无人机app以及仿司空2的管理平台&#xff0c;集航线规划、任务派发、实时图像、无人机管理等功能的平台。 当前阶段主要实现了&…

突破编程_前端_SVG(circle 圆形)

1 circle 元素的基本属性和用法 SVG 的 <circle> 元素用于在SVG文档中绘制圆形。它具有几个基本属性&#xff0c;允许定义圆形的大小、位置、填充颜色和边框样式。以下是 <circle> 元素的基本属性及其详细解释&#xff1a; 1.1 cx 和 cy 描述&#xff1a;这两个…

记录一次Java中使用P12证书访问https,nginx返回403的问题

目录 1、先使用浏览器导入证书访问&#xff0c;测试证书和密钥是否正确2、编写初始java代码3、结果响应 403 Forbidden4、解决方案 1、先使用浏览器导入证书访问&#xff0c;测试证书和密钥是否正确 成功返回&#xff0c;说明p12证书和密钥是没问题的。 2、编写初始java代码 …

Harmony鸿蒙南向外设驱动开发-Codec

功能简介 OpenHarmony Codec HDI&#xff08;Hardware Device Interface&#xff09;驱动框架基于OpenMax实现了视频硬件编解码驱动&#xff0c;提供Codec基础能力接口给上层媒体服务调用&#xff0c;包括获取组件编解码能力、创建组件、参数设置、数据的轮转和控制、以及销毁…

oracle创建整个数据库的只读账户

在源用户readonly 下创建只读用户 reader readonly 的表空间为AA 一、创建只读用户 create user reader identified by 密码 default tablespace AA; 二、授权 grant connect to reader ; 三、获取原账号readonly 的查询权限 select grant select on ||owner||.||object…