假设我有一组x,y坐标,用于标记沿轮廓的点。有没有办法可以构建轮廓的样条曲线表示,我可以在其长度上的特定位置进行求值并恢复插值的x,y坐标?
通常情况下,X和Y值之间不存在1:1的对应关系,因此单变量样条对我没有好处。双变量样条曲线会很好,但据我所知,所有用于评估scipy.interpolate
中的二变量样条函数的函数取x,y值并返回z,而我需要给出z并返回x,y(因为x ,y是一条线上的点,每个z映射到唯一的x,y)。
以下是我希望能够做到的草图:
import numpy as np
from matplotlib.pyplot import plot
# x,y coordinates of contour points, not monotonically increasing
x = np.array([ 2., 1., 1., 2., 2., 4., 4., 3.])
y = np.array([ 1., 2., 3., 4., 2., 3., 2., 1.])
# f: X --> Y might not be a 1:1 correspondence
plot(x,y,'-o')
# get the cumulative distance along the contour
dist = [0]
for ii in xrange(x.size-1):
dist.append(np.sqrt((x[ii+1]-x[ii])**2 + (y[ii+1]-y[ii])**2))
d = np.array(dist)
# build a spline representation of the contour
spl = ContourSpline(x,y,d)
# resample it at smaller distance intervals
interp_d = np.linspace(d[0],d[-1],1000)
interp_x,interp_y = spl(interp_d)
答案 0 :(得分:25)
您希望使用参数化样条,而不是从y
值中插入x
,而是设置新参数t
,并插入y
和x
的值t
,并使用单变量样条函数。如何为每个点分配t
值会影响结果,并且如您的问题所示,使用距离可能是一个好主意:
from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import scipy.interpolate
x = np.array([ 2., 1., 1., 2., 2., 4., 4., 3.])
y = np.array([ 1., 2., 3., 4., 2., 3., 2., 1.])
plt.plot(x,y, label='poly')
t = np.arange(x.shape[0], dtype=float)
t /= t[-1]
nt = np.linspace(0, 1, 100)
x1 = scipy.interpolate.spline(t, x, nt)
y1 = scipy.interpolate.spline(t, y, nt)
plt.plot(x1, y1, label='range_spline')
t = np.zeros(x.shape)
t[1:] = np.sqrt((x[1:] - x[:-1])**2 + (y[1:] - y[:-1])**2)
t = np.cumsum(t)
t /= t[-1]
x2 = scipy.interpolate.spline(t, x, nt)
y2 = scipy.interpolate.spline(t, y, nt)
plt.plot(x2, y2, label='dist_spline')
plt.legend(loc='best')
plt.show()
答案 1 :(得分:2)
import numpy as np
import scipy.interpolate
from matplotlib.pyplot import plot
# x,y coordinates of contour points, not monotonically increasing
x = np.array([2., 1., 1., 2., 2., 4., 4., 3.])
y = np.array([1., 2., 3., 4., 2., 3., 2., 1.])
# f: X --> Y might not be a 1:1 correspondence
plot(x, y, '-o')
# get the cumulative distance along the contour
dist = np.sqrt((x[:-1] - x[1:])**2 + (y[:-1] - y[1:])**2)
dist_along = np.concatenate(([0], dist.cumsum()))
# build a spline representation of the contour
spline, u = scipy.interpolate.splprep([x, y], u=dist_along, s=0)
# resample it at smaller distance intervals
interp_d = np.linspace(dist_along[0], dist_along[-1], 50)
interp_x, interp_y = scipy.interpolate.splev(interp_d, spline)
plot(interp_x, interp_y, '-o')
答案 2 :(得分:1)
您可以使用splprep和splev,看看scipy cookbook,例如与您的问题非常相似。
http://wiki.scipy.org/Cookbook/Interpolation#head-34818696f8d7066bb3188495567dd776a451cf11