gpt4 book ai didi

python - 将网络摄像头素材从OpenCV获取到PyQt

转载 作者:行者123 更新时间:2023-12-02 16:21:31 27 4
gpt4 key购买 nike

我正在尝试使用opencv从摄像机获取网络摄像机数据,然后在PyQt gui中显示该数据。我之前使用Tkinter通过使用.after函数访问Tkinter主窗口循环来完成此操作。但是,PyQt似乎不具有相同的可用性,并且要使另一个循环与应用程序一起运行,您需要使用单独的线程。所以这是我想出的:

import sys
import cv2
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import QImage
import time

class VideoCapture(QtGui.QWidget):
def __init__(self, parent = None):
QtGui.QWidget().__init__()
self.camera = None
self.camera = cv2.VideoCapture(0)
b, self.frame = self.camera.read()
self.label = QtGui.QLabel()
self.workThread = WorkThread(self)
self.connect(self.workThread, QtCore.SIGNAL('update_Camera'), self.draw)
self.workThread.start()

def closeEvent(self, event):
self.workThread.stop()

def draw(self):
print "I should Redraw"
height, width, channel = self.frame.shape
bpl = 3 * width
self.qImg = QImage(self.frame.data, width, height, bpl, QImage.Format_RGB888)
pix = QtGui.QPixmap(self.qImg)
self.label.setPixmap(pix)
self.label.show()



class WorkThread(QtCore.QThread):
def __init__(self, parent):
QtCore.QThread.__init__(self)
self.parent = parent

def __del__(self):
self.wait()

def run(self):
while True:
self.emit(QtCore.SIGNAL('update_Camera'), "_")
self.terminate()


app = QtGui.QApplication(sys.argv)
test = VideoCapture()
test.draw()

sys.exit(app.exec_())

我的想法很简单:我将创建一个带有循环的线程,该线程发出一个信号通知主应用程序进行更新。 (显然,我不想要一个带有while True循环的线程,但我只是为了方便起见而使用它,并计划在可以保证这个想法可行的情况下替换它)。但是,信号似乎没有被注册,因为从来没有调用过draw()函数。知道我在做什么错吗?

最佳答案

我对OpenCV一无所知,所以我只能猜测问题所在。

我的猜测是您只读取一次视频数据。如果是视频流,则必须不断读取和解释数据。

import sys
import cv2
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import QImage
import time

class VideoCapture(QtGui.QWidget):

update_video = QtCore.pyqtSignal()

def __init__(self, parent = None):
QtGui.QWidget().__init__()
self.camera = cv2.VideoCapture(0)
self.label = QtGui.QLabel()
layout = QtGui.QHBoxLayout()
self.setLayout(layout)
layout.addWidget(self.label)

# Create the worker Thread
self.workThread = WorkThread(self.readVideo)
self.update_video.connect(self.draw)

def start(self):
self.workerThread.start()

def stop(self):
self.workThread.alive = False
self.workThread.stop()

def readVideo(self):
"""Note this method is executed in a thread. No drawing can happen in a thread. Emit a signal to draw items."""
b, self.frame = self.camera.read()
self.update_video.emit() # Signals are slow this may happen too fast

def closeEvent(self, event):
self.stop()
return QtGui.QWidget.closeEvent(self, event)
#self.workThread.alive = False
#self.workThread.stop()

def draw(self):
print "I should Redraw"
height, width, channel = self.frame.shape
bpl = 3 * width
qImg = QImage(self.frame.data, width, height, bpl, QImage.Format_RGB888)
pix = QtGui.QPixmap(qImg)
self.label.setPixmap(pix)
# self.label.show() # The label is now a part of the widget layout



class WorkThread(QtCore.QThread):
def __init__(self, target=None, args=(), kwargs={}):
QtCore.QThread.__init__(self)
# I don't know how Qt's threads work, so I am treating it like a python thread
self.target = target
self.args = args
self.kwargs = kwargs
self.alive = True

def run(self):
while self.alive:
self.target(*self.args, **self.kwargs)


app = QtGui.QApplication(sys.argv)
test = VideoCapture()
test.start()

sys.exit(app.exec_())

由于您每秒仅更新多次,因此您可能为此使用计时器而不是线程。计时器可能更容易使用,也更安全。
import sys
import cv2
from PyQt4 import QtGui
from PyQt4 import QtCore
from PyQt4.QtGui import QImage
import time

class VideoCapture(QtGui.QWidget):
def __init__(self, parent = None):
QtGui.QWidget().__init__()
self.camera = cv2.VideoCapture(0)
self.label = QtGui.QLabel()
layout = QtGui.QHBoxLayout()
self.setLayout(layout)
layout.addWidget(self.label)

# Create the worker Thread
self.timer= QtCore.QTimer()
self.timer.setInterval(300)
self.timer.timeout.connect(self.draw_camera)

def start(self):
self.timer.start()

def stop(self):
self.timer.stop()

def draw_camera(self):
"""You can draw in a timer, so just read the data and draw however fast you want."""
print "I should Redraw"
b, frame = self.camera.read()
height, width, channel = frame.shape
bpl = 3 * width
qImg = QImage(frame.data, width, height, bpl, QImage.Format_RGB888)
pix = QtGui.QPixmap(qImg)
self.label.setPixmap(pix)

def closeEvent(self, event):
self.stop()
return QtGui.QWidget.closeEvent(self, event)

app = QtGui.QApplication(sys.argv)
test = VideoCapture()
test.start()

sys.exit(app.exec_())

关于python - 将网络摄像头素材从OpenCV获取到PyQt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40391901/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com