python 图像可视化_Python 可视化与图像处理
Python绘图工具非常丰富,在基础层面上则是 matplotlib 作为核心库;还有一些基于 matplotlib 的工具包更为便捷,在代码可读性和功能上都有显著提升效果;例如 seaborn 和 plotnine 就是比较值得推荐的选择。各工具包之间存在明显的优劣差异:
matplotlib
在Python中常用于matplotlib库中的pyplot模块,在导入该模块后默认将其命名为plt以方便访问和使用绘图功能。以下将介绍matplotlib3.2.0及后续版本的相关功能。
通用函数
plt.show()
显示绘图窗口。
plt.figure()
创建绘图新窗口并传给fig:
fig = plt.figure()
fig能够利用提供的绘图工具进行操作。它不仅支持绘制子图等功能,在不新建新窗口的情况下可以直接调用plt.function()进行绘图,默认在一个画布中显示图像
fig.add_subplot()
给窗口添加子图像,参数有三个,分别是子图像的行、列、索引。两种使用方式:
ax =fig.add_subplot(numbRow, numbCol, plotNum)
ax= fig.add_subplot(111)
第一种方法通常通过逗号分隔来明确指定三个参数。第二种方法则是将这三个整数值整合为一个三位数进行输入。这种方法必须是一个三位数,并且能够唯一识别用户的输入参数。例如 223,则表示将图像划分为 2× 2 的网格,并在第三个网格中添加一个子图像。
plt.imsave()
用于保存图像的具体需求时会遇到问题,在源代码中缺乏明确提示的情况下更容易出现参数传递顺序导致的错误情况。具体使用方法如下:
plt.imsave(name,img)#先传名字再传img数组
图例
为图像添加图例,在画图函数中添加label属性就行。如:
ax.plot(X,Y,label = '图例')
然后使用legend()函数显示所有的图例,它可以设置图例的位置等参数:
ax.legend(loc='best') #看这个介绍
显示中文(不然可能乱码):
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
图像标题
ax.set_title('aaa',fontsize=12,color='r')
坐标轴设置
ax.set_xlim([-2, 2])#设置x坐标轴范围
ax.set_ylim([-2, 2])#设置y坐标轴范围
ax.set_xlabel('xxxxxxxxxxx')#设置x坐标轴名称
ax.set_ylabel('yyyyyyyyyyy')#设置y坐标轴名称
ticks= np.arange(-2, 2, 0.3)
ax.set_xticks(ticks)#设置x轴刻度
ax.set_yticks(ticks)#设置y轴刻度
ax.axis('scaled')#设置坐标轴宽高等比于x、y范围
ax.axis('image')#类似于scaled,暂时没发现区别
ax.axis('off')#关闭坐标轴
ax.axis('equal')#图像宽高比例不变,坐标轴范围变
ax.axis('tight')#坐标轴紧紧贴合图像,不设置默认就是这个
ax.axis('square')#设置坐标轴宽高比为1:1,坐标轴跨度取较大的那个
动态图像
plt.cla()
ax.clear()
这两个函数用于将子图清空,配合暂停函数
plt.pause(0.1)
即可实现动态图像。
二维图像
contourf()和contour()
画等高线图。这两个函数差一个字母,但用法一样,区别如下:
使用方法:
ax.contourf(X, Y, Z, levels=10, alpha=0.5, cmap='jet')
X轴坐标数组(二维数组array或matrix)X用于生成网格点的位置信息,Y轴坐标数组(二维数组array或matrix)Y与X类型一致,用于表示网格点的位置信息,Z则对应于每个网格点处的函数值构成一个二维数值型数组(同样遵循二维数组array或matrix的数据结构)。在Python环境下,该网格生成过程主要依赖于numpy库中的meshgrid()函数来完成操作.等高线数量参数levels在这里被设定为10条,这一数值的选择有助于后续绘图工作的精细度调节.透明度参数alpha取值范围限定在0到1之间,本例中设置为0.5,实现了半透明效果.这种半透明特性的一个显著优势是可以将多幅图像叠加绘制在同一画布上,方便进行对比分析.颜色映射参数cmap提供了丰富的预设色彩方案可供选择,本案例中采用'jet'色谱方案进行绘图,当然也可以根据具体需求自定义颜色映射表,具体配置建议参考相关技术文档.剩余参数均具有默认预设值,因此在实际应用中可以选择跳过相应设置
效果图:
看起来不够圆润。这是因为我的计算区域设定只有7×7个单元格的原因导致绘图时按照你的单元格数量进行处理而呈现出了棱角分明的特点。有一点奇怪的是这样的有限制度下竟然能够绘制出这么多条等高线呢?推测可能是通过某种插值方法来绘制这些等高线吧?反正这个图主要是用来查看数据分布情况不需要特别精确的效果展示就可以了!如果想要更精确的效果展示则可以适当增加单元格的数量建议不要让线条之间的间隔太密集以至于线条数量超过了单元格数量的比例
另外,可以用clabel()这个函数用来标注等高线图的数值:
plt.clabel(C, inline=False, fontsize=12)
变量C被赋值为最近绘制的一条等高线图(在调用绘图函数如contour之后传递给变量C,并赋值为C = \text{contour}(...)),其中inline参数用于指示是否将标签绘制在曲线内部;同时需要调整fontsize参数以设置字体大小为适当数值。
plot()
ax.plot(x, y, ls="-", lw=2, label="plot figure", color='black',alpha=0.5...)
用来绘制二维平面上的点和线。此外,在三维空间中也同样适用,在三维坐标系中的xOy平面上进行绘制。参数说明:
x: 要画的线的各个点在x轴上的坐标(一维数组)
y: 位于y轴上的各点坐标(采用一维或二维数组表示;其中其长度与x轴数组相同;而第二维度数即代表绘制线条的数量)
ls:折线图的线条风格,这里是一个减号
lw:折线图的线条宽度
label:标记图内容的标签文本
color:颜色
alpha:透明度
还有许多可调节的参数无需一一列举,请参考链接以获取详细信息。此外,标注过的函数提供多种个性化设置方案包括但不限于color、alpha和width等参数的具体设置方式。
hist()
ax.hist(data集,bins=fifty,range=(-五到五),density=True,cumulative=True,rwidth=零点九,orientation='垂直方向')
画频次直方图,重要参数介绍:
x:待统计的一维数据
bins:柱子的数量
range:数据统计的范围
density:是否需要将该变量转译为频率密度图(即在单位区间内所占的比例?例如,在一个区间内有n个数据点,则该区间对应的频率是n除以总样本数;而如果区间宽度不一,则需要用该范围内的数据频数乘上区间长度来计算其对应的频率占比。)
cumulative:是否累加,若为真,柱子统计的是小于等于这个值的所有数据。
rwidth:柱子的宽度。
orientation:柱子是垂直还是水平放置。
以下统计一个正态分布的累计柱状图:
hist2d()与hexbin()
ax.hist2d(x,y,bins=30,cmap='Blues')
二维频率分布图。
参数设置与上文所述的一维频率分布相同。
以下展示二维正态分布的抽样频次统计图表(旁边附有colorbar(使用plt.colorbar函数),至于如何添加子图的问题目前尚在探讨中):
ax.hexbin(x,y,gridsize=30,cmap='Blues')
就是方格变成六边形格,gridsize表示格子大小:
三维图像
建立三维坐标系
fig = plt.figure() #添加绘图窗口
ax = fig.add_subplot(221,projection = '3d') #窗口内添加3d子图
ax = fig.add_subplot(projection = '3d') #如果只画一张图,可以用这个
plot_surface()
ax.plot_surface(X, Y, Z, rstride = 1, cstride = 1, cmap='jet')
画三维的曲面图,并且带有梯度颜色。
X、Y、Z代表每个网格点在各自坐标轴上的数值;cmap用于确定绘制颜色的方式;rstride参数设置为每隔一定数量的行计算一次梯度并将该梯度绘制到对应的区域;而cstride参数则应用于列方向;当它们增大时;在图上表示梯度变化的部分(称为'补丁')也会变得更大;相应地;在整个图形中会使用的'补丁'数量也会减少;如下图所示:当rstride=1时;在行方向上的每个单元格都会计算梯度并绘制相应的颜色;而当rstride=2时;则每隔一个单元格计算一次梯度并绘制颜色'补丁';同样地;c stride=1会在列方向上每个单元格都处理类似操作;c stride=2则每隔一列进行处理
外部图像
图像导入与显示
import matplotlib.pyplot as plt; import pylab; (在某些情况下,默认情况下PyLab已经在脚本环境中启用绘图功能)
img=plt.imread("image.jpg") #读取图片,读取到的是:高度×宽度×3RGB 的array数组
fig = plt.figure() #创建窗口
ax = fig.add_subplot(111) #创建子图
ax.imshow(img) #子图中添加图片
pylab.show()#显示窗口
cv2
图像批处理
从压缩包中直接读取图片
import zzip
import cv2
import numpy库
import matplotlib.pyplot库
path= 'D:/Datasets/dogs-vs-cats/train.zip'#压缩包地址
with zipfile.ZipFile(path, mode='r') as f: for name in f.namelist(): if '.jpg' not in name: continue
print(name)
with f.open(name,mode='r') as image_file:
content= image_file.read() #读取图片
img = np.asarray(bytearray(content), dtype='uint8') #将jpg格式转码
img = cv2.imdecode(img, cv2.IMREAD_COLOR) #通过OpenCV库的imdecode函数从压缩格式中解码得到该图像,并将其转换为BGR格式请注意的是,在此过程中需特别注意的是,请确保所使用的RGB顺序与预期的不同如果未正确重组该结果则可能在Matplotlib等图形库中导致颜色显示异常
b,g,r =cv2.split(img)
img= cv2.merge([r,g,b]) #将BGR拆分再重组为RGB
plt.imshow(img)
plt.show()break
图形拉伸
importcv2
cv2.resize(img,(h,w),interpolation=0)
将存在于数组中的图像进行拉伸处理至高度h和宽度w,并规定其中的interpolation参数设置为0时采用最近邻插值法以避免平滑处理操作;其他相关的插值参数(interpolation)建议参考附带链接获取更多信息
seaborn
import seaborn as sns
seaborn减少了matplotlib绘图操作的复杂性,并使生成的图表更加美观,在制作matplotlib图表时,通过设置sns.set()能够显著提升图表的专业呈现效果
mayavi
import mayavi.mlab as mlab
mayavi是一种用于绘制三维图形的库软件,在某些情况下需要特定的数据处理才能生成高质量的三维可视化效果。
然而matplotlib不具备光线追踪功能,
因此它无法实现光线追踪效果,
导致图像中缺乏遮挡效果。
其提供的绘图函数与matplotlib具有相似性,
mayavi官方提供了丰富的文档资料以及简明扼要的例子说明。
mesh()
生成三维图形表面类似于matplotlib中的plot_surface函数,在使用过程中需要注意的是 meshgrid 的索引顺序可能存在问题;建议最好使用 mgrid 来创建网格以避免混淆。
mlab.mesh(x, y, z )#绘制光滑表面
mlab.mesh(x, y, z, representation="wireframe", line_width=1.0)#绘制线而不是表面
下图画了一个卷起来的彩带:
代码如下:
importmayavi.mlab as mlabimportnumpy as np
roll= 10r= 0.5w= 0.8theta= np.linspace(np.pi0.5,np.pi2roll,num=roll100)[:,np.newaxis]
h= np.linspace(-1,1,num=2)[np.newaxis,:]+0.5x= y = z =np.zeros([len(theta),len(h[0,:])])
x= x + np.cos(theta)thetar/np.pi
y= y + np.sin(theta)thetar/np.pi
z= z + h - theta*w/np.piprint(y.shape,z.shape)
mlab.mesh(x, y, z)#绘制光滑表面
mlab.show()
plot3d()
绘制三维坐标系中的曲线图形类似于matplotlib的plot函数。同样建议使用mgrid生成网格。
mlab.plot3d(x,y,z)
numpy
用numpy的一些函数生成格式化的绘图数据。
linspace()
通过linspace(a, b, n)函数可以生成一个包含端点a和b在内的等差数列(即插值序列),该序列共有n个元素。这种等差数列采用的是固定类型的数组(如float),而Python中的列表(list)则是动态类型的。需要注意的是,在array中所有元素必须具有相同的数值类型(如浮点数),因此无法存储任意类型的元素;相反,在Python的标准列表(list)中可以存储任何类型的对象。值得注意的是,在NumPy库中,默认情况下定义了一种核心数组结构(类似于C++的数组),这种特殊的数据结构支持快速随机访问和高效运算;因此,在处理大规模同种数据时建议使用这种基于NumPy的核心数组形式以获得更好的性能表现
具体使用和其他参数:
meshgrid()
该方法用于生成对应类型的网格结构(其中,在每个维度上都是由二维或三维列表构成),同时可用于绘制梯度图以及其他类似图形。具体实现时需根据需求选择相应的数据组织方式,并按照预设规则进行绘图操作。
[X, Y] = meshgrid(x,y)或者Python还支持[X,Y] = meshgrid(x,y),即使不加方括号也可以使用;直接赋值给变量A即为[A] = meshgrid(x,y),传递给一个变量时同样适用;不过在后续操作中需要注意一些细节。
2. [X, Y] = meshgrid(x)与[X, Y] = meshgrid(x, x)是等同的
3. [X, Y, Z] = meshgrid(x, y, z)生成三维的网格
生成方式在二维X-Y平面中遵循先Y后X的原则,在三维空间中的排列顺序为Y-X-Z。举例而言,在一个三维网格环境中查询x=2,y=7,z=3的位置时,Y轴坐标对应的值可以通过访问数组元素Y[7][2][3]来确定。同样地,在二维网格环境中若要查询x=2,y=7位置的X轴坐标,则可以通过访问数组元素X[7][2]来实现相应的数据提取操作。
下图显示8*3的网格的X的列表:
mgrid
注意
importnumpy as np
a= np.mgrid[0:10:2,0:10:1]print(a)
索引中的第二个冒号用于指定步长值,默认情况下步长值为1,并且该步长值不包括在最终结果中。若要指定数值范围内的元素数量,则应使用复合整数值(如5j),这种情况下步长值将被设定为1,并且结果将包含最终的那个数值
特定图像样例
