作为标题所述,我正在尝试将fig
转换为PIL.Image
。我目前可以通过首先将fig
保存到磁盘,然后使用Image.open()
打开该文件,但是该过程的时间比预期的时间更长,我希望通过跳过本地节省的步骤,它会更快一些。
这是我到目前为止所拥有的:
# build fig
figsize, dpi = self._calc_fig_size_res(img_height)
fig = plt.Figure(figsize=figsize)
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.imshow(torch.from_numpy(S).flip(0), cmap = cmap)
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)
ax.axis('tight'); ax.axis('off')
# export
fig.savefig(export_path, dpi = dpi)
# open image as PIL object
img = Image.open(export_path)
构建无花果后,我已经尝试这样做(它将在出口阶段之前(:
pil_img = Image.frombytes('RGB', canvas.get_width_height(), canvas.tostring_rgb())
但没有显示整个图像。看起来这是左上角的一裁,但它可能只是数据的怪异表示 - 我正在使用频谱图,因此图像相当抽象。
编辑#2
PIL.Image.frombytes('RGB',
fig.canvas.get_width_height(),fig.canvas.tostring_rgb())
与下面的35/40ms相比,花费约2毫米。
这是我到目前为止找到的最快方法。
我今天也一直在看这个。
在matplotlib文档中,Savefig函数具有此。
pil_kwargsdict,可选的附加关键字参数已通过保存图形时,要pil.image.save。仅适用于格式使用枕头(即JPEG,TIFF(保存的,(如果关键字是(设置为非单位值(png。
这一定意味着它已经是PIL图像,但我看不到它。
您可以关注此
matplotlib:将图保存到numpy数组
将其放入numpy数组,然后进行
PIL.Image.fromarray(array)
您可能需要使用Array [:, :, ::-1]
编辑:
我已经测试了到目前为止的各种方式。
import io
def save_plot_and_get():
fig.savefig("test.jpg")
img = cv2.imread("test.jpg")
return PIL.Image.fromarray(img)
def buffer_plot_and_get():
buf = io.BytesIO()
fig.savefig(buf)
buf.seek(0)
return PIL.Image.open(buf)
def from_canvas():
lst = list(fig.canvas.get_width_height())
lst.append(3)
return PIL.Image.fromarray(np.fromstring(fig.canvas.tostring_rgb(),dtype=np.uint8).reshape(lst))
结果
%timeit save_plot_and_get()
35.5 ms±148 µs每循环(平均±std。dev。7行,每个循环10循环(
%timeit save_plot_and_get()
35.5 ms±142 µs每循环(平均±std。dev。7行,每个循环10个(
%timeit buffer_plot_and_get()
40.4 ms±152 µs每循环(平均±std。dev。7次,每个循环10循环(
我使用以下功能:
def fig2img(fig):
"""Convert a Matplotlib figure to a PIL Image and return it"""
import io
buf = io.BytesIO()
fig.savefig(buf)
buf.seek(0)
img = Image.open(buf)
return img
示例用法:
import numpy as np
import matplotlib.pyplot as plt
from PIL import Image
x = np.arange(-3,3)
plt.plot(x)
fig = plt.gcf()
img = fig2img(fig)
img.show()
我将其标记为重复,然后关闭它,因为我使用了错误的链接。
无论如何,答案可能在这里:
如何将Pylab图保存到可以读取pil image的内存文件中?
不幸的是,这并没有导致任何速度提高,但是如果有人有类似问题,我仍然在下面发布我的特定解决方案:
# build fig
figsize, dpi = self._calc_fig_size_res(img_height)
fig = plt.Figure(figsize = figsize)
canvas = FigureCanvas(fig)
ax = fig.add_subplot(111)
ax.imshow(torch.from_numpy(S).flip(0), cmap = camp)
fig.subplots_adjust(left = 0, right = 1, bottom = 0, top = 1)
ax.axis('tight'); ax.axis('off')
# convert to PIL Image object
buf = io.BytesIO()
fig.savefig(buf, format='png', dpi = dpi)
buf.seek(0)
pil_img = deepcopy(Image.open(buf))
buf.close()