Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用PyQt和OpenCV读取帧_Python_Opencv_Model View Controller_Pyqt_Pyqt5 - Fatal编程技术网

Python 如何使用PyQt和OpenCV读取帧

Python 如何使用PyQt和OpenCV读取帧,python,opencv,model-view-controller,pyqt,pyqt5,Python,Opencv,Model View Controller,Pyqt,Pyqt5,我一直在尝试使用OpenCV和PyQt从网络摄像头读取帧。我知道有很多例子。但我想使用MVC模型视图控制器 OpenCV处理控制器,我为model创建了models.py,为GUI创建了views.py 在运行代码之前,我没有看到任何错误,当我运行代码时,GUI打开,然后我按下open webcam,我看到以下警告和错误: [ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674

我一直在尝试使用OpenCV和PyQt从网络摄像头读取帧。我知道有很多例子。但我想使用MVC模型视图控制器

OpenCV处理控制器,我为model创建了models.py,为GUI创建了views.py

在运行代码之前,我没有看到任何错误,当我运行代码时,GUI打开,然后我按下open webcam,我看到以下警告和错误:

[ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback

Process finished with exit code 1
这里是views.py

from PyQt5.QtCore import QThread, QTimer
from PyQt5.QtWidgets import QLabel, QWidget, QPushButton, QVBoxLayout, QApplication, QHBoxLayout, QMessageBox
from models import Camera

class UI_Window(QWidget):

    def __init__(self, camera = None):
        super().__init__()
        self.camera = camera

        # Create a timer.
        self.timer = QTimer()
        self.timer.timeout.connect(Camera.nextFrameSlot)

        # Create a layout.
        layout = QVBoxLayout()

        # Add a button
        button_layout = QHBoxLayout()

        btnCamera = QPushButton("Open camera")
        btnCamera.clicked.connect(Camera.openCamera)
        button_layout.addWidget(btnCamera)
        layout.addLayout(button_layout)

        # Add a label
        self.label = QLabel()
        self.label.setFixedSize(640, 640)

        layout.addWidget(self.label)

        # Set the layout
        self.setLayout(layout)
        self.setWindowTitle("First GUI with QT")
        self.setFixedSize(800, 800)

    # https://stackoverflow.com/questions/1414781/prompt-on-exit-in-pyqt-application

class MovieThread(QThread):
    def __init__(self, camera):
        super().__init__()
        self.camera = camera

    def run(self):
        self.camera.acquire_movie(200)

if __name__ == '__main__':
    app = QApplication([])
    window = UI_Window()
    window.show()
models.py

import cv2
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QPixmap, QImage

class Camera:

    def __init__(self, camera):
        self.camera = camera
        self.cap = None

    def openCamera(self):
        self.vc = cv2.VideoCapture(0)
        # vc.set(5, 30)  #set FPS
        self.vc.set(3, 640)  # set width
        self.vc.set(4, 480)  # set height

        if not self.vc.isOpened():
            msgBox = QMessageBox()
            msgBox.setText("Failed to open camera.")
            msgBox.exec_()
            return

        self.timer.start(1000. / 24)

    # https://stackoverflow.com/questions/41103148/capture-webcam-video-using-pyqt
    def nextFrameSlot(self):
        rval, frame = self.vc.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)

    def initialize(self):
        self.cap = cv2.VideoCapture(self.camera)
start.py

from PyQt5.QtWidgets import QApplication

from models import Camera
from views import UI_Window

camera = Camera(0)
camera.initialize()

app = QApplication([])
start_window = UI_Window(camera)
start_window.show()
app.exit(app.exec_())

这个代码对我有用。为了测试,我把所有的都放在一个文件中

我搬走了

camera.initialize()
我将nextFrameSlot从摄像头移动到UI_窗口

我还创建了“在UI_窗口中启动”以将self.timer.start从摄像头移动到UI_窗口

编辑:在单独的文件中测试代码

我还添加了read_gray和负片颜色readnegative=True,read_gray negative=True

顺便说一句:我在很多地方检查了frame是否为空,但如果frame不是frame,则不能使用,但如果frame不是None,则不能使用,因为frame是numpy.array,如果不是numpy.array,则可能会给出错误的结果

我从一个模型移动到另一个视图的所有GUI小部件

models.py

import cv2
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QPixmap, QImage

class Camera:

    def __init__(self, camera):
        self.camera = camera
        self.cap = None

    def openCamera(self):
        self.vc = cv2.VideoCapture(0)
        # vc.set(5, 30)  #set FPS
        self.vc.set(3, 640)  # set width
        self.vc.set(4, 480)  # set height

        if not self.vc.isOpened():
            msgBox = QMessageBox()
            msgBox.setText("Failed to open camera.")
            msgBox.exec_()
            return

        self.timer.start(1000. / 24)

    # https://stackoverflow.com/questions/41103148/capture-webcam-video-using-pyqt
    def nextFrameSlot(self):
        rval, frame = self.vc.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)

    def initialize(self):
        self.cap = cv2.VideoCapture(self.camera)
