介绍
前面讲述的都是一维插值,即节点为一维变量,插值函数是一元函数(曲线)。若节点是二维的,插值函数就是二元函数,即曲面。如在某区域测量了若干点(节点)的高程(节点值),为了画出较精确的等高线图,就要先插入更多的点(插值点),计算这些点的高程(插值)。
插值节点为网络节点
已知m x n个节点:(xi,yj,zij)(i=1,2,…,m;j=1,2,…,n),且x1<…<xm;y.<…<yn。求点(x,y)处的插值z。
Matlab中有一些计算二维插值的命令。如:
z = interp2( x0 ,y0 ,z0 ,x,y, ‘method’)
其中:x0,y0分别为m维和n维向量,表示节点;z0为n x m矩阵,表示节点值;x,y为一维数组,表示插值点,x与y应是方向不同的向量,即-一个是行向量,另一个是列向量;z为矩阵,它的行数为y的维数,列数为x的维数,表示得到的插值;'method’的用法一维插值。
如果是三次样条插值,可以使用命令
pp = csapel( {x0 ,y0} ,z0 , conds ,valconds),z = fnval(pp,{x,y})
其中:x0,y0分别为m维和n维向量;z0为m x n矩阵;z为矩阵,它的行数为x的维数,列数为y的维数,表示得到的插值,具体使用方法同一维插值。
插值节点为散乱节点
已知n个节点(xi,yi,zi),i=1,2,n,求点(x,y)处的插值z。
对上述问题, Matlab中提供了插值函数griddata ,其格式为
ZI = griddata(x,y,z,XI,YI)
其中:x、y、z均为n维向量,指明所给数据点的横坐标、纵坐标和竖坐标;向量XI、YI是给定的网格点的横坐标和纵坐标;返回值ZI为网格(XI, YI)处的函数值。XI 与YI应是方向不同的向量.即一个是行向量.另-一个是列向量。
图像模糊处理–样条插值
某二维图像表达式为 (𝑥+𝑦)e−5𝑥2+𝑦2 完成图像的二维插值使其变清晰。
np,mgrid[维度 1,…, 维度 n]
维度格式(a: b:cj )cj 表点数
import numpy as np from scipy import interpolate import pylab as pl import matplotlib as mpl def func (x,y): return (x+y)*np.exp(-5.0*(x**2+y**2)) pl.figure(figsize =(12,9)) #X-Y 轴分为 15*15 的网格 y, x = np.mgrid[-1:1:15j, -1:1:15j] # 计算每个网格点上函数值 fvals = func (x,y) # 三次样条二维插值 newfunc = interpolate.interp2d(x, y, fvals , kind='cubic') # 计算 100*100 网格上插值 xnew = np.linspace(-1,1,100) ynew = np.linspace(-1,1,100) fnew = newfunc(xnew ,ynew) # 可视化 # 让 imshow 的参数 interpolation 设置为 'nearest' 方便比较插值处理 pl.subplot(121) im1 = pl.imshow (fvals , extent = [-1,1, -1,1], cmap = mpl.cm.hot,interpolation='nearest', origin="lower") pl.colorbar(im1) pl.subplot(122) im2 = pl.imshow(fnew , extent = [-1,1, -1,1], cmap = mpl.cm.hot, interpolation='nearest', origin="lower") pl.colorbar(im2) pl.show()
左图为原始数据,右图为二维插值结果图
二维插值的三维图
某二维图像表达式为 (𝑥+𝑦)e−5𝑥2+𝑦2 完成三维图像
的二维插值可视化。
rstride 行跨度
cstride 列跨度
antialised 抗 锯齿效果
import numpy as np from mpl_toolkits.mplot3d import Axes3D import matplotlib as mpl from scipy import interpolate import matplotlib.cm as cm import matplotlib.pyplot as plt def func(x, y): return (x + y) * np.exp(-5.0 * (x ** 2 + y ** 2)) # X-Y轴分为20*20的网格 x = np.linspace(-1, 1, 20) y = np.linspace(-1, 1, 20) x, y = np.meshgrid(x, y) # 20*20的网格数据 fvals = func(x, y) # 计算每个网格点上的函数值 15*15的值 fig = plt.figure(figsize=(18,10)) # 设置图的大小 # Draw sub-graph1 ax = plt.subplot(1, 2, 1, projection='3d') # 设置图的位置 surf = ax.plot_surface(x, y, fvals, rstride=2, cstride=2, cmap=cm.coolwarm, linewidth=0.5, antialiased=True) # 第四个第五个参数表示隔多少个取样点画一个小面,第六个表示画图类型,第七个是画图的线宽,第八个表示抗锯齿 ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('f(x, y)') # 标签 plt.colorbar(surf, shrink=0.5, aspect=5) # 标注 # 二维插值 newfunc = interpolate.interp2d(x, y, fvals, kind='cubic') # newfunc为一个函数 # 计算100*100的网格上的插值 xnew = np.linspace(-1, 1, 100) # x ynew = np.linspace(-1, 1, 100) # y fnew = newfunc(xnew, ynew) # 仅仅是y值 100*100的值 np.shape(fnew) is 100*100 print(fnew) xnew, ynew = np.meshgrid(xnew, ynew) ax2 = plt.subplot(1, 2, 2, projection='3d') surf2 = ax2.plot_surface(xnew, ynew, fnew, rstride=2, cstride=2, cmap=cm.coolwarm, linewidth=0.5, antialiased=True) ax2.set_xlabel('xnew') ax2.set_ylabel('ynew') ax2.set_zlabel('fnew(x, y)') plt.colorbar(surf2, shrink=0.5, aspect=5) # 标注 plt.show()
左图的二维数据集的函数值由于样本较少,会显得粗糙 。
而右图对二维样本数据进行三次样条插值,拟合得到更多数据点的样本值,绘图后图像明显 光滑多了。
每日一句
If you are doing your best,you will not have to worry about failure.(如果你竭尽全力,你就不用担心失败)