Python matplotlib的imshow函数速度较慢

6
我希望使用imshow显示一张图片。这是一张1600x1200的灰度图像,我发现matplotlib使用float32来解码值。加载这张图片需要大约2秒钟的时间,我想知道是否有任何方法可以使其更快。关键是我并不真正需要高分辨率的图片,我只想标记某些点并将图片作为背景绘制。因此,

  • 第一个问题:对于这样的图像,2秒钟的性能表现良好还是可以加速。
  • 第二个问题:如果性能表现良好,如何通过降低分辨率来加速处理过程。重要提示:最终我仍然希望图像可以延伸到1600x1200像素。

我的代码:

import matplotlib
import numpy

plotfig     = matplotlib.pyplot.figure()
plotwindow  = plotfig.add_subplot(111)
plotwindow.axis([0,1600,0,1200])
plotwindow.invert_yaxis() 
img = matplotlib.pyplot.imread("lowres.png")
im  = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray,origin='centre')
plotfig.set_figwidth(200.0)
plotfig.canvas.draw()
matplotlib.pyplot.show()

这是我想做的事情。如果保存在lowres.png中的图片分辨率低于1600x1200(即400x300),它将像应该显示的那样显示在左上角。如何将其缩放到整个1600x1200像素区域?如果运行此程序,则下面的canvas.draw()命令是慢速部分。也许有一种方法可以加快此命令吗?
提前感谢您!
根据您的建议,我已经更新到最新版本的matplotlib
版本1.1.0svn,检查8988
我还使用以下代码:
img = matplotlib.pyplot.imread(pngfile)
img *= 255
img2 = img.astype(numpy.uint8)
im  = self.plotwindow.imshow(img2,cmap=matplotlib.cm.gray, origin='centre')

尽管如此,仍需要大约2秒钟才能显示图像...还有其他的想法吗?

补充一下:我发现了以下功能

zoomed_inset_axes

因此,原则上matplotlib应该能够完成任务。在那里,也可以以“缩放”的方式绘制图片...


1
你为什么想要加快速度?是为了增加GUI的响应能力还是因为你需要显示成千上万张图片,每张图片2秒钟还不够快?答案可能因原因而异。一般来说,如果你使用numpy自己的方法,在Python中坚持使用,你很难超越它们的性能,而且根据方法的不同,即使在本地代码中,你也可能很难改进它们。对我来说,加载1600x1200像素的图像需要2秒钟是可以接受的。 - Chinmay Kanchi
我想要比2秒更快的原因很简单。当程序在使用时,人们应该能够快速浏览图片以获得概述。0.5秒的时间是很好的选择。因此,分辨率并不是那么重要。一旦选择了有趣的图像,程序可以加载完整分辨率的文件... - r6d9
3个回答

5
数据大小与最终图像的像素尺寸无关。
如果您不需要高分辨率图像,可以通过对数据进行降采样来更快地生成图像。如果您的数据以numpy数组的形式存在,则可以使用以下方法快速处理数据:每隔 n 行、n 列取一个值:data[::n,::n]
您可以使用 fig.set_size_inchesplt.savefigdpi 参数来控制输出图像的像素尺寸。
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

data=np.arange(300).reshape((10,30))
plt.imshow(data[::2,::2],cmap=cm.Greys)

fig=plt.gcf()
# Unfortunately, had to find these numbers through trial and error
fig.set_size_inches(5.163,3.75)  
ax=plt.gca()
extent=ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())

plt.savefig('/tmp/test.png', dpi=400,
            bbox_inches=extent)

enter image description here


谢谢您的回答和示例代码!据我所理解,这段代码仅影响它保存的文件。然而,在我的情况下,我想要显示具有此大小的文件。为了澄清这一点,我在上面添加了我的示例代码。 - r6d9
1
@sebastian:显示低分辨率图像需要2秒钟吗?如果是这样,我不知道你如何显著加快速度。其次,matplotlib并不是以速度为高优先级而设计的。使用imagemagick先生成所有缩略图,然后使用Tk、Gtk、Qt或wx等GUI框架来显示图像可能会更快。最后,我认为matplotlib无法控制图形窗口的大小和位置。至少在Linux上,这由窗口管理器控制。 - unutbu
不,显示分辨率为1200x1600像素的高清图像需要2秒钟。我认为可以通过将一个像素变成16个像素来显示一个300x400像素大小的图片,并告诉matplotlib将其显示为1200x1600像素大小的图片。 - r6d9

2
您可以通过在matplotlibrc文件中添加以下行来禁用imshow的默认插值(通常位于〜/ .matplotlib / matplotlibrc):

image.interpolation : none

结果是更快的渲染和更清晰的图像。

1
我找到了一个解决方案,只要需要显示低分辨率图像就可以。可以使用以下代码行来实现:

im  = matplotlib.pyplot.imshow(img,cmap=matplotlib.cm.gray, origin='centre',extent=(0,1600,0,1200))

extent参数告诉matplotlib在这个范围内绘制图形。如果使用分辨率较低的图像,则可以大大加快进程。尽管如此,如果有人知道其他技巧以使进程更快,以便在相同速度下使用更高的分辨率,那将是很棒的。

感谢所有考虑过我的问题的人,欢迎提出更多意见!


1
这不会裁剪您的图像并仅显示其中的一小部分吗? - endolith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接