skimage2.transform.ThinPlateSplineTransform#

class skimage2.transform.ThinPlateSplineTransform[source]#

Bases: object

Thin-plate spline transformation.

Given two matching sets of points, source and destination, this class estimates the thin-plate spline (TPS) transformation which transforms each point in source into its destination counterpart.

Attributes:
srcarray_like of shape (N, 2)

Coordinates of control points in source image.

References

[1]

Bookstein, Fred L. “Principal warps: Thin-plate splines and the decomposition of deformations,” IEEE Transactions on pattern analysis and machine intelligence 11.6 (1989): 567–585. DOI:10.1109/34.24792 https://user.engineering.uiowa.edu/~aip/papers/bookstein-89.pdf

Examples

>>> import _skimage2 as ski2

Define source and destination control points such that they simulate rotating by 90 degrees and generate a meshgrid from them:

>>> src = np.array([[0, 0], [0, 5], [5, 5], [5, 0]])
>>> dst = np.array([[5, 0], [0, 0], [0, 5], [5, 5]])

Estimate the transformation:

>>> tps = ski2.transform.ThinPlateSplineTransform.from_estimate(src, dst)

Appyling the transformation to src approximates dst:

>>> np.round(tps(src), 4)
array([[5., 0.],
       [0., 0.],
       [0., 5.],
       [5., 5.]])

Create a meshgrid to apply the transformation to:

>>> grid = np.meshgrid(np.arange(5), np.arange(5))
>>> grid[1]
array([[0, 0, 0, 0, 0],
       [1, 1, 1, 1, 1],
       [2, 2, 2, 2, 2],
       [3, 3, 3, 3, 3],
       [4, 4, 4, 4, 4]])
>>> coords = np.vstack([grid[0].ravel(), grid[1].ravel()]).T
>>> transformed = tps(coords)
>>> np.round(transformed[:, 1]).reshape(5, 5).astype(int)
array([[0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4],
       [0, 1, 2, 3, 4]])

The estimation can fail - for example, if all the input or output points are the same. If this happens, you will get a transform that is not “truthy” - meaning that bool(tform) is False:

>>> if tps:
...     print("Estimation succeeded.")
Estimation succeeded.

Not so for a degenerate transform with identical points.

>>> bad_src = np.ones((4, 2))
>>> bad_tps = ski2.transform.ThinPlateSplineTransform.from_estimate(
...      bad_src, dst)
>>> if not bad_tps:
...     print("Estimation failed.")
Estimation failed.

Trying to use this failed estimation transform result will give a suitable error:

>>> bad_tps.params
Traceback (most recent call last):
  ...
FailedEstimationAccessError: No attribute "params" for failed estimation ...
__init__()[source]#
estimate(src, dst)[source]#

Estimate optimal spline mappings between source and destination points.

Deprecated since version 0.26: estimate is deprecated since version 0.26 and will be removed in version 2.2. Please use ThinPlateSplineTransform.from_estimate class constructor instead.

Parameters:
srcarray_like of shape (N, 2)

Control points at source coordinates.

dstarray_like of shape (N, 2)

Control points at destination coordinates.

Returns:
success: bool

True indicates that the estimation was successful.

Notes

The number N of source and destination points must match.

classmethod from_estimate(src, dst) Self | FailedEstimation[source]#

Estimate optimal spline mappings between source and destination points.

Parameters:
srcarray_like of shape (N, 2)

Control points at source coordinates.

dstarray_like of shape (N, 2)

Control points at destination coordinates.

Returns:
tformSelf or FailedEstimation

An instance of the transformation if the estimation succeeded. Otherwise, we return a special FailedEstimation object to signal a failed estimation. Testing the truth value of the failed estimation object will return False. E.g.

tform = ThinPlateSplineTransform.from_estimate(...)
if not tform:
    raise RuntimeError(f"Failed estimation: {tf}")

Notes

The number N of source and destination points must match.

property inverse#