A from-scratch, notebook-based derivation and implementation of 2D Iterative Closest Point (ICP) scan matching — the algorithm behind most LiDAR/point-cloud localization and scan-to-scan registration pipelines (Cartographer, PCL, KISS-ICP, etc.). Everything is built with numpy/sympy/matplotlib only, no point-cloud libraries, so every step of the math is visible and animatable.
| Notebook | Covers |
|---|---|
IterativeClosestPoint.ipynb |
SVD-based ICP, non-linear least-squares (Gauss-Newton) ICP, point-to-plane ICP, robust-kernel outlier rejection |
svd_eigen.ipynb |
Why SVD of the cross-covariance matrix gives the optimal rotation — relates eigendecomposition of the covariance matrix to SVD of the data matrix |
Given two 2D scans (point sets)
Each ICP iteration alternates between correspondence estimation (nearest-neighbor matching, brute-force here) and transform estimation (closed-form via SVD, or a linearized least-squares step).
- Center both point sets on their centroids.
- Compute the cross-covariance matrix
$K = \sum (q_i - \mu_Q)(p_i - \mu_P)^T$ . - Decompose
$K = USV^T$ ; the optimal rotation is$R = UV^T$ , translation is recovered from the centroids. - This is the orthogonal Procrustes solution — exact for a given correspondence set, no linearization needed.
- State
$x = [x, y, \theta]^T$ , error$e_{i,j}(x) = R_\theta p_i + t - q_j$ . - Builds the Jacobian
$J = [I ;; R'_\theta p_i]$ , accumulates$H = \sum J^TJ$ ,$g = \sum J^Te$ , solves$H\Delta x = -g$ each iteration. - Point-to-point metric; converges slower than SVD-ICP for this reason — motivates method 3.
- Computes surface normals along
$Q$ (2D normal of a tangent segment:$n_v = [-v_y, v_x]$ ). - Error is the correspondence residual projected onto the normal:
$E = \sum_i (n_i \cdot (R_\theta p_i + t - q_j))^2$ . - Jacobian collapses from
$2\times3$ to$1\times3$ (verified symbolically withsympy). Converges in noticeably fewer iterations than point-to-point.
- Injects synthetic outliers into
$P$ and shows that all three methods above (SVD, least-squares, point-to-plane) drift/fail without correction. - Introduces a weighting kernel
$w(e) = \mathbb{1}[|e| < \text{threshold}]$ applied to each correspondence's contribution to$H$ /$g$ (or to the cross-covariance in the SVD case). - For SVD-ICP specifically, discusses the two places outliers leak in — the rotation step (fixable by down-weighting the cross-covariance sum) and the centering/translation step (fixable only by iteratively re-estimating the centroid while excluding marked outliers).
- For a covariance matrix
$\Sigma = X^TX / (N-1)$ , shows$\Sigma = VLV^T$ (eigendecomposition) and$X = USV^T$ (SVD of the data) give the same$V$ , with$L = S^2/(N-1)$ . - Visual sanity check: fits confidence ellipses to a synthetic Gaussian point cloud two ways (from
np.linalg.eigon the covariance vs.np.linalg.svdon the centered data) and confirms they coincide. - This is the piece of linear algebra that justifies why SVD of the cross-covariance matrix in method 1 is doing something geometrically meaningful.
ICP-Localization/
├── IterativeClosestPoint.ipynb # main notebook — all 4 ICP variants + outlier handling
├── svd_eigen.ipynb # SVD vs eigendecomposition theory + visualization
└── README.md
git clone https://github.com/Programiz-007/ICP-Localization.git
cd ICP-Localization
pip install numpy matplotlib sympy jupyter
jupyter notebookNo external datasets — all point clouds are synthetically generated in-notebook, so each cell is reproducible standalone. The animation cells use matplotlib.animation; if %matplotlib inline playback is choppy, switch to %matplotlib notebook or export the animation to GIF.
- Besl & McKay, A Method for Registration of 3-D Shapes, IEEE PAMI 1992 (original ICP)
- Chen & Medioni, Object Modeling by Registration of Multiple Range Images, 1992 (point-to-plane metric)
- Low, Linear Least-Squares Optimization for Point-to-Plane ICP Surface Registration, 2004
- Extend to 3D point clouds (rotation via quaternion/SO(3), same SVD machinery)
- KD-tree correspondence search instead of brute-force
$O(NM)$ - Generalized-ICP (plane-to-plane) formulation
- Benchmark against a real LiDAR scan pair (e.g. KITTI or a TurtleBot3 Gazebo scan)