Point cloud registration

Align one cloud onto another and get a 4×4 transform. The pipeline follows KISS-Matcher (FPFH plus graph pruning) with the TEASER++ robust solver (GNC-TLS and COTE), so it needs no initial guess and no installation.

Source cloud (to be moved)

The cloud that gets moved. The output matrix applies to it.

Nothing loaded

Target cloud (reference)

The frame that stays put.

Nothing loaded

How it works

  1. Put the source cloud on the left (it gets moved) and the target on the right (it stays fixed).
  2. The voxel size fills itself in; if the two clouds share a lot of surface with real geometry, leave it alone.
  3. Hit “Run registration” and check the overlap and RMSE.
  4. Download the aligned cloud, or paste the matrix into the coordinate transform tool.

The algorithm: KISS-Matcher’s pipeline, TEASER++’s solver

The hard part of registration is not solving for the pose, it is that many of the correspondences are simply wrong. Nearest-neighbour matching on real data is wrong more often than it is right, and a plain least-squares fit follows those outliers all the way to a confidently wrong answer. The whole pipeline is therefore built around throwing out the bad correspondences first, then solving on what is left.

  • Voxel downsampling: thins the clouds down to keypoints and, at the same time, fixes the noise bound — every threshold in KISS-Matcher is a multiple of the voxel size.
  • FPFH, 33 dimensions: a local geometric histogram per keypoint. Rotate or translate the scene and the values barely move, which is exactly what lets it match across viewpoints.
  • Mutual matching plus a ratio test: a pair survives only if it is the nearest neighbour in both directions, and only if its two nearest neighbours are far enough apart. In repetitive structures — corridors, fences — this step alone removes most of the wrong pairs.
  • Graph pruning (ROBIN’s max-core): connect correspondences whose pairwise distances agree and keep the largest k-core. True correspondences differ by noise only; wrong ones almost never satisfy that together, so they sink to the low-core layers and get cut.
  • GNC-TLS for rotation: a gradually tightened truncated least squares over the chain of differences (TIMs) between corresponding points. The closed-form step is an SVD; the weights separate inliers from outliers by themselves.
  • COTE for translation: each axis votes one-dimensionally for the centre covered by the most intervals, so an outlier on one axis cannot drag the other two.
  • ICP refinement: the robust solution is already close, so a nearest-neighbour ICP pushes the residual below the voxel scale.

The pipeline comes from MIT-SPARK’s KISS-Matcher (parameter names included: normal radius 3× voxel, FPFH radius 5× voxel, pruning noise bound 1× voxel, solver noise bound 0.75× voxel) and the GNC-TLS / COTE solvers from TEASER++. This page rewrites the same algorithm in TypeScript and runs it in the browser: no WASM download, opens instantly — at the cost of not being the tool of choice at millions of points yet.

Tuning

ParameterWhen to touch it
Voxel sizeThe one knob you have to understand. Too small: many keypoints, slow, and noise dominates the descriptors. Too large: the geometry blurs and matching loses its discriminative power. If the cloud is too big to finish, the page raises it automatically and reports the value it used.
Keypoint capControls the cost. 2000–3000 is the comfortable range in a browser.
Correspondence capPruning is O(n²), so a higher cap is more accurate and slower.
Ratio testKeep it on for repetitive scenes (long corridors, fences, shelving). Turn it off if the scene is distinctive and matches are scarce.
ICP refinementOn by default. If your clouds are very noisy, ICP can pull the result towards the noise — turn it off and compare.

Reading the result

  • Overlap: the share of source points that land within 1.5 voxels of the target. Below 60% usually means it did not really register.
  • RMSE: mean nearest-neighbour distance over those points. The two clouds sit on different voxel grids, so the voxel size is the floor — chasing zero is pointless.
  • Inliers: how many correspondences the robust solver accepted. Its ratio to the post-pruning count says how clean the data was.
  • Rotation / translation: the decomposed, human-readable version. Both near zero means the clouds were already in the same frame.

Things that happen

SymptomUsually this
Low overlap, matrix looks wrongThe clouds share too little surface, or differ in scale (millimetres versus metres)
Very few matches (< 50)The voxel is so large that detail is gone, or the surface is too smooth
The result is flipped 180°The scene is rotationally symmetric (square room, cylinder); crop the symmetry away first
Results jump between runsToo few inliers — the data does not support global registration; align coarsely or use a method that takes an initial guess
The page froze for ten secondsMore than 3000 keypoints, main thread saturated; lower the keypoint cap or raise the voxel size

Why local only: calibration and registration clouds often carry customer site coordinates or unpublished site data. There is no backend here, so the file never leaves your browser. The trade-off is that your machine sets the compute budget — which is why the defaults lean towards finishing in a few seconds.