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"))
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).
• 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.
• refinement — py -3.11 examples_3d/refinement.py
pose als Eingabe)fuse_to_voxel · pose_error · bundle_adjust · mean_reprojection_error · optimize_pose_graph · relative_pose · mean_edge_error · rotation_translation_error
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.