我尝试了this回答的代码,并在一段时间(2-10秒)之后崩溃,错误Process finished with exit code -1073740771 (0xC000041D)
,有时与0xC0000005
崩溃。如果我试图拖动窗口,它会立即崩溃。然而,当我把time.sleep(0.1)
放在run
时它工作正常。如果我使用短于0.1的睡眠,它会再次崩溃。
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel,QMessageBox
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, Qt
import cv2
import sys
import time
class CamThread(QThread):
changemap = pyqtSignal('QImage')
def run(self):
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
while True:
ret, img_rgb = cap.read()
if ret:
self.rgb = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2RGB)
self.convert = QImage(self.rgb.data, self.rgb.shape[1], self.rgb.shape[0], QImage.Format_RGB888)
self.p = self.convert.scaled(640, 480, Qt.KeepAspectRatio)
self.changemap.emit(self.p)
#time.sleep(0.1)
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'webcam'
self.initUI()
@pyqtSlot('QImage')
def setImage(self, image):
self.label.setPixmap(QPixmap.fromImage(image))
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(100, 100, 640, 480)
self.resize(640, 480)
self.label = QLabel(self)
self.label.resize(640, 480)
thr = CamThread(self)
thr.changemap.connect(self.setImage)
thr.start()
app = QApplication(sys.argv)
win = App()
#win.setAttribute(Qt.WA_DeleteOnClose, True)
win.show()
app.exit(app.exec_())
我认为问题出在信号/插槽的某个地方但是却找不到任何相关的东西。
修复了它使用QMutex
和QWaitCondition
来防止主线程已经更新时的更新调用。显然,问题在于此。 eyllanesc,如你所见,我是新来的,我应该在原创帖子中回答一下吗?
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QMessageBox
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot, Qt, QMutex, QWaitCondition
import cv2
import sys
import time
class CamThread(QThread):
changemap = pyqtSignal('QImage')
def __init__(self, mutex, condition):
super().__init__()
self.mutex = mutex
self.condition = condition
def run(self):
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
while True:
try:
ret, img_rgb = cap.read()
if ret:
rgb = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2RGB)
#any other image processing here
convert = QImage(rgb.data, rgb.shape[1], rgb.shape[0], QImage.Format_RGB888)
p = convert.scaled(640, 480, Qt.KeepAspectRatio)
self.changemap.emit(p)
self.condition.wait(self.mutex)
except:
print('error')
class App(QWidget):
time = 0
def __init__(self):
super().__init__()
self.title = 'webcam'
self.mutex = QMutex()
self.condition = QWaitCondition()
self.initUI()
@pyqtSlot('QImage')
def setImage(self, image):
self.mutex.lock()
try:
self.label.setPixmap(QPixmap.fromImage(image))
finally:
self.mutex.unlock()
self.condition.wakeAll()
def initUI(self):
self.mutex.lock()
self.setWindowTitle(self.title)
self.setGeometry(100, 100, 640, 480)
self.resize(640, 480)
self.label = QLabel(self)
self.label.resize(640, 480)
self.thr = CamThread(mutex = self.mutex,condition=self.condition)
self.thr.changemap.connect(self.setImage)
self.thr.start()
app = QApplication(sys.argv)
win = App()
win.show()
app.exit(app.exec_())
注:在此示例中,您仍需要正确停止线程并关闭相机连接。