Thin Plate Spline (TPS)
January 3, 2026 · View on GitHub
Python (NumPy & SciPy) implementation of the generalized Polyharmonic Spline interpolation (also known as Thin Plate Spline in 2D). It learns a smooth elastic mapping between two Euclidean spaces with support for:
- Arbitrary input and output dimensions
- Arbitrary spline order
k - Optional regularization
Useful for interpolation, deformation fields, and smooth non-linear regression.
For a faster implementation in PyTorch, see torch-tps.
🚀 Install
Pip
$ pip install thin-plate-spline
From source
git clone git@github.com:raphaelreme/tps.git # OR https://github.com/raphaelreme/tps.git
cd tps
pip install .
Getting started
import numpy as np
from tps import ThinPlateSpline
# Control points
X_train = np.random.normal(0, 1, (800, 3)) # 800 points in R^3
Y_train = np.random.normal(0, 1, (800, 2)) # Values for each point (800 values in R^2)
# New source points to interpolate
X_test = np.random.normal(0, 1, (300 0, 3))
# Initialize spline model (Regularization is controlled with alpha parameter)
tps = ThinPlateSpline(alpha=0.5)
# Fit spline from control points
tps.fit(X_train, Y_train)
# Interpolate new points
Y_test = tps.transform(X_test)
Examples
See the example/ folder for scripts showing:
- Interpolation in 1D, 2D, 3D
- Arbitrary input and output dimensions
- Image warping with elastic deformation
Image Warping
Example of increasing/decreasing/randomly deforming a dog's face using sparse control points.

Code: example/image_warping.py
🧠 Theory Summary
The model solves the regularized interpolation problem:
min_f \sum_{i=1}^n (y_i - f(x_i))^2 + \int \|\nabla^{\text{order}} f\|_$2^{2}$ dxWith solution:
Where:
- : radial basis function (RBF) (depends on
orderand the input dimensiond) - : a polynomial of degree
order - 1
Default kernel (TPS):
General kernel:
🔧 API
ThinPlateSpline(alpha=0.0, order=2, enforce_tps_kernel=False)
Creates a general polyharmonic spline interpolator (Default to TPS in 2D and natural cubic splines in 1D).
- alpha (float): Regularization strength (default 0.0)
- order (int): Spline order (default is 2 for TPS)
- enforce_tps_kernel (bool): Force TPS kernel r^2 log r, even when mathematically suboptimal
.fit(X, Y)
Fits the model to control point pairs.
- X:
(n, d)input coordinates - Y:
(n, v)target coordinates
Returns: self
.transform(X)
Applies the learned mapping to new input points.
- X:
(n', d)points
Returns: (n', v) interpolated values
License
MIT License