在QGraphicsView中播放图像序列(神秘内存泄漏) [英] Playing image sequence in QGraphicsView (Mysterious Memory Leak)

查看:1054
本文介绍了在QGraphicsView中播放图像序列(神秘内存泄漏)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试处理图像序列,并使用OpenCV和PyQt5对结果进行视频处理.我有一些遍历目录的代码,读取图像,并尝试 将它们显示在QGraphicsView上.

I'm trying to process an image sequence and make a video of the results using OpenCV and PyQt5. I've got some code that loops through a directory, reads in the images, and tries to display them on a QGraphicsView.

def on_start(self):
    for f in self.image_list:
        img = cv2.imread(f)
        img = cv2qimage(img, False)
        self.scene.set_qimage(img)

self.scene继承自QGraphicsScene.

  def set_qimage(self, qimage):
        self.pixmap = QPixmap.fromImage(qimage)
        self.addPixmap(self.pixmap)

问题在于,每次我调用addPixmap()时,图像都被添加到所有其他图像的顶部,并且很快我的内存不足,一切都崩溃了. 当前代码不包含任何处理步骤,它只是将numpy ndarry转换为QImage并将QPixmap添加到场景中.

The problem is everytime I call addPixmap() the image is just added on top of all the other images and soon I run out of memory and everything crashes. The current code doesn't include any of the processing steps, it just converts the numpy ndarry to a QImage and adds the QPixmap to the scene.

什么是更新QGraphicsScene的正确方法,以便我可以流式传输图像序列?

推荐答案

每次使用addPixmap()时,您都在创建新的QGraphicsPixmapItem,不必要地增加了内存.解决方案是创建一个QGraphicsPixmapItem并重新使用它.另外,处理任务可能会阻塞主线程,因此您必须使用线程来执行繁重的任务,并通过信号发送QImage.

Every time you use addPixmap() you are creating a new QGraphicsPixmapItem adding memory unnecessarily. The solution is to create a QGraphicsPixmapItem and reuse it. In addition the processing task can block the main thread so you must use a thread to do the heavy task and send the QImage through signals.

class ProcessWorker(QObject):
    imageChanged = pyqtSignal(QImage)

    def doWork(self):
        for f in self.image_list:
            img = cv2.imread(f)
            img = cv2qimage(img, False)
            self.imageChanged.emit(img)
            QThread.msleep(1)

class Widget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        lay = QVBoxLayout(self)
        gv = QGraphicsView()
        lay.addWidget(gv)
        scene = QGraphicsScene(self)
        gv.setScene(scene)
        self.pixmap_item = QGraphicsPixmapItem()
        scene.addItem(self.pixmap_item)

        self.workerThread = QThread()
        self.worker = ProcessWorker()
        self.worker.moveToThread(self.workerThread)
        self.workerThread.finished.connect(self.worker.deleteLater)
        self.workerThread.started.connect(self.worker.doWork)
        self.worker.imageChanged.connect(self.setImage)
        self.workerThread.start()


    @pyqtSlot(QImage)
    def setImage(self, image):
        pixmap = QPixmap.fromImage(image)
        self.pixmap_item.setPixmap(pixmap)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

这篇关于在QGraphicsView中播放图像序列(神秘内存泄漏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