python - 在 QGraphicsView 中播放图像序列(神秘的内存泄漏)
问题描述
我正在尝试使用 OpenCV 和 PyQt5 处理图像序列并制作结果视频。我有一些代码循环遍历一个目录,读取图像,并尝试将它们显示在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 添加到场景中。
更新 QGraphicsScene 以便我可以流式传输一系列图像的正确方法是什么?
解决方案
每次使用时,addPixmap()
您都在不必要地创建新的QGraphicsPixmapItem
添加内存。解决方案是创建一个QGraphicsPixmapItem
并重用它。此外,处理任务会阻塞主线程,因此您必须使用线程来完成繁重的任务并发送QImage
直通信号。
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_())
推荐阅读
- html - 缩进任何不以大项目符号字符开头的环绕文本行?
- vue.js - 部署到heroku后,修改vuejs组件和laravel app的app.scss没有更新
- angular - 如何允许一个 Angular 元素的输出事件更新另一个 Angular 元素的值?
- python - 在 Kivy 的屏幕之间传递文本输入
- jupyter-notebook - 如何链接到保存为 Reveal.JS 的 Jupyter Notebook 中的幻灯片?
- postgresql - 将附加节点附加到 postgres 主服务器作为热备用
- c# - MessageBox 和 while 循环 C#
- ios - 在 iOS 应用程序中添加应用程序事件会产生未声明的标识符“AppEvent”
- python - 在 Keras 中,为什么测试加载了 load_model 的模型比 load_weights 慢得多?
- javascript - 用js点击复选框