2013-01-15 22 views
12

輪郭に沿って点をマークするx、y座標のセットがあるとします。その長さに沿った特定の位置で評価し、補間されたx、y座標を復元できる輪郭のスプライン表現を作成する方法はありますか?任意の等高線のスムーススプライン表示、f(長さ) - > 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

私はあなたの 'X'と 'y'アレイは1を持つことができませんどのように理解していません。 1対応であり、まだカーブ上の点を定義しています...あなたはあなたが念頭に置いている例を説明しようと思いますか? – Jaime

+0

私の例の座標をプロットしようとしてみてください - この場合、直線カーブ自体が戻ってくるので、X→YまたはY→Xからのユニークなマッピングはありません。 –

答えて

22

あなたがパラメトリック・スプラインを使用する場合は、代わりにx値からyを補間する、新しいパラメータを設定tを使用し、tの値からyxの両方を補間します。両方の単変量スプラインを使用します。見て、あなたがsplprepとsplevを使用することができます

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() 

enter image description here

+1

ZOMGはPythonでとても簡単です。 RubyのCatmull-Rom実装:/ good stuff – aledalgrande

+0

@Jaimeこれはとても面白いテクニックです、ありがとうございます! dist_splineに加えて、tの他の妥当な値は何ですか?どこでもっと読むことができますか?何らかの理由で、スプライン法はscipyには書かれていません:http://docs.scipy.org/doc/scipy-0.16.1/reference/interpolate.html – baltazar

+1

@baltazar [パラメトリック方程式](https: //en.wikipedia.org/wiki/Parametric_equation)。曲線の微分幾何学の文脈では、距離に似ている曲線の長さによるパラメータ化には、[自然なパラメータ化](https://en.wikipedia.org/)と呼ばれる特殊な性質があります。 wiki/Differential_geometry_of_curves#Length_and_natural_parametryzation)。パラメータのもう1つの明白なオプションは、データセットに正しいジオメトリがある場合は、中心点の周りの角度になります。 – Jaime

1

splprepsplevを使用した例です。

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') 

Parametric spline example

関連する問題