matplotlib中应知应会numpy存储、交换图像
numpy的ndarray是mpl官方推荐的输入数据结构
mpl官方推荐绘图时,应以numpy的ndarray数据结构输入数据。虽然有时用pandas中的两个数据结构、python的list等数据结构也可以,但不能保证都能成功。
这是因为numpy的ndarray的结构设计天生具有保存、交换、变换图像数据的优势。
本篇:
- 将一幅image转换为ndarray保存起来;
- 再在mpl的fig中读取保存的ndarray,并显示出该image;
- 并分析ndarray保存image的基本思想。
在mpl中,很多对象的一些参数设置都要借助ndarray的变换来实现一些绘图效果。因此理解ndarray保存图像,对后面学习相关内容非常有帮助。
阅读前两篇关于像素和分辨率的文章,会让你阅读本篇更轻松。
将一幅image存入ndarray
仍然以上篇中用到的这幅image为例:原图像可以到"Python草堂“QQ群下载。
输入如下代码:
import numpy as npfrom PIL import Imageim_source = Image.open('./assets/img2array.jpg') #应该修改成你的image保存的路径im_ar = np.array(im_source)np.save('./assets/imgdata.npy',im_ar)# 同样要修改为你保存数据文件的目录im_ar.shape
注意:上面的代码需要Python的 PIL库的支持
上面的代码完成了这么几件事:
- 读取了磁盘上的"img2array.jpg"图像;
- 将图像数据转换为数组;
- 将数组保存为磁盘文件“imgdata.npy"
- 查看了这个数组的形状是:(344, 250, 3)
ndarray保存图像的方式解析
上面的第4个任务显示,图像数据被保存在一个(344, 250, 3)的3维数组中。
你如果读了上一篇,应该记得,这个(344, 250)正是该image的像素大小:
没错,numpy就是用这样一个3维数组保存image数据的:
- image高度上的像素个数是ndarray的行数,这里是344行;
- image宽度上的像素个数是ndarray的列数,这里是255列;
- 行列交叉位置,就是图像的坐标位置了,即每个像素单元格上,再用一个有3个元素一维数组表示该像素的颜色 [R, G, B] 值。
如下图所示,每个格子是一个像素,每个格子上的3元素的列表就是该像素上的 [R, G, B] 值。
使用:im_ar[12][27]检索,返回一个array([247, 176, 148]
我们就知道第13行,第28列上的像素的颜色是 [247, 176, 148],在配色软件上检索这个值:
numpy就是这样用ndarray保存image的。是不是豁然开朗了!
读取ndarray,显示出图像
我将生存的ndarray数据文件放到了"Python草堂"群文件的DataSets文件中,供大家下载。
输入如下代码:
注意:这是纯面向对象绘图的代码,所以看起来代码比较多,但每一步在做什么,我都很清楚。
from matplotlib.backends.backend_agg import FigureCanvasAggfrom matplotlib.figure import Figure,SubplotParamsimport numpy as npfig =Figure(figsize=(1.1,1.4), dpi=300, facecolor=(239/256,239/256,239/256), edgecolor=(82/256,101/256,155/256), linewidth=2.0, frameon=True, )canvas = FigureCanvasAgg(fig)imgdata = np.load('./assets/imgdata.npy',)fig.figimage(imgdata,xo=40,yo=30,origin='upper')s, (width, height) = canvas.print_to_buffer() from PIL import Imageim = Image.frombytes("RGBA