尝试在 QGraphicsScene 和 QGraphicsView 中显示 opencv 视频,但没有显示

Posted

技术标签:

【中文标题】尝试在 QGraphicsScene 和 QGraphicsView 中显示 opencv 视频,但没有显示【英文标题】:Trying to display opencv video in QGraphicsScene and QGraphicsView but Nothing shows up 【发布时间】:2016-05-16 21:03:22 【问题描述】:

我有一个用 Python 编写的 GUI 应用程序,我正在尝试在 Qt 应用程序中显示视频。

它使用 QGraphicsScene 和 QGraphicsView 来显示图像,但现在我必须显示视频。当我尝试在这里显示视频时,我会这样做:

首先,我从 cv2 包创建 VideoCapture。之后,我在每次迭代中运行循环并读取帧,然后将其转换为 QPixmap(这是正确完成的,我检查了单个帧)。我将该 QPixmap 对象返回给包含 QGraphicsScene 和 QGraphicsView 的类,并尝试将其添加到场景中。

问题是,只有在视频结束时,才会显示最后一帧,在整个视频播放期间,我很高兴看到这个画面

我之前提到的循环是这样的:

    self.imageViewer.start_capturing()
    self.timer = QtCore.QTimer()
    self.fps = 24

    while True:
        retVal = self.imageViewer.read_frame()
        if not retVal:
            self.timer.stop()
            break
        self.timer.start(1000./self.fps)
    self.imageViewer.stop_capturing()

self.ImageViewer 是一个包含 QGraphicsScene 和 QGraphicsView 的组件 我还在这里放置了计时器,以便它显示适当的 fps 数量,但它没有帮助。

GUI 应用程序本身显示带有一些按钮的 QGraphicsView

middleLayout.addWidget(self.imageViewer.view)

这就是我的意思。所以它没有显示imageViewer,但它显示了QGraphicsView的子类

这是 ImageViewer 类中 read_frame 方法的代码。

def read_frame(self):
    """
    Reads a frame from the video, if video ended, then False is returned.
    If there is a successful reading then True is returned
    :return: True if video is read successfully, False otherwise.
    """
    retVal, self.current_frame = self.capture.getFrame()
    if not retVal:
        return False
    else:
        self.pixmap = retVal
        self.scene.addPixmap(self.pixmap)
        return True

self.capture.getFrame() 方法只返回 QPixmap 项和 CV::mat 项。

这整个过程是正确完成的,因为我尝试逐帧手动阅读并且一切正常,但是当我尝试显示视频时,应用程序冻结,如上图所示。所以我手动尝试通过手动单击一个按钮来完成整个描述的过程,该按钮加载我的框架并将其放到 QGraphicsScene 上,所以我假设应用程序的核心工作正常(我什至尝试通过单击获得大约 5-7 fps快:D)

我希望我把我的问题说清楚了,并包含了所有需要的代码。

【问题讨论】:

【参考方案1】:

我认为你的计时逻辑是错误的..你没有正确使用计时器..你可以使用connect或者你可以使用睡眠。

我会这样做:

def grabFrame
    retVal = self.imageViewer.read_frame()
    if not retVal:
        self.timer.stop()
        self.imageViewer.stop_capturing()

在你的主要逻辑或你的类的一些初始化函数中的某个地方:

yourObject.connect(timer,SIGNAL("timeout()"),yourObject,SLOT("grabFrame()"))
timer.start(1000./self.fps)       

或者你可以在之后使用某种睡眠时间模块

import time
...
while True:
    retVal = self.imageViewer.read_frame()
    if not retVal:
        break
    time.sleep(1./self.fps)//in fraction of second
self.imageViewer.stop_capturing()

【讨论】:

以上是关于尝试在 QGraphicsScene 和 QGraphicsView 中显示 opencv 视频,但没有显示的主要内容,如果未能解决你的问题,请参考以下文章

如何在一个类中继承 QGraphicsRectItem 和 QGraphicsEllipseItem?

尝试在 QGraphicsScene 和 QGraphicsView 中显示 opencv 视频,但没有显示

查看整个 QGraphicsScene

如何在 QGraphicsScene 中正确放置小部件

Qt等待用户在QGraphicsScene中选择项目

Qt - QGraphicsScene 和 QGraphicsView 不更新更改?