1

Я хотел бы установить кубическую кривую безье на множестве из 500 случайных точек.Наименьшие квадраты, подходящие для кубической кривой Безье

Вот код, у меня есть для кривой Безье:

import numpy as np 
from scipy.misc import comb 

def bernstein_poly(i, n, t): 
    """ 
    The Bernstein polynomial of n, i as a function of t 
    """ 

    return comb(n, i) * (t**(n-i)) * (1 - t)**i 


def bezier_curve(points, nTimes=1000): 

    nPoints = len(points) 
    x = np.array([p[0] for p in points]) 
    y = np.array([p[1] for p in points]) 

    t = np.linspace(0.0, 1.0, nTimes) 

    polynomial_array = np.array([ bernstein_poly(i, nPoints-1, t) for i in range(0, nPoints) ]) 

    xvals = np.dot(x, polynomial_array) 
    yvals = np.dot(y, polynomial_array) 

    return xvals, yvals 


if __name__ == "__main__": 
    from matplotlib import pyplot as plt 

    nPoints = 4 
    points = np.random.rand(nPoints,2)*200 
    xpoints = [p[0] for p in points] 
    ypoints = [p[1] for p in points] 

    xvals, yvals = bezier_curve(points, nTimes=1000) 
    plt.plot(xvals, yvals) 
    plt.plot(xpoints, ypoints, "ro") 
    for nr in range(len(points)): 
     plt.text(points[nr][0], points[nr][1], nr) 

    plt.show() 

Я знаю, что Numpy и SciPy имеют методы наименьших квадратов: numpy.linalg.lstsq и scipy.optimize.least_squares

Но я не уверен, как я могу используйте их для установки кривой на 500 точек. Может ли кто-нибудь помочь?

Спасибо

+0

какая часть ваших данных оправдывает использование кривой Безье, в отличие от чего-то гораздо более подходящего для шумовых данных? Потому что, прежде чем кто-то ответит на ваш вопрос, вы сможете ответить, почему вы считаете, что вам нужна кривая Безье, а не что-то более подходящее. –

+0

В этом случае я использую кривую Безье, потому что я следую инструкциям из книги, и я хотел бы это реализовать. Я знаю, что есть намного лучшие варианты, но в этом конкретном примере мне нужно использовать кривые Безье. – stepp0

+0

Это говорит о том, что вы еще не были полностью честны в своем вопросе. Я уверен, что вы сказали, что вы только что сказали в своем посте, и говоря *, которая * книга, является противоположностью ненужной информации. –

ответ

1

Используйте функцию curve_fit в SciPy, https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

import numpy as np 
from scipy.optimize import curve_fit 
def func(x, a, b, c): 
    return a * np.exp(-b * x) + c 

xdata = np.linspace(0, 4, 50) 
y = func(xdata, 2.5, 1.3, 0.5) 
ydata = y + 0.2 * np.random.normal(size=len(xdata)) 

popt, pcov = curve_fit(func, xdata, ydata) 

#Constrain the optimization to the region of 0 < a < 3, 0 < b < 2 and 0 < c < 1: 


popt, pcov = curve_fit(func, xdata, ydata, bounds=(0, [3., 2., 1.])) 
0

Сама SciPy документация имеет самое превосходное руководство по использованию шлицы здесь:

https://docs.scipy.org/doc/scipy/reference/tutorial/interpolate.html

с большим кода, примеров и крутых графов, сравнивающих разные типы сплайнов.

+0

Не кривые Безье и сплайны Безье разные? Спасибо за вашу рекомендацию, но я не вижу, как я могу это использовать в своем случае. – stepp0

+0

Приношу свои извинения. Как насчет этой ссылки из pypi? Пример кода и отображаемый график выглядят так, как вы ... https://pypi.python.org/pypi/bezier/0.3.0 –