在pyqt5中恢复使用opencv创建的线程



我正在尝试设计一个与我的计算机视觉项目相关的gui。在这个视频中,我想停止网络摄像头的输入,我想通过按下一个按钮来恢复它。我设法停止了传送,但无法恢复。相机打开了,但不工作。这是程序的代码。

from PyQt5 import uic
from PyQt5 import QtCore, QtWidgets, QtGui
import cv2
import sys
class opencv_feed(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.ui = uic.loadUi('../designs/design5_flexible_opencv_window2.ui', self)    #change this whenever u want... keep the ui file with you
self.resize(900,600)
self.worker1 = worker1()                                #creating an instance
self.worker1.start()
self.worker1.ImgUpdate.connect(self.ImageUpdateSlot)
self.but_stop.clicked.connect(self.cancel_feed)
self.but_resume.clicked.connect(self.resume_feed)


def ImageUpdateSlot(self, Image):
self.label.setPixmap(QtGui.QPixmap.fromImage(Image))

def cancel_feed(self):
self.worker1.stop()

def resume_feed(self):
self.__init__()
#self.worker1.ImgUpdate.connect(self.ImageUpdateSlot)
class worker1(QtCore.QThread):
ImgUpdate = QtCore.pyqtSignal(QtGui.QImage)

@QtCore.pyqtSlot()
def run(self):  #put self in every variable to stop crashing the gui, when we interact with gui
self.ThreadActive = True
self.feed = cv2.VideoCapture(0)
while self.ThreadActive:
self.ret, self.frm = self.feed.read()
if self.ret:
self.img = cv2.cvtColor(self.frm, cv2.COLOR_BGR2RGB)
#print(img1.shape)
self.img = cv2.flip(self.img,1)
self.qtformat_conv_img = QtGui.QImage(self.img.data, self.img.shape[1], self.img.shape[0], QtGui.QImage.Format_RGB888)
#print(self.img.shape)
self.pic = self.qtformat_conv_img.scaled(self.img.shape[1],self.img.shape[0],QtCore.Qt.KeepAspectRatio)    #keep this as an attribute, else when resizing the app stops                                              
self.ImgUpdate.emit(self.pic)
def stop(self):
self.ThreadActive = False
self.feed.release()
self.quit()
#os._exit(0)  

if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
wind = opencv_feed()
wind.show()
sys.exit(app.exec_())

谁能告诉我我做错了什么?

链接到UI文件…https://drive.google.com/file/d/1UP8RjQML1GzFA75eGURgWt4Y0o_Ip3sU/view?usp=sharing

一个线程只能启动一次。一旦它完成,您需要创建另一个线程对象来实际运行。我会在self之后再加一面旗帜。ThreadActive调用类似于"pause"保持线程存活,不做任何事情。

@QtCore.pyqtSlot()
def run(self):  #put self in every variable to stop crashing the gui, when we interact with gui
self.ThreadActive = True
self.paused = False
self.feed = cv2.VideoCapture(0)
while self.ThreadActive:
if not self.paused:
self.ret, self.frm = self.feed.read()
if self.ret:
self.img = cv2.cvtColor(self.frm, cv2.COLOR_BGR2RGB)
#print(img1.shape)
self.img = cv2.flip(self.img,1)
self.qtformat_conv_img = QtGui.QImage(self.img.data, 
self.img.shape[1], 
self.img.shape[0], 
QtGui.QImage.Format_RGB888)
#print(self.img.shape)
self.pic = self.qtformat_conv_img.scaled(self.img.shape[1],self.img.shape[0],QtCore.Qt.KeepAspectRatio)    #keep this as an attribute, else when resizing the app stops                                              
self.ImgUpdate.emit(self.pic)

这样当你想暂停线程时,你可以使用

标志来暂停和取消暂停要么这样,要么你总是需要创建另一个worker实例。如果您在init之外创建实例,它是否工作?? 我不确定如果init被调用两次。

编辑:你还必须改变暂停和重新开始的方式

def cancel_feed(self):
self.worker1.paused = True
def resume_feed(self):
self.worker1.paused = False

最新更新