小编典典

使用SciPy的Bézier曲线拟合

python

我有一组近似于2D曲线的点。我想将Python与numpy和scipy配合使用,以找到近似适合这些点的三次贝塞尔曲线路径,在该路径中,我指定两个端点的确切坐标,并返回其他两个控制点的坐标。

我最初以为scipy.interpolate.splprep()可以做我想做的事,但是似乎迫使曲线穿过每个数据点(因为我想您希望进行插值)。我以为我走错了路。

我的问题与此相似:如何将贝塞尔曲线拟合到一组数据?,除了他们说他们不想使用numpy。我的偏好是在scipy或numpy的某个地方找到我已经实现的东西。否则,我计划使用numpy来实现从该问题的答案之一链接的算法:一种自动拟合数字化曲线的算法(pdf。第622页)。

感谢您的任何建议!

编辑:我知道不能保证三次贝塞尔曲线都能通过所有点。我想要一个穿过两个给定端点的端点,并且该端点尽可能接近指定的内部点。


阅读 222

收藏
2020-12-20

共1个答案

小编典典

这是一段拟合点的python代码:

'''least square qbezier fit using penrose pseudoinverse
    >>> V=array
    >>> E,  W,  N,  S =  V((1,0)), V((-1,0)), V((0,1)), V((0,-1))
    >>> cw = 100
    >>> ch = 300
    >>> cpb = V((0, 0))
    >>> cpe = V((cw, 0))
    >>> xys=[cpb,cpb+ch*N+E*cw/8,cpe+ch*N+E*cw/8, cpe]            
    >>> 
    >>> ts = V(range(11), dtype='float')/10
    >>> M = bezierM (ts)
    >>> points = M*xys #produces the points on the bezier curve at t in ts
    >>> 
    >>> control_points=lsqfit(points, M)
    >>> linalg.norm(control_points-xys)<10e-5
    True
    >>> control_points.tolist()[1]
    [12.500000000000037, 300.00000000000017]

'''
from numpy import array, linalg, matrix
from scipy.misc import comb as nOk
Mtk = lambda n, t, k: t**(k)*(1-t)**(n-k)*nOk(n,k)
bezierM = lambda ts: matrix([[Mtk(3,t,k) for k in range(4)] for t in ts])
def lsqfit(points,M):
    M_ = linalg.pinv(M)
    return M_ * points

通常在bezier曲线上查看 动画bezier
bezierinfo

2020-12-20