Numpy 任意轮廓的平滑样条线表示,f(长度)-->;x、 y

Numpy 任意轮廓的平滑样条线表示,f(长度)-->;x、 y,numpy,scipy,curve-fitting,bezier,spline,Numpy,Scipy,Curve Fitting,Bezier,Spline,假设我有一组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 ma

假设我有一组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)

您希望使用参数样条曲线,其中,您不需要从
x
值中插值
y
,而是设置一个新参数
t
,并使用单变量样条曲线从
t
的值中插值
y
x
。如何将
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()

以下是使用and的示例:


我不明白为什么您的
x
y
数组不能有1:1的对应关系,并且仍然在曲线上定义点。。。你能试着用一个例子来解释你的想法吗?试着绘制我的示例坐标-在这种情况下,直线曲线会自动返回,因此在Python中不可能有来自X-->Y或Y-->XZOMG的唯一映射如此简单,我不得不用Ruby编写自己的Catmull Rom实现…:/好stuff@Jaime这是非常有趣的技巧,谢谢!除了dist_样条曲线外,t的其他合理值是什么?我在哪里可以读到更多关于它的信息?由于某些原因,scipy中没有记录样条线方法:@baltazar您可以对曲线进行一些读取。在曲线微分几何的上下文中,曲线长度的参数化(类似于距离)具有一些特殊特性,因此被称为。另一个明显的参数选项是围绕中心点的角度,如果你的数据集有正确的几何体。这是一个非常简单的例子——希望我能把它框起来挂在墙上。现在,我想知道在缩放时是否可以考虑“非共线”,或者这是否太过了。对不起,我得到了
AttributeError:module'scipy.interpolate'没有属性“spline”
,有什么想法吗?
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')