views.py

main.py


这个代码对我有用。为了测试,我把所有的都放在一个文件中

我搬走了

camera.initialize()
我将nextFrameSlot从摄像头移动到UI_窗口

我还创建了“在UI_窗口中启动”以将self.timer.start从摄像头移动到UI_窗口

编辑:在单独的文件中测试代码

我还添加了read_gray和负片颜色readnegative=True,read_gray negative=True

顺便说一句:我在很多地方检查了frame是否为空,但如果frame不是frame,则不能使用,但如果frame不是None,则不能使用,因为frame是numpy.array,如果不是numpy.array,则可能会给出错误的结果

我从一个模型移动到另一个视图的所有GUI小部件

models.py

import cv2
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtGui import QPixmap, QImage

class Camera:

    def __init__(self, camera):
        self.camera = camera
        self.cap = None

    def openCamera(self):
        self.vc = cv2.VideoCapture(0)
        # vc.set(5, 30)  #set FPS
        self.vc.set(3, 640)  # set width
        self.vc.set(4, 480)  # set height

        if not self.vc.isOpened():
            msgBox = QMessageBox()
            msgBox.setText("Failed to open camera.")
            msgBox.exec_()
            return

        self.timer.start(1000. / 24)

    # https://stackoverflow.com/questions/41103148/capture-webcam-video-using-pyqt
    def nextFrameSlot(self):
        rval, frame = self.vc.read()
        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        image = QImage(frame, frame.shape[1], frame.shape[0], QImage.Format_RGB888)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)

    def initialize(self):
        self.cap = cv2.VideoCapture(self.camera)
views.py

main.py


如果您只是在寻找问题的简单答案,那么这里有一个consice替代@furas的答案:

如何使用PyQt和OpenCV读取帧

使用Python 3.7.9进行测试

requirements.txt:

numpy==1.19.4
opencv-python==4.4.0.46
PyQt5==5.15.1
PyQt5-sip==12.8.1

如果您只是在寻找问题的简单答案,那么这里有一个consice替代@furas的答案:

如何使用PyQt和OpenCV读取帧

使用Python 3.7.9进行测试

requirements.txt:

numpy==1.19.4
opencv-python==4.4.0.46
PyQt5==5.15.1
PyQt5-sip==12.8.1

您在Google中搜索过cap_msmf.cpp 674 SourceReaderCB::~SourceReaderCB终止异步回调了吗?您发现了什么?在开始时,您使用initialize,它使用cv2.videocaptureslf.camera,但也有运行camera.openCamera的按钮,它使用self.vc=cv2.VideoCapture0-因此您创建了两次访问,但没有释放第一次访问。但它不起作用,请回答您的第一条评论:这是完整的错误消息吗?难道你没有更多的错误行吗?可能还有其他有用的信息-例如,哪一行是问题所在。不幸的是,这是完整的消息您是否在Google中搜索了cap_msmf.cpp 674 SourceReaderCB::~SourceReaderCB终止异步回调?您发现了什么?在开始时,您使用initialize,它使用cv2.videocaptureslf.camera,但也有运行camera.openCamera的按钮,它使用self.vc=cv2.VideoCapture0-因此您创建了两次访问,但没有释放第一次访问。但它不起作用,请回答您的第一条评论:这是完整的错误消息吗?难道你没有更多的错误行吗?也许还有其他有用的信息-例如,哪一行是问题所在。不幸的是,这是完整的消息,它在一个文件中工作。但是当我把它分成3个文件时。我在views.py中看到错误。上面写着“未解析的摄像机引用”。nextFrameSlot和start中的摄像头未联机,您必须使用self。为了访问self.cameraI,我添加了在单独文件中测试的代码。我还添加了read_gray并将颜色转换为负片。在Camera/model中,我还将添加其他过滤器和图像修改,例如翻转、识别轮廓和其他cv2功能,这些功能在一个文件中工作。但是当我把它分成3个文件时。我在views.py中看到错误。上面写着“未解析的摄像机引用”。nextFrameSlot和start中的摄像头未联机,您必须使用self。为了访问self.cameraI,我添加了在单独文件中测试的代码。我还添加了read_gray并将颜色转换为负片。在相机/模型中,我还将添加其他过滤器和图像修改——例如翻转、识别轮廓和其他cv2功能
numpy==1.19.4
opencv-python==4.4.0.46
PyQt5==5.15.1
PyQt5-sip==12.8.1