16

我是 python 新手。我在由一组给定点定义的 3D 空间中有一条线曲线。谁能建议我如何使用带有 scipy 包的样条函数的插值来获得曲线的样条系数,就像 MATLAB 中的 spline.coeff 函数一样?谢谢!

编辑:

我用过

tck = interpolate.SmoothBivariateSpline(pts2[:,0], pts2[:,1], pts2[:,2])
test_pts = pts2[:,2]-tck.ev(pts2[:,0], pts2[:,1])
print test_pts

但这显然适用于曲面,而不适用于直线曲线是一个包含点坐标的pts2Nx3numpy array

好的,我知道我做错了什么。我的输入点太少了。现在我有另一个问题。函数 get_coeffs 应该在每个不返回样条系数。这些系数按什么顺序返回?我有一个代表结的 79 tx 和 79 ty 的数组,当我调用函数来调用结时,我得到一个 1x5625 的数组

4

1 回答 1

31

I too am new to python, but my recent searching led me to a very helpful scipy interpolation tutorial. From my reading of this I concur that the BivariateSpline family of classes/functions are intended for interpolating 3D surfaces rather than 3D curves.

For my 3D curve fitting problem (which I believe is very similar to yours, but with the addition of wanting to smooth out noise) I ended up using scipy.interpolate.splprep (not to be confused with scipy.interpolate.splrep). From the tutorial linked above, the spline coefficients your are looking for are returned by splprep.

The normal output is a 3-tuple, (t,c,k) , containing the knot-points, t , the coefficients c and the order k of the spline.

The docs keep referring to these procedural functions as an "older, non object-oriented wrapping of FITPACK" in contrast to the "newer, object-oriented" UnivariateSpline and BivariateSpline classes. I would have preferred "newer, object-oriented" myself, but as far as I can tell UnivariateSpline only handles the 1-D case whereas splprep handles N-D data directly.

Below is a simple test-case that I used to figure out these functions:

import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
from mpl_toolkits.mplot3d import Axes3D


# 3D example
total_rad = 10
z_factor = 3
noise = 0.1

num_true_pts = 200
s_true = np.linspace(0, total_rad, num_true_pts)
x_true = np.cos(s_true)
y_true = np.sin(s_true)
z_true = s_true/z_factor

num_sample_pts = 80
s_sample = np.linspace(0, total_rad, num_sample_pts)
x_sample = np.cos(s_sample) + noise * np.random.randn(num_sample_pts)
y_sample = np.sin(s_sample) + noise * np.random.randn(num_sample_pts)
z_sample = s_sample/z_factor + noise * np.random.randn(num_sample_pts)

tck, u = interpolate.splprep([x_sample,y_sample,z_sample], s=2)
x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck)
u_fine = np.linspace(0,1,num_true_pts)
x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck)

fig2 = plt.figure(2)
ax3d = fig2.add_subplot(111, projection='3d')
ax3d.plot(x_true, y_true, z_true, 'b')
ax3d.plot(x_sample, y_sample, z_sample, 'r*')
ax3d.plot(x_knots, y_knots, z_knots, 'go')
ax3d.plot(x_fine, y_fine, z_fine, 'g')
fig2.show()
plt.show()

output plot

于 2014-10-23T20:28:27.547 回答