Difficulties to use scipy.interpolate BSpline: "TypeError: 'list' object cannot be interpreted as an integer"
Difficulties to use scipy.interpolate BSpline: "TypeError: 'list' object cannot be interpreted as an integer"
来自 :
splrep
可以根据路径和平滑因子计算 B 样条结、系数和度数
splev
使用生成的 B 样条启用插值
BSpline
可以直接从节点、系数和度数构建样条
那么,应该让我表演:
import numpy as np
from scipy.interpolate import splev, splprep, BSpline
path = [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.630482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254, 1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.9705882352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176), (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.0846185328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 2802.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.843424134807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.676470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125016151504795, 1214.2319876178394, 3262.029411764706), (-35.000550767864524, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35.0, 100.00005756991993, 3970.5)]
p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]]
tck, u = splprep(p, k=3)
t, c0, k = tck
sp = BSpline(t, k, c0)
目标是能够调整 B 样条曲线。但是 BSpline
对我的论点不满意:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/lalebarde/anaconda3/lib/python3.7/site-packages/scipy/interpolate/_bsplines.py", line 184, in __init__
self.k = operator.index(k)
TypeError: 'list' object cannot be interpreted as an integer
如果我检查变量的形状和类型:
type(t)
<class 'numpy.ndarray'>
type(c0)
<class 'list'>
type(k)
<class 'int'>
t.shape
(21,)
np.array(c0).shape
(3, 17)
我对 BSpline 的使用失败,来自 documentation:
class scipy.interpolate.BSpline(t, c, k, extrapolate=True, axis=0)
t: ndarray, shape (n+k+1,) --> knots
c: ndarray, shape (>=n, …) --> spline coefficients - At least k+1 coefficients are required for a spline of degree k, so that n >= k+1. Additional coefficients, c[j] with j > n, are ignored.
k: int --> B-spline order
除了系数 c
,它应该是与我的路径 p
.
长度相同的一维向量
例如,sp = BSpline(t, c0[0], k)
执行时没有错误,与 c0[1]
或 c0[2]
一样,但当然,我希望使用 splprep
计算的所有系数.
从 here 看来,scipy 插值手册令人困惑:
tck[1]: x and y coordinates of the relocated control points
手册说:
(t,c,k) a tuple containing the vector of knots, the B-spline coefficients, and the degree of the spline
最终,我错误地解释了 BSpline 的 样条系数参数 。
那么,我如何使用 BSpline
或其他函数从 splprep
返回的结和系数构建 BSpline?
BSpline(t, k, c0)
应该是 BSpline(t, c0, k)
编辑。事实上,还有一个问题:splprep returns 数组列表与 BSpline
.
不一致
注意splrep和splprep的区别:
基本上,splrep/splev一致,splrep/BSpline一致,但是splprep/BSpline不一致。这是一个已知的疣,无法以向后兼容的方式修复。
如果你想一起使用它们,你需要转置 c
数组。
基于您的 OP 示例:
In [1]: import numpy as np
...: from scipy.interpolate import splev, splprep, BSpline
...: path = [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.6
...: 30482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254,
...: 1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.97058
...: 82352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176),
...: (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.08461
...: 85328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 28
...: 02.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.84342413
...: 4807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.6
...: 76470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059
...: ), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125
...: 016151504795, 1214.2319876178394, 3262.029411764706), (-35.0005507678645
...: 24, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3
...: 616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35
...: .0, 100.00005756991993, 3970.5)]
...: p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]
...: ]
...: tck, u = splprep(p, k=3, s=0) # ADDED s=0 for clarity
...:
In [2]: t, c, k = tck
In [3]: c1 = np.asarray(c)
In [4]: spl = BSpline(t, c1.T, k) # Note the transpose
In [5]: spl(u) - path # these should match, and they do
Out[5]:
array([[ -4.54747351e-13, -1.13686838e-13, -4.54747351e-13],
[ 0.00000000e+00, -1.13686838e-13, 0.00000000e+00],
[ -4.54747351e-13, 0.00000000e+00, 0.00000000e+00],
[ 0.00000000e+00, -2.27373675e-13, -2.27373675e-13],
[ -4.54747351e-13, 0.00000000e+00, 4.54747351e-13],
[ -4.54747351e-13, 0.00000000e+00, -6.82121026e-13],
[ 2.27373675e-13, 0.00000000e+00, 0.00000000e+00],
[ -1.13686838e-13, -4.54747351e-13, -4.54747351e-13],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 4.26325641e-14, -9.09494702e-13, 0.00000000e+00],
[ 1.42108547e-14, -4.54747351e-13, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 7.10542736e-15, 0.00000000e+00, -4.54747351e-13],
[ 0.00000000e+00, -3.41060513e-13, 0.00000000e+00],
[ -7.10542736e-15, -1.13686838e-13, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]])
此答案基于 https://github.com/scipy/scipy/issues/10389。
那里的一般建议适用:如果你想要插值,更喜欢 make_interp_spline
而不是 splrep
和 splprep
。如果你想要平滑,目前只有 FITPACK,splrep(与 BSpline 兼容)或 splprep(你需要手动转置)。
来自
splrep
可以根据路径和平滑因子计算 B 样条结、系数和度数splev
使用生成的 B 样条启用插值BSpline
可以直接从节点、系数和度数构建样条
那么,应该让我表演:
import numpy as np
from scipy.interpolate import splev, splprep, BSpline
path = [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.630482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254, 1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.9705882352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176), (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.0846185328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 2802.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.843424134807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.676470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125016151504795, 1214.2319876178394, 3262.029411764706), (-35.000550767864524, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35.0, 100.00005756991993, 3970.5)]
p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]]
tck, u = splprep(p, k=3)
t, c0, k = tck
sp = BSpline(t, k, c0)
目标是能够调整 B 样条曲线。但是 BSpline
对我的论点不满意:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/lalebarde/anaconda3/lib/python3.7/site-packages/scipy/interpolate/_bsplines.py", line 184, in __init__
self.k = operator.index(k)
TypeError: 'list' object cannot be interpreted as an integer
如果我检查变量的形状和类型:
type(t)
<class 'numpy.ndarray'>
type(c0)
<class 'list'>
type(k)
<class 'int'>
t.shape
(21,)
np.array(c0).shape
(3, 17)
我对 BSpline 的使用失败,来自 documentation:
class scipy.interpolate.BSpline(t, c, k, extrapolate=True, axis=0)
t: ndarray, shape (n+k+1,) --> knots
c: ndarray, shape (>=n, …) --> spline coefficients - At least k+1 coefficients are required for a spline of degree k, so that n >= k+1. Additional coefficients, c[j] with j > n, are ignored.
k: int --> B-spline order
除了系数 c
,它应该是与我的路径 p
.
例如,sp = BSpline(t, c0[0], k)
执行时没有错误,与 c0[1]
或 c0[2]
一样,但当然,我希望使用 splprep
计算的所有系数.
从 here 看来,scipy 插值手册令人困惑:
tck[1]: x and y coordinates of the relocated control points
手册说:
(t,c,k) a tuple containing the vector of knots, the B-spline coefficients, and the degree of the spline
最终,我错误地解释了 BSpline 的 样条系数参数 。
那么,我如何使用 BSpline
或其他函数从 splprep
返回的结和系数构建 BSpline?
BSpline(t, k, c0)
应该是 BSpline(t, c0, k)
编辑。事实上,还有一个问题:splprep returns 数组列表与 BSpline
.
注意splrep和splprep的区别:
基本上,splrep/splev一致,splrep/BSpline一致,但是splprep/BSpline不一致。这是一个已知的疣,无法以向后兼容的方式修复。
如果你想一起使用它们,你需要转置 c
数组。
基于您的 OP 示例:
In [1]: import numpy as np
...: from scipy.interpolate import splev, splprep, BSpline
...: path = [(2077.0, 712.0, 1136.6176470588234), (2077.0004154771536, 974.6
...: 30482962754, 1313.735294117647), (2077.1630960823995, 1302.460574562254,
...: 1490.8529411764707), (2078.1944091179635, 1674.693193015173, 1667.97058
...: 82352941), (2080.5096120056783, 2086.976611915444, 1845.0882352941176),
...: (2085.1051468332066, 2711.054258877495, 2022.2058823529412), (1477.08461
...: 85328733, 2803.6223679691457, 2199.323529411765), (948.4693105162195, 28
...: 02.0390667447105, 2376.4411764705883), (383.8615403256207, 2804.84342413
...: 4807, 2553.5588235294117), (-41.6669725172834, 2497.067373170676, 2730.6
...: 76470588235), (-37.94311919744064, 1970.5155845437525, 2907.794117647059
...: ), (-35.97395938535092, 1576.713103381243, 3084.9117647058824), (-35.125
...: 016151504795, 1214.2319876178394, 3262.029411764706), (-35.0005507678645
...: 24, 893.3910350913443, 3439.1470588235297), (-35.0, 631.2108462417168, 3
...: 616.264705882353), (-35.0, 365.60545190581837, 3793.3823529411766), (-35
...: .0, 100.00005756991993, 3970.5)]
...: p = [[x for x,y,z in path], [y for x,y,z in path], [z for x,y,z in path]
...: ]
...: tck, u = splprep(p, k=3, s=0) # ADDED s=0 for clarity
...:
In [2]: t, c, k = tck
In [3]: c1 = np.asarray(c)
In [4]: spl = BSpline(t, c1.T, k) # Note the transpose
In [5]: spl(u) - path # these should match, and they do
Out[5]:
array([[ -4.54747351e-13, -1.13686838e-13, -4.54747351e-13],
[ 0.00000000e+00, -1.13686838e-13, 0.00000000e+00],
[ -4.54747351e-13, 0.00000000e+00, 0.00000000e+00],
[ 0.00000000e+00, -2.27373675e-13, -2.27373675e-13],
[ -4.54747351e-13, 0.00000000e+00, 4.54747351e-13],
[ -4.54747351e-13, 0.00000000e+00, -6.82121026e-13],
[ 2.27373675e-13, 0.00000000e+00, 0.00000000e+00],
[ -1.13686838e-13, -4.54747351e-13, -4.54747351e-13],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 4.26325641e-14, -9.09494702e-13, 0.00000000e+00],
[ 1.42108547e-14, -4.54747351e-13, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 7.10542736e-15, 0.00000000e+00, -4.54747351e-13],
[ 0.00000000e+00, -3.41060513e-13, 0.00000000e+00],
[ -7.10542736e-15, -1.13686838e-13, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00],
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00]])
此答案基于 https://github.com/scipy/scipy/issues/10389。
那里的一般建议适用:如果你想要插值,更喜欢 make_interp_spline
而不是 splrep
和 splprep
。如果你想要平滑,目前只有 FITPACK,splrep(与 BSpline 兼容)或 splprep(你需要手动转置)。