双三次插值,双三次插值算法

内容广告上

我用Python编程语言开发了双三次插值来演示给一些本科生。

方法如wikipedia所述,

代码运行良好,只是得到的结果与使用scipy库时得到的结果略有不同。

插值代码在下面的函数bicubic_interpolation中显示。import numpy as np

import matplotlib.pyplot as plt

from mpl_toolkits import mplot3d

from scipy import interpolate

import sympy as syp

import pandas as pd

pd.options.display.max_colwidth = 200

%matplotlib inline

def bicubic_interpolation(xi, yi, zi, xnew, ynew):

# check sorting

if np.any(np.diff(xi) < 0) and np.any(np.diff(yi) < 0) and稳重的花卷/p>

np.any(np.diff(xnew) < 0) and np.any(np.diff(ynew) < 0):

raise ValueError('data are not sorted')

if zi.shape != (xi.size, yi.size):

raise ValueError('zi is not set properly use np.meshgrid(xi, yi)')

z = np.zeros((xnew.size, ynew.size))

deltax = xi[1] - xi[0]

deltay = yi[1] - yi[0]

for n, x in enumerate(xnew):

for m, y in enumerate(ynew):

if xi.min() <= x <= xi.max() and yi.min() <= y <= yi.max():

i = np.searchsorted(xi, x) - 1

x3 = x1+2*deltax

f00 = zi[i-1, j-1] #row0 col0 >> x0,y0

f01 = zi[i-1, j] #row0 col1 >> x1,y0

f02 = zi[i-1, j+1] #row0 col2 >> x2,y0

f10 = zi[i, j-1] #row1 col0 >> x0,y1

f11 = p00 = zi[i, j] #row1 col1 >> x1,y1

f12 = p01 = zi[i, j+1] #row1 col2 >> x2,y1

f20 = zi[i+1,j-1] #row2 col0 >> x0,y2

f21 = p10 = zi[i+1,j] #row2 col1 >> x1,y2

f22 = p11 = zi[i+1,j+1] #row2 col2 >> x2,y2

if 0 < i < xi.size-2 and 0 < j < yi.size-2:

f03 = zi[i-1, j+2] #row0 col3 >> x3,y0

f13 = zi[i,j+2] #row1 col3 >> x3,y1

f23 = zi[i+1,j+2] #row2 col3 >> x3,y2

f30 = zi[i+2,j-1] #row3 col0 >> x0,y3

f31 = zi[i+2,j] #row3 col1 >> x1,y3

f32 = zi[i+2,j+1] #row3 col2 >> x2,y3

f33 = zi[i+2,j+2] #row3 col3 >> x3,y3

elif i<=0:

f03 = f02 #row0 col3 >> x3,y0

f13 = f12 #row1 col3 >> x3,y1

f23 = f22 #row2 col3 >> x3,y2

f30 = zi[i+2,j-1] #row3 col0 >> x0,y3

f31 = zi[i+2,j] #row3 col1 >> x1,y3

f32 = zi[i+2,j+1] #row3 col2 >> x2,y3

f33 = f32 #row3 col3 >> x3,y3

elif j<=0:

f03 = zi[i-1, j+2] #row0 col3 >> x3,y0

f13 = zi[i,j+2] #row1 col3 >> x3,y1

f23 = zi[i+1,j+2] #row2 col3 >> x3,y2

f30 = f20 #row3 col0 >> x0,y3

f31 = f21 #row3 col1 >> x1,y3

f32 = f22 #row3 col2 >> x2,y3

f33 = f23 #row3 col3 >> x3,y3

elif i == xi.size-2 or j == yi.size-2:

f03 = f02 #row0 col3 >> x3,y0

f13 = f12 #row1 col3 >> x3,y1

f23 = f22 #row2 col3 >> x3,y2

f30 = f20 #row3 col0 >> x0,y3

f31 = f21 #row3 col1 >> x1,y3

f32 = f22 #row3 col2 >> x2,y3

f33 = f23 #row3 col3 >> x3,y3

f = np.array([p00, p01, p10, p11,

a = A@f

a = a.reshape(4,4).transpose()

z[n,m] = np.array([1, px, px**2, px**3]) @ a @ np.array([1, py, py**2, py**3])

return z

我正在测试函数的数据如下所示。我将结果与scipy和真模型(函数f)进行比较。def f(x,y):

return np.sin(np.sqrt(x ** 2 + y ** 2))

x = np.linspace(-6, 6, 11)

xx, yy = np.meshgrid(x, y)

z = f(xx, yy)

x_new = np.linspace(-6, 6, 100)

xx_new, yy_new = np.meshgrid(x_new, y_new)

z_new = bicubic_interpolation(x, y, z, x_new, y_new)

z_true = f(xx_new, yy_new)

f_scipy = interpolate.interp2d(x, y, z, kind='cubic')

z_scipy = f_scipy(x_new, y_new)

fig, ax = plt.subplots(2, 2, sharey=True, figsize=(16,12))

img0 = ax[0, 0].scatter(xx, yy, c=z, s=100)

ax[0, 0].set_title('original points')

fig.colorbar(img0, ax=ax[0, 0], orientation='vertical', shrink=1, pad=0.01)

img1 = ax[0, 1].imshow(z_new, vmin=z_new.min(), vmax=z_new.max(), origin='lower',

ax[0, 1].set_title('bicubic our code')

fig.colorbar(img1, ax=ax[0, 1], orientation='vertical', shrink=1, pad=0.01)

img2 = ax[1, 0].imshow(z_scipy, vmin=z_scipy.min(), vmax=z_scipy.max(), origin='lower',

ax[1, 0].set_title('bicubic scipy')

fig.colorbar(img2, ax=ax[1, 0], orientation='vertical', shrink=1, pad=0.01)

img3 = ax[1, 1].imshow(z_true, vmin=z_true.min(), vmax=z_true.max(), origin='lower',

ax[1, 1].set_title('true model')

fig.colorbar(img3, ax=ax[1, 1], orientation='vertical', shrink=1, pad=0.01)

plt.subplots_adjust(wspace=0.05, hspace=0.15)

plt.show()

 

a00, a01, a02, a03, a10, a11, a12, a13 = syp.symbols('a00 a01 a02 a03 a10 a11 a12 a13')

a20, a21, a22, a23, a30, a31, a32, a33 = syp.symbols('a20 a21 a22 a23 a30 a31 a32 a33')

p = a00 + a01*y + a02*y**2 + a03*y**3稳重的花卷/p>

+ a10*x + a11*x*y + a12*x*y**2 + a13*x*y**3稳重的花卷/p>

+ a20*x**2 + a21*x**2*y + a22*x**2*y**2 + a23*x**2*y**3稳重的花卷/p>

+ a30*x**3 + a31*x**3*y + a32*x**3*y**2 + a33*x**3*y**3

df = pd.DataFrame(columns=['function', 'evaluation'])

for i in range(2):

for j in range(2):

function = 'p({}, {})'.format(j,i)

df.loc[len(df)] = [function, p.subs({x:j, y:i})]

for i in range(2):

for j in range(2):

function = 'px({}, {})'.format(j,i)

df.loc[len(df)] = [function, px.subs({x:j, y:i})]

for i in range(2):

for j in range(2):

function = 'py({}, {})'.format(j,i)

df.loc[len(df)] = [function, py.subs({x:j, y:i})]

for i in range(2):

for j in range(2):

function = 'pxy({}, {})'.format(j,i)

df.loc[len(df)] = [function, pxy.subs({x:j, y:i})]

eqns = df['evaluation'].tolist()

symbols = [a00,a01,a02,a03,a10,a11,a12,a13,a20,a21,a22,a23,a30,a31,a32,a33]

A = syp.linear_eq_to_matrix(eqns, *symbols)[0]

A = np.array(A.inv()).astype(np.float64)

print(df)

print(A)

 

 

<ppddlf知道bicubic_interpolation函数的问题在哪里,为什么它与scipy得到的结果略有不同?< p="" style="margin: 0px; padding: 0px; max-width: 100%;"></ppddlf知道bicubic_interpolation函数的问题在哪里,为什么它与scipy得到的结果略有不同?<>

非常感谢您的帮助!

内容广告下