InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

ENH: Point-to-plane ICP metric for point-set registration (supersedes closed PR #3899)

Open
#6,729 0 comments 0 reactions 0 assignees View on GitHub
area:Registration type:Enhancement
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

ITK has no point-to-plane ICP metric; point-to-point converges slowly on smooth surface-to-surface registration. PR #3899 ("WIP: Point to Plane ICP") was closed 2026-05-10 for inactivity — its structure was right but the math had three correctness bugs. Filing so the algorithmic findings and restart plan are discoverable rather than buried in a closed WIP PR.

Why this is wanted

Point-to-plane ICP (Chen & Medioni / Low 2004) minimizes the distance from each moving point to the *tangent plane* at its fixed-set correspondence, rather than to the correspondence point itself. On smooth surfaces this converges in far fewer iterations than point-to-point, which slides along the surface.

Repeatedly requested on Discourse: threads t/4044, t/3010, t/2214, t/3742, t/7410.

Prior art and why #3899 was closed

- PR #3899 — "WIP: Point to Plane ICP", opened ~2023, **closed 2026-05-10** on inactivity.
- The close comment (https://github.com/InsightSoftwareConsortium/ITK/pull/3899#issuecomment-4415625800) carries the canonical math derivation, write-ups of the three correctness bugs found in the PR's implementation, and the recommended structural pattern. That comment is the durable reference for anyone restarting the work.
- The structural shape of #3899 was sound; the math was not. Do not simply rebase it.

Suggested approach

1. **Do not modify** `Modules/Registration/Metricsv4/include/itkPointSetToPointSetMetricWithIndexv4.hxx`. PR #3899's edits there would have silently regressed every other PointSet metric. Add a new class instead.
2. In the new metric class, override only `GetLocalNeighborhoodValue` and `GetLocalNeighborhoodValueAndDerivative`.
3. Per-point residual is `e = n · (p − q)`; the per-point gradient contribution is `-e · n`, where `n` is the unit normal at the fixed-set correspondence `q`.
4. `PixelType` should be `itk::CovariantVector` so normals ride along with the point set.
5. Test fixture: unit sphere with position-vector normals; apply a known small-angle rigid transform and recover it via `GradientDescentOptimizerv4`. A stand-alone NumPy implementation of the canonical algorithm converges on this fixture in 13 iterations to ~1e-5 RMS — reproduce that reference (the algorithm is fully specified in the #3899 close comment) and use it as the single source of truth for the C++ expected values.

Adjacent ecosystem

Pranjal's PRs #3733 (RANSAC remote module), #3734 (FPFH remote module), and #3728 (`DistanceThreshold` in the Euclidean-distance metric) together form a feature-extraction → matching → fine-alignment pipeline. A point-to-plane ICP metric is the missing fine-alignment stage that completes it.

Contributor guide

Open the contributing guide

Research direction

Read the canonical math derivation in PR #3899's close comment, then inspect Modules/Registration/Metricsv4/include/itkPointSetToPointSetMetricWithIndexv4.hxx without modifying it. Add a new metric class following the stated override structure, and validate it with the unit-sphere fixture, known rigid transform, GradientDescentOptimizerv4, and the reported 13-iteration, approximately 1e-5 RMS reference.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, numpy
Domain
computer-vision
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.