我有一个 PyQT4 应用程序,可以在 Matplotlib 图中显示中等大小的图像。我显示的测试图像约为 5Mb(2809 x 1241 像素)。顺便说一下,我使用GDAL读取数据。图像被读入数组,其中无数据值被屏蔽。然后用标准化值和指定的颜色图显示
它似乎使用过多的内存来显示 5mb 的文件。我看到的是,需要 140mb 的内存才能显示以全分辨率读取的图像。(使用 imshow 的应用程序注释掉使用了 60mb 内存,而使用它的应用程序则使用了 206MB)当图像以多个图形显示时,问题变得更糟,因为每个图形都使用额外的 200m 内存。当内存使用量达到 700-900 MB 范围时,显示大约 3 或 4 个数字,应用程序开始陷入困境。
我了解 matplotlib 必须存储所有像素,即使它只显示下采样的子集以匹配屏幕分辨率。我可能最终会编写例程来仅读取一定数量的像素以匹配图形大小。但由于该应用程序将在 8 个独立的屏幕上显示最多 8 个地图,我担心它仍然使用过多的内存。
所以我的问题是:
1)这似乎是用于显示简单的颜色映射图像的过多内存量?对我来说确实如此。
2)我可以做些什么来减少内存使用吗?例如使用整数数据类型、释放内存等。
3)我应该使用哪些其他策略来处理这种内存使用?例如下采样(在全屏分辨率 1900x1200 下可能不是很有效)、切换到 64 位架构等
谢谢,下面的代码
import sys, os, random
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import matplotlib
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.colors as colors
import numpy as np
from osgeo import gdal, gdalconst
gridfile = r"i:\vistrails\workingfiles\secondseason\secondseason_workfile_2012_02_28b\brt_1\brt_prob_map.tif"
class AppForm(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.create_main_frame()
ds = gdal.Open(gridfile, gdal.GA_ReadOnly)
ary = ds.GetRasterBand(1).ReadAsArray(buf_ysize=500, buf_xsize=300)
ndval = ds.GetRasterBand(1).GetNoDataValue()
rasterdata = np.ma.masked_array(ary, mask=(ary==ndval))
del ary
self.axes.imshow(rasterdataint, cmap=matplotlib.cm.jet)
del rasterdata
def create_main_frame(self):
self.main_frame = QWidget()
# Create the mpl Figure and FigCanvas objects.
# 5x4 inches, 100 dots-per-inch
#
self.dpi = 100
self.fig = Figure((5.0, 4.0), dpi=self.dpi)
self.canvas = FigureCanvas(self.fig)
self.canvas.setParent(self.main_frame)
self.axes = self.fig.add_subplot(111)
self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)
vbox = QVBoxLayout()
vbox.addWidget(self.canvas)
vbox.addWidget(self.mpl_toolbar)
self.main_frame.setLayout(vbox)
self.setCentralWidget(self.main_frame)
def main():
app = QApplication(sys.argv)
form = AppForm()
form.show()
app.exec_()
if __name__ == "__main__":
main()
Run Code Online (Sandbox Code Playgroud)
imshow()已注意到使用的内存问题,如下所示。
1/ 升级
正如此处提到的,升级到最新版本的 mpl 可能会解决该问题。
2/ 太尔
作为替代方案,您可以使用 PIL 库。
当它转到 jpg 文件时,imshow()正在使用 PIL(如果已安装)。您可以直接使用 PIL 模块,如此处所述。