Playing image sequence in QGraphicsView (Mysterious Memory Leak)(在 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 中播放图像序列(神秘的内存泄漏)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 QGraphicsView 中播放图像序列(神秘的内存泄漏)
基础教程推荐
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 筛选NumPy数组 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01