Skip to main content

CPD-PyTorch

Coherent Point Drift point set registration in PyTorch

Rigid · Affine · Deformable · Landmark-guided — on CPU, CUDA or Apple GPUs, in float32 or float64

Yuliang (Chris) Xiao · University of Toronto

Documentation PyPI Python versions CI Open in Colab License

News · Installation · Quick Start · Methods · Performance · Examples · Documentation · Citation

Rigid registration
Rigid
The bunny, rotated by 45° and shifted: CPD recovers the rotation, translation and scale.
Affine registration
Affine
A fish outline, rotated, sheared and shifted: CPD recovers the full linear map.
Deformable registration
Deformable
Two different fish: a smooth displacement field bends one onto the other.
Deformable registration with landmarks
Deformable with landmarks
A third of the target is missing; four known point pairs (stars) guide the fit.

CPD-PyTorch aligns a moving point set Y to a fixed point set X without known correspondences, using Coherent Point Drift (Myronenko & Song, 2010): the points of Y are the centers of a Gaussian mixture, fitted to X by expectation-maximization while the centers move coherently. It keeps the interface of pycpd and adds GPUs, batches and memory-bounded computation for point sets of 100,000 points.

News

  • 2026-09 — CPD-PyTorch 1.0. A rewrite, published on PyPI as cpd-pytorch (#3): CUDA and Apple GPUs with a dtype argument for float32 or float64 (#4, building on #2), batched registration, a block-wise E-step that fits 100,000-point sets in under 1 GB, a faster low-rank solver, normalization, correspondences, results verified against pycpd, and documentation on Read the Docs. See the changelog and the migration guide.
  • 2024-03 — torchcpd 0.0.1. The first installable release: a PyTorch port of pycpd (started in February 2023) with rigid, affine, deformable (including low-rank) and constrained deformable registration on the GPU.

Highlights

  • Four methods: rigid (with optional scaling), affine, deformable (with a low-rank option for large point sets) and deformable with known correspondences.
  • Any device and precision: CPU, CUDA and Apple Silicon (MPS), in float32 or float64.
  • NumPy or PyTorch: NumPy arrays in, NumPy arrays out; or tensors that stay on the GPU.
  • Batches: register many point-set pairs in one call.
  • Large point sets: memory grows linearly with the number of points, not quadratically.
  • Correspondences: the most probable source point for every target point.
  • Verified: matches pycpd to 1e-8 in float64; tested on Python 3.8-3.14 with PyTorch 1.10-2.14 on Linux, macOS and Windows, and on CUDA and Apple GPUs.

Installation

pip install cpd-pytorch

For GPU support, install the PyTorch build for your platform first (instructions). Add matplotlib for the example scripts with pip install "cpd-pytorch[examples]".

Quick Start

from cpd_pytorch import RigidRegistration, datasets

X, Y = datasets.load_bunny()  # target and source, NumPy arrays (N, 3)
reg = RigidRegistration(X, Y)
TY, (s, R, t) = reg.register()  # TY = s * Y @ R + t, aligned with X
print(reg.iteration, s, t)

register() returns the transformed source points and the transform, as NumPy arrays because the inputs were NumPy arrays. To use a GPU, pass device, or tensors that are already on the GPU:

import torch

reg = RigidRegistration(X, Y, device="cuda", dtype=torch.float32)  # NumPy in, NumPy out

X_gpu = torch.as_tensor(X, device="cuda", dtype=torch.float32)
Y_gpu = torch.as_tensor(Y, device="cuda", dtype=torch.float32)
TY, (s, R, t) = RigidRegistration(X_gpu, Y_gpu).register()  # tensors on the GPU

On Apple Silicon, use device="mps" with dtype=torch.float32 (MPS has no float64).

Batches, large point sets and correspondences use the same classes:

import numpy as np
from cpd_pytorch import DeformableRegistration

# 32 pairs at once: (B, N, D) and (B, M, D). An unbatched X is shared by every pair.
rng = np.random.default_rng(0)
Ys = np.stack([Y + rng.normal(0, 0.05, 3) for _ in range(32)])  # (32, 453, 3)
TY, (s, R, t) = RigidRegistration(X, Ys).register()
print(TY.shape, R.shape)  # (32, 453, 3) (32, 3, 3)

# Low-rank kernel and block-wise E-step for large point sets (add device="cuda" for a GPU),
# then the most probable source point for every target point.
reg = DeformableRegistration(X, Y, low_rank=True, normalize=True)
TY, _ = reg.register()
index = reg.correspondences()  # X[n] matches Y[index[n]]

Methods

Class Transform Use it for Parameters
RigidRegistration s * Y @ R + t Same shape, different pose (and size) s, R, t
AffineRegistration Y @ B + t Shear or anisotropic scaling B, t
DeformableRegistration Y + G @ W Shapes that bend or deform smoothly G, W
ConstrainedDeformableRegistration Y + G @ W Deformation with some known point pairs G, W

The options you are most likely to need:

Option Default Meaning
w 0 Weight of the outlier distribution; use 0.1-0.3 for noise, outliers or partial overlap.
normalize False Register in normalized coordinates, so the parameters below do not depend on your units. Recommended for deformable registration.
alpha, beta 2, 2 Deformable only: stiffness of the deformation and width of the Gaussian kernel (in data units, or RMS radii with normalize=True).
low_rank, num_eig False, 100 Deformable only: approximate the kernel, for large source point sets.
max_iterations, tolerance 100, 1e-3 Stopping criteria.
device, dtype from the inputs Where and in which precision to compute.
chunk_size automatic Target points per E-step block; lower it if you run out of GPU memory.

Performance

Time per EM iteration for random 3D point sets of N = M points, after a warm-up and including the setup of each registration; memory in parentheses. The benchmarks page has all results, including float64 on the GPU, the CPU up to 100,000 points and Apple GPUs.

NVIDIA RTX 3090, float32 (peak GPU memory):

Method Points CPD-PyTorch 1.0 torchcpd 0.0.1
Rigid 20,000 49 ms (0.8 GB) 95 ms (10.7 GB)
Rigid 100,000 1.2 s (0.8 GB) out of memory
Deformable 20,000 0.42 s (4.6 GB) 1.37 s (12.2 GB)
Deformable, low rank 20,000 59 ms (0.8 GB) 1.1 s (12.2 GB)
Deformable, low rank 100,000 1.4 s (0.8 GB) out of memory

Apple M4 Pro CPU, float64 (peak process memory):

Method Points CPD-PyTorch 1.0 torchcpd 0.0.1 pycpd
Rigid 8,000 69 ms (0.7 GB) 158 ms (5.4 GB) 826 ms (5.4 GB)
Deformable, low rank 5,000 46 ms (0.5 GB) 734 ms (2.7 GB) 1,042 ms (2.6 GB)

Examples

New to CPD? The quick-start notebook runs in the browser on Google Colab, with no installation.

The examples/ folder has one short script per method (rigid, affine, deformable, low-rank and constrained, in 2D and 3D) plus batch_registration.py and large_point_clouds.py. Each runs from any directory and accepts --device, --dtype, --save animation.gif and --no-show:

python examples/fish_deformable_2D.py --device cpu

Documentation

The documentation has a user guide (methods, parameters, devices, batching, large point sets), the API reference and a migration guide for users of pycpd and of torchcpd 0.0.x.

Citation

If you use CPD-PyTorch in your research, please cite both the Coherent Point Drift paper and this library:

@article{myronenko2010cpd,
  title   = {Point Set Registration: Coherent Point Drift},
  author  = {Myronenko, Andriy and Song, Xubo},
  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},
  volume  = {32},
  number  = {12},
  pages   = {2262--2275},
  year    = {2010},
  doi     = {10.1109/TPAMI.2010.46}
}

@software{xiao2026cpdpytorch,
  author  = {Xiao, Yuliang},
  title   = {{CPD-PyTorch}: Coherent Point Drift Point Set Registration in {PyTorch}},
  year    = {2026},
  version = {1.0.0},
  url     = {https://github.com/YuliangXiaoYLX/CPD-Pytorch},
  license = {Apache-2.0}
}

The software entry is also in CITATION.cff, which GitHub's "Cite this repository" button reads.

Acknowledgements

CPD-PyTorch started as a PyTorch port of pycpd by Siavash Khallaghi (MIT License, see NOTICE). Registration with known correspondences follows the Extended CPD of Golyanik et al. (2016).

License

This project is licensed under the Apache 2.0 License.

Star History

Star History Chart

Developed by Chris Xiao | University of Toronto

Metadata

Release files for cpd-pytorch 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cpd-pytorch 1.0.0
File Size Uploaded
cpd_pytorch-1.0.0.tar.gz 163.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cpd-pytorch 1.0.0
File Interpreter ABI Platform
cpd_pytorch-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 235.9 kB

Release files / cpd_pytorch-1.0.0.tar.gz

Download URL cpd_pytorch-1.0.0.tar.gz
Size 163.9 kB
Tags Source
SHA-256 checksum
How to use checksums
80c1d08659552f6275fdf16699a8f64323cd81e3b1a9550fd8a3e6026751645e
BLAKE2b-256 checksum
How to use checksums
f196ebce32dfb236c8c8c1f9c55b38138ae897c8153b76ac10e3bf57765245db
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / cpd_pytorch-1.0.0-py3-none-any.whl

Download URL cpd_pytorch-1.0.0-py3-none-any.whl
Size 72.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ba3c5836fdb0afb7a76cd39309f4384b0d58dcee57ad8639d41ef227deeddd2b
BLAKE2b-256 checksum
How to use checksums
d769d3cd93ac864905dcb9043ccb54559ca3e15850ddb2b891f88e7eaa0a3b44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page