icp_point2plane — 3D refine op

• Datenarten: points × points × normals → pose

• Aufruf: import fullseye as fs; fs.ledger.icp_point2plane(src, dst, dst_normals, iters=30, tol=1e-09, init=None, trim=None, device='cpu', reproducible=False) (die Implementierung direkt: import match3d; match3d.icp_point2plane(src, dst, dst_normals, iters=30, tol=1e-09, init=None, trim=None, device='cpu', reproducible=False); aus dem Register: ops3d.get("icp_point2plane"))

Verwendung

Verfeinert die Starrkörpertransformation hochgenau mit Point-to-Plane-ICP (Gauß-Newton, Kleinwinkelnäherung).

Verfeinerungsverfahren, das die Anfangspose aus einem groben Match (ganzzahliges NCC / Fourier-Mellin ±3° / Hough ±0.5voxel) durch Minimierung der Punkt-Ebene-Abstände von Oberflächen-Punktwolken festzieht. In jeder Iteration wird jedem src-Punkt sein dst- Nächster-Nachbar zugeordnet und das Punkt-Ebene-Residuum r_i = n_i·(R·p_i + t - q_i) minimiert. Linearisiert man R mit der Kleinwinkelnäherung R ≈ I + [ω]×, ist die Jacobi-Matrix jeder Korrespondenz J_i = [p_i×n_i | n_i] (aus dem Spatprodukt n·(ω×p)=ω·(p×n)), der konstante Term b_i = -n_i·(p_i - q_i). Die Normalgleichungen (JᵀJ)x = Jᵀb werden als 6×6-System gelöst, um das Inkrement x=[ω|t] zu erhalten, das mit Rodrigues in eine Rotation zurückgeführt und akkumuliert wird. Punkt-Ebene erlaubt Gleiten innerhalb der Tangentialebene und konvergiert daher mit weniger Iterationen als point-to-point eng an die Oberfläche (Low 2004).

Gemessen (wellige Oberfläche N=2025, CPU float64): aus anfänglich 6°/Translation 0.06 in 4 Iterationen zurück auf euclid RMSE 1.7e-16 und Rotationsfehler 0° (point-to-point stagniert nach 17 Iterationen bei RMSE 4e-2 und Rotation 1.9°). Auch bei Anfangswinkeln von 3-20° Maschinengenauigkeit in 4-5 Iterationen.

Argumente:

src (N,3): zu bewegende Punktwolke (Anfangspose nach dem groben Match).

dst (M,3): Referenz-Punktwolke (fest).

dst_normals (M,3): Einheitsnormalen von dst (werden intern normiert, auch wenn sie nicht normiert sind).

Falls unbekannt, vorab mit pointcloud.estimate_normals(dst) o. Ä. schätzen.

iters: maximale Anzahl der Iterationen.

tol: Abbruch als konvergiert, wenn die RMSE-Änderung unter diesem Wert liegt.

init ((R0,t0)): Anfangspose (R,t des groben Matches übergeben). Bei None die Identität.

trim (float|None): Anteil in [0,1). Trimmed ICP, das in jeder Iteration den obersten Anteil mit dem größten Punkt-Ebene-Residuum verwirft

(robust gegen Teilüberlappung und Ausreißer).

device: "cpu"/"cuda" usw. torch-device-String (geräteunabhängig).

reproducible: bei True werden JᵀJ und Jᵀb der Normalgleichungen (Reduktionen über N Punkte) mit ozakimm (Ozaki-Schema) berechnet,

Punkt-Ebene-Residuum und Anwendung der Pose sind elementweise Operationen, der RMSE nutzt math.fsum. Unabhängig von der Reihenfolge der src-Punkte und der Zahl der BLAS-Threads

sind R, t und rmse bitgleich. Standard False ist wie bisher (J.T @ J).

Rückgabewert:

R (3,3), t (3,), aligned (N,3)=R·src+t, rmse (Punkt-Ebene-RMSE über die verwendeten Punkte),

n_iter (tatsächliche Iterationszahl).

Referenzen (Beispieldaten, Literatur)

• Katalog der Beispieldaten (Download-URLs / Lizenzen) — 2-D nutzt skimage.data (BSD/Public Domain) plus synthetische Bilder, 3-D nennt Download-URLs echter Datenquellen (Stanford, PDS, …).

• Herkunft und Literatur der Operatoren — die Quellen der Forschung/Verfahren, auf denen diese Operatorfamilie beruht.

Ausführbare Beispiele (verifizierte Samples, die diesen Operator wirklich aufrufen)

• refinement — py -3.11 examples_3d/refinement.py

Typkompatible Folge-Operatoren (nehmen pose als Eingabe)

fuse_to_voxel · pose_error · bundle_adjust · mean_reprojection_error · optimize_pose_graph · relative_pose · mean_edge_error · rotation_translation_error

Gleiche Kategorie (refine)

refine_peak_newton · refine_translation_lk · refine_lm · refine_rotation_z · icp_point2point_3d


*Provenance: match3d.py — 3D Operator-Registry. Diese Notiz wird von tools/opdocs.py md erzeugt (nicht von Hand bearbeiten).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.