Гладкая сплайн-аппроксимация с фиксированной начальной и конечной точками с использованием scipy.interpolate - PullRequest
0 голосов
/ 28 февраля 2020

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

Я хотел бы добиться чего-то похожего на красную диаграмму ниже, которая сглажена, и я хотел бы начать / закончить в тех же точках, где другие графики начинаются и заканчиваются. Я не против, чтобы он не проходил через оставшиеся точки данных, я бы предпочел контролировать величину сглаживания, но начало и конец нужно фиксировать. Можно ли этого достичь с помощью scipy.interpolate? Есть ли альтернативы?

Я нашел { ссылка }, который используется для оранжевого графика, который очень похож на версию splprep с s=0, то есть интерполяцию, но это также использует s = 0, поэтому я не вижу, как это помогает сглаживать.

Я также нашел { ссылка }, где коэффициентами манипулируют; опять же я не вижу, как это помогает в достижении моей цели. Коэффициенты, полученные в результате splprep со сглаживанием, уже ведут к начальным точкам красного графика.

import numpy as np
from matplotlib import pyplot as plt
from scipy.interpolate import splprep, splev, make_interp_spline

border_segment = 16 * np.asarray([[[2, 8], [2, 9], [2, 10], [2, 11], [1, 12], [0, 13], [0, 14], [0, 15], [1, 16], [2, 17], [2, 18]]])

plt.scatter( border_segment[0].T[0], border_segment[0].T[1] )

# With smoothing s<>0
tck, u = splprep(border_segment[0].T, u=None, s=border_segment[0].shape[0]*16, per=0)
u_new = np.linspace(u.min(), u.max(), border_segment[0].shape[0]*16)
x_new, y_new = splev(u_new, tck, der=0)
plt.plot(x_new, y_new, color='red')

# With interpolation s=0
tck, u = splprep(border_segment[0].T, u=None, s=0.0, per=0)
x_new, y_new = splev(u_new, tck, der=0)
plt.plot(x_new, y_new, color='green')

# With boundary conditions, also see https://stackoverflow.com/a/47233842/4556546
l, r = [(1, (0, 0))], [(1, (0, 0))]
clamped_spline = make_interp_spline(u, np.array(border_segment[0].T).T, bc_type=(l, r))
x_new, y_new = clamped_spline(u_new).T
plt.plot(x_new, y_new, color='orange')

Plotting result from the code above

1 Ответ

1 голос
/ 01 марта 2020

Не из коробки. Вы можете попробовать использовать веса, w, чтобы обрезать сплайн в конечных точках. YMMV хотя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...