Interpolation is a mathematical technique used to estimate or determine values between known data points. B-spline (Basis spline) interpolation is a generalization of cubic spline interpolation and it involves finding a B-spline curve that passes through each of the given data points.
The SciPy API provides the BSpline class to implement B-spline fitting for a given data. In this tutorial, you'll learn how to implement B-spline interpolation using the BSpline class in Python. The tutorial covers:
- Understanding B-spline interpolation
- Implementing B-spline interpolation
- Source code listing
We'll start by loading the required libraries.
from scipy import interpolate
import matplotlib.pyplot as plt
import numpy as np
- Knots: set of values that define the parameter space over which the B-spline curve is defined.
- Spline coefficients: also known as control points, are a set of values associated with each basis function in the B-spline representation.
- Degree of the spline: indicates the order of the polynomials used in the basis functions.
y = [0, 1, 3, 4, 3, 5, 7, 5, 2, 3, 4, 8, 9, 8, 7]
n = len(y)
x = range(0, n)
plt.plot(x, y, 'ro', label="original")
plt.plot(x, y, 'b', label="linear interpolation")
plt.title("Target data")
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid()
plt.show()
To initiate B-spline interpolation, we must first obtain the necessary coefficients. This can be achieved using the 'splrep' function. The function returns a tuple (t, c, k) containing the vector of knots (t), B-spline coefficients (c), and the degree of the spline (k). These coefficients serve as the fundamental building blocks for our B-spline interpolation process.
tck = interpolate.splrep(x, y, s=0, k=3)
x_new = np.linspace(min(x), max(x), 100)
y_fit = interpolate.BSpline(*tck)(x_new)
plt.title("BSpline curve fitting")
plt.plot(x, y, 'ro', label="original")
plt.plot(x_new, y_fit, '-c', label="B-spline")
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid()
plt.show()
from scipy import interpolate
import matplotlib.pyplot as plt
import numpy as np
y = [0,1,3,4,3,5,7,5,2,3,4,8,9,8,7]
n = len(y)
x = range(0, n)
plt.plot(x, y, 'ro', label="original")
plt.plot(x, y, 'b', label="linear interpolation")
plt.title("Target data")
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid()
plt.show()
tck = interpolate.splrep(x, y, s=0, k=3)
x_new = np.linspace(min(x), max(x), 100)
y_fit = interpolate.BSpline(*tck)(x_new)
plt.title("BSpline curve fitting")
plt.plot(x, y, 'ro', label="original")
plt.plot(x_new, y_fit, '-c', label="B-spline")
plt.legend(loc='best', fancybox=True, shadow=True)
plt.grid()
plt.show()
How can I implement this to 3D curve? What should I do with the z variable
ReplyDeleteYou can use below example.
Deletefrom scipy import interpolate
import matplotlib.pyplot as plt
import numpy as np
# Original data points in 3D
x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
y = [0, 1, 3, 4, 3, 5, 7, 5, 2, 3, 4, 8, 9, 8, 7]
z = [0, 2, 1, 4, 3, 6, 8, 5, 3, 2, 4, 9, 7, 8, 6]
# Create a parametric variable 't' based on the number of data points
t = np.arange(len(x))
# Number of points on the interpolated curve
num_points = 100
# Perform B-spline interpolation in 3D
tck_x = interpolate.splrep(t, x, s=0, k=3)
tck_y = interpolate.splrep(t, y, s=0, k=3)
tck_z = interpolate.splrep(t, z, s=0, k=3)
# Create a new parameter range
t_new = np.linspace(t[0], t[-1], num_points)
# Evaluate the B-spline curves at the new parameter values
x_new = interpolate.BSpline(*tck_x)(t_new)
y_new = interpolate.BSpline(*tck_y)(t_new)
z_new = interpolate.BSpline(*tck_z)(t_new)
# Plot the original and interpolated data points in 3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c='r', marker='o', label='Original Data')
ax.plot(x_new, y_new, z_new, '-c', label='B-spline Interpolation')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
plt.title('B-spline Interpolation in 3D')
plt.legend(loc='best')
plt.show()
Amazing, was trying to translate some Maya code into python, thank you
ReplyDelete