Skip to main content
Version: 3.4.20 (unreleased)

ICP Alignment

Iterative Closest Point (ICP) automatically registers one dataset onto another — it nudges a source mesh or point cloud into the best rigid fit against a fixed reference. VRGS repeatedly pairs each source point with its nearest point (or surface) on the reference, solves for the rotation and translation that best line the pairs up, applies it, and repeats until the fit stops improving. It is the tool to reach for when two overlapping scans, an SfM model and a lidar cloud, or successive surveys of the same outcrop need to sit in a common coordinate frame.

Where to find it

ICP lives in the Iterative Closest Point panel, on both the Triangulated Mesh and the Point Clouds ribbon tabs. It aligns a mesh or a point cloud to a mesh or a point cloud, in both the OpenGL and Vulkan 3D views. For a per-button reference see the Triangulated Mesh and Point Clouds ribbons.

Rigid alignment only

ICP applies a rigid transform (rotation + translation) — it never changes the size of the source. If the two datasets are at different scales, fix that first with a GCP rescale (see Coarse pre-alignment).

How ICP works​

Each iteration does three things:

  1. Correspondence — for every (sampled) source point, find the closest point or surface on the reference, discarding any pair farther apart than the Max Distance cutoff.
  2. Solve — compute the single rotation + translation that minimises the paired distances.
  3. Apply and repeat — move the source and measure the new alignment error. When the fit stops improving, ICP has converged.

VRGS keeps track of the best alignment it finds along the way, so if later iterations start to drift it reverts to the best pose rather than leaving the source worse off. If no iteration fits better than the starting pose, the source stays where it was and the messages panel says so.

Point-to-plane vs point-to-point​

The matching mode is chosen per object with the two buttons in the panel. A new object starts on Point to Plane.

ModeWhat it minimisesBest for
Point to PlaneDistance from each source point to the reference surface. A mesh's surface is its triangles; a point cloud stands in for one through the plane through each of its points' 12 nearest neighbours. Converges faster and slides more freely along smooth surfaces. Pairs are weighted robustly, so vegetation and other points that do not match pull less.Surfaces, whether the reference is a mesh or a cloud.
Point to PointDistance between each source point and the nearest reference point (classic ICP).Unstructured data with no surface to speak of.

Aligning to an elevation model​

A reference whose facets never overhang, such as a DEM grid or a 2D triangulation, counts as an elevation model, and the messages panel says so. A DEM draws a cliff as a ramp one cell wide, and fitting a cliff face to that ramp would tilt the model, so:

  • Reference facets steeper than 60° are left out of the fit, and so are source points whose own normal is that steep.
  • Point to Point runs as Point to Plane instead, with a warning. It pairs points with the DEM's nodes, and cannot correct an offset smaller than about half their spacing.

Use a model's Align to Reference Elevation instead when an SfM workflow is what you are aligning: it also fits scale and carries all the workflow's outputs with it.

Before you start​

ICP refines an already roughly correct alignment — it is not a global search. For a reliable result:

  • Load both datasets and make sure they are shown in the 3D view.
  • Pre-align them so they start within roughly a model unit and a small rotation of each other. Drag them close by hand, or use the tiepoint/GCP corrections below for a coarse first pass.
  • Make sure they overlap — ICP can only match the region the two datasets share. More overlap gives a more stable fit.
You choose the reference

The active object (the one selected in the project tree / 3D view) is the source that ICP moves. The reference is one other mesh or point cloud shown in the view. With one shown, ICP uses it. With several, a menu headed Align 'source' to: opens when you click ICP, and dismissing it starts nothing. With none, the messages panel says so.

Running an alignment​

  1. Select the dataset you want to move (the source) in the project tree so it is the active object.
  2. Make sure the dataset you want to align it to (the reference) is shown in the 3D view.
  3. On the Triangulated Mesh or Point Clouds tab, in the Iterative Closest Point panel, choose the mode.
  4. Set the parameters (see below). Start with a generous Max Distance for a coarse run, then tighten it for a final pass.
  5. Click ICP to start, and pick the reference if a menu asks. The fit runs in the background and the results appear in the messages panel.
  6. Click ICP again at any time to stop early. The best pose so far is kept.
Compare them as you go

Split View on the Triangulated Mesh tab splits the 3D view into two panes with their own viewpoints, so you can look at the same place from two sides.

Parameters​

All ICP settings are stored on the active object, so each dataset remembers its own values, and the ribbon shows the active object's.

ControlMeaningDefault
Max DistanceThe correspondence cutoff, in model units (metres for georeferenced data). Point pairs farther apart than this are ignored, which stops the fit being pulled toward the wrong surface. Use a larger value for a coarse first run and tighten it as the datasets close in. Must be greater than zero.1.0
SamplingUse every Nth source vertex when matching (1, 2, 4, 8, 16, 32, 64, 128). 1 uses every vertex (most accurate); higher values use fewer points so each iteration is faster but coarser — handy for a quick first alignment of a huge dataset.1
Keep Closest %:Keep only this percentage of the correspondences, the closest ones, and discard the rest, from 10 to 100. 100 keeps them all. Point to Plane already down-weights outliers, so lower this only to drop the farthest pairs outright, such as where the datasets only partly overlap.100 (keep all)
Use TiepointsAnchor the fit on the object's tiepoints: Point to Point takes its centroids from them instead of from the correspondences, and Point to Plane turns the source about the centroid of its tie points. Only available once the object has tiepoints.Off
A practical recipe

For a large, only-roughly-aligned pair: start with Sampling 8–16, a Max Distance of a few times the point spacing, and Keep Closest %: at 100; run ICP. Then drop Sampling back to 1, tighten Max Distance, and (if the datasets only partly overlap) lower Keep Closest %: to around 90–95 for a clean final pass.

Coarse pre-alignment with tiepoints and GCPs​

When the two datasets start too far apart for ICP to lock on, give it a coarse manual alignment first. The Corrections group on the same ribbon tab (Correct on the Point Clouds tab) computes a transform from matched control points:

  1. Use Add Tiepoint and Target to place pairs of matching points — one on the source, one on the corresponding feature on the reference.
  2. Apply a correction:
CommandEffect
From GCPRigid fit (rotation + translation) from the tiepoints/ground-control points — no scaling.
From GCP with ScalingAdds a uniform scale, for datasets captured at different scales.
From OrientationFit from orientation (dip/azimuth) control points.
From BothCombine position and orientation control points in one fit.
Rescale From GCP / Anisotropic Rescale GCPApply an isotropic or directional scale correction from the tiepoints.
  1. Optionally enable Use Tiepoints to anchor ICP on those control points, then run ICP to refine.

Checking the result​

  • The messages panel — Point to Plane reports how far the source moved and turned, and the signed distance to the reference at the 16th, 50th and 84th percentiles, before and after, over the points it used. It warns when the reference barely constrains part of the pose, which it then leaves alone, and when the run stopped at its iteration limit. Point to Point reports the RMS error at each iteration: a steadily falling value that levels off means a good convergence.
  • ICP_Residual attribute — Point to Plane writes each source vertex's signed distance to the reference in the final pose. It is positive above an elevation model, and otherwise on the side the reference's normal faces, and has no value where the reference is not within Max Distance. Colour the source by it (see Attributes) to see where the fit is tight and where it is not. Values that change sign in a pattern show a remaining tilt or twist.
  • ICP_Diff attribute — Point to Point writes each source point's distance to its matched reference point in the final pose: low values are a tight fit, high values flag regions that did not align well (poor overlap, moving features, or noise).

For a rigorous, signed surface-to-surface comparison of two aligned datasets (rather than ICP's internal residual), use M3C2 comparison.

Undoing an alignment​

  • Ctrl+Z restores the source's pre-ICP geometry (ICP snapshots it before the run).
  • Undo Transform on the Triangulated Mesh ribbon steps back through the transforms applied to the active mesh, so you can peel off the last ICP (or correction) without losing earlier work.

A mesh's photogrammetric cameras move with it, through ICP and undo alike.

Tips and troubleshooting​

  • The source moved toward the wrong dataset. Undo, and pick the right reference from the menu when you run ICP again.
  • nothing to align in the messages. The reference is not shown. Show it in the 3D view and run ICP again.
  • ICP barely moves the source, or says too few points matched. The datasets probably start too far apart, or Max Distance is too small to find correspondences. Do a coarse tiepoint/GCP correction first, or increase Max Distance for the first run.
  • The fit is pulled toward outliers / a non-overlapping region. Lower Keep Closest %: to reject the worst correspondences, and reduce Max Distance once the datasets are close.
  • A model tilts when aligned to a DEM. Use Point to Plane, which leaves the cliff faces out. Colour by ICP_Residual to see where the misfit remains.
  • the cutoff distance must be more than 0 in the messages. Max Distance must be a positive value — every correspondence is rejected at zero. Set a sensible cutoff and rerun.
  • The two datasets are different sizes. ICP is rigid and cannot fix scale — use From GCP with Scaling or a Rescale correction first.
  • It is slow on a huge dataset. Raise Sampling (e.g. 16 or 32) for the coarse passes, then return it to 1 for the final refinement.
  • The result looks worse than where it started. ICP commits the best pose it found, so this is rare — but if it happens, Ctrl+Z / Undo Transform and retry from a better manual pre-alignment with a tighter Max Distance.

See also​