我正在写一个应用程序来控制一个带有人脸识别的多储物柜保险箱,我遇到了一个问题,我已经成功地复制了一个小得多的应用程序(代码如下)。在更新#3的文章末尾有更短的代码
为了合并PyQt 5和OpenCV,我遵循了tutorial by docPhil99 on GitHub。
每当我尝试使用QThread关闭和打开网络摄像头几次后,我得到一个错误:Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
我在MacOS 13.2.1 OpenCV 4.7.0 PyQt 5上使用来自Anaconda的PyCharm CE和Python 3.10
class VideoThread(QThread):
change_pixmap_signal = pyqtSignal(np.ndarray)
def __init__(self, parent=None):
super().__init__(parent)
self.cv_img = None
self.ret = None
self.camera_needed = False
def run(self):
# capture from webcam
self.camera_needed = True
self.cap = cv2.VideoCapture(0)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)
while self.camera_needed:
self.ret, self.cv_img = self.cap.read()
if self.ret:
self.change_pixmap_signal.emit(self.cv_img)
def stop(self):
self.cap.release()
self.camera_needed = False
self.exit(0)
class TestWindowForCameraOpenAndClose(QWidget):
def __init__(self):
super().__init__()
self.video_thread = VideoThread()
self.video_thread.change_pixmap_signal.connect(self.refresh_video)
self.ui()
def ui(self):
layout = QHBoxLayout()
self.camera_preview = QLabel(self)
self.camera_preview.resize(480, 320)
turn_on_btn = QPushButton('ON', self)
turn_on_btn.clicked.connect(self.turn_on)
turn_off_btn = QPushButton('OFF', self)
turn_off_btn.clicked.connect(self.turn_off)
layout.addWidget(self.camera_preview)
layout.addWidget(turn_on_btn)
layout.addWidget(turn_off_btn)
self.setLayout(layout)
self.show()
def turn_on(self):
self.video_thread.start()
def turn_off(self):
self.video_thread.stop()
@pyqtSlot(np.ndarray)
def refresh_video(self, cv_img):
qt_img = self.convert_cv_qt(cv_img)
self.camera_preview.setPixmap(qt_img)
def convert_cv_qt(self, cv_img):
rgb_img = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB)
h, w, ch = rgb_img.shape
bytes_per_line = ch * w
qt_format = QtGui.QImage(rgb_img.data, w, h, bytes_per_line, QtGui.QImage.Format_RGB888)
p = qt_format.scaled(480, 320, Qt.KeepAspectRatio)
return QPixmap.fromImage(p)
app = QApplication(sys.argv)
w = TestWindowForCameraOpenAndClose()
w.show()
app.exec()
这个程序显然非常简化,但它给出了同样的错误。
我期望它在按开时打开网络摄像头,在按关时关闭。
---- UPDATE ---- Try/except在这里似乎没有帮助,因为它没有捕获这个错误。
- 更新#2 -当在PyCharm中的Windows 10上运行相同的代码时,Python 3.10从Anaconda而不是分段错误,我得到了这个错误,但程序继续。
[ WARN:0@16.708] global cap_msmf.cpp:1759 CvCapture_MSMF::grabFrame videoio(MSMF): can't grab frame. Error: -2147483638
----更新#3 ----我试着在OpenCV中只测试相机
import cv2
camera_preview = cv2.VideoCapture(0)
if not camera_preview.isOpened():
exit()
while (True):
camera_preview = cv2.VideoCapture(0)
ret, frame = camera_preview.read()
if not ret:
break
cv2.imshow('frame', frame)
if cv2.waitKey(0):
break
camera_preview.release()
cv2.destroyAllWindows()
这应该会给予我一个视频预览,但我只得到一个静态帧,没有视频。然而,此处不存在分段故障错误。
我开始觉得这是OpenCV的错误。
老实说,我没有什么想法,可悲的是,我还没有完全理解QThreads,我没有时间完成我的大学课程申请。提前谢谢你,阿图尔
1条答案
按热度按时间44u64gxh1#
变化
致:
解决了这个问题。
看来,主要的问题是事情的顺序-我试图释放相机,而线程仍在使用其数据。