shot_descriptor — 3D feature_register op

• Datenarten: points × normals → descriptor

• Aufruf: import fullseye as fs; fs.ledger.shot_descriptor(points, normals, kp_idx, tree, radius, n_azim=8, n_elev=2, n_rad=2, n_cos=11) (die Implementierung direkt: import feat_shot; feat_shot.shot_descriptor(points, normals, kp_idx, tree, radius, n_azim=8, n_elev=2, n_rad=2, n_cos=11); aus dem Register: ops3d.get("shot_descriptor"))

Verwendung

Der SHOT-Deskriptor (Tombari 2010). Er richtet an jedem Keypoint ein lokales Bezugssystem ein und nimmt eine kugelförmige Umgebung.

Die Umgebung wird aufgeteilt in radial 2 × Elevation 2 × Azimut 8 = 32 Raumzellen; in jeder Zelle wird der "Kosinus des Winkels zwischen LRF-z-Achse und der Normale des Nachbarpunkts" per quadrilinearer Interpolation in ein Histogramm mit n_cos=11 Bins akkumuliert → die 32×11=352 Dimensionen werden L2-normiert. Rückgabewert (Kp,352). Punkte ohne gültiges LRF erhalten einen Nullvektor.

Raises ValueError: wenn die Zeilenzahl von normals nicht zu points passt (mischt man die Normalen einer anderen Punktwolke ein, laufen die Nachbarindizes aus dem Bereich und es entsteht ein roher IndexError — dieselbe Klasse wie bei compute_fpfh).

Argumente: points (N,3), normals (N,3) Einheitsnormalen, kp_idx sind die Punkt- indizes der Keypoints (Ausgabe von iss_keypoints), tree ist ein aus points gebauter scipy.spatial.cKDTree (vom Aufrufer bereitgestellt), radius ist der Stützradius (sowohl für die LRF-Schätzung als auch für das Sammeln der Nachbarn verwendet). Ändert man n_azim, n_elev, n_rad, n_cos, wird die Dimension n_azim*n_elev*n_rad*n_cos.

Ablauf: Das LRF nimmt die Eigenvektoren der Kovarianz mit Abstandsgewicht max(radius-d, 0) (x = größter, z = kleinster Eigenwert), richtet sie am Vorzeichen der Nachbarmehrheit aus und macht das System rechtshändig. Keypoints mit weniger als 5 Nachbarn oder degeneriertem LRF bleiben Nullvektoren (sie werden auf der Matching-Seite ausgeschlossen). Jeder Nachbarpunkt wird in Radius, Elevation (arccos(qz/r)/π) und Normalen-Kosinuswinkel mit Bin-Mitten bei 0.5 linear interpoliert, der Azimut wird zyklisch gewrappt und akkumuliert; zuletzt wird jede Zeile L2-normiert. Rückgabewert ist float64 (len(kp_idx), n_azim*n_elev*n_rad*n_cos) (standardmäßig 352). Beim Vergleich von 2 Wolken auf beiden Seiten denselben radius und dieselbe Normalen-Vorzeichenregel verwenden (wird die Normalenrichtung umgekehrt, kippt das Kosinuswinkel-Histogramm). register_shot wendet diese Funktion auf beide Wolken an und führt bis zu Matching und RANSAC durch.

Hintergrundwissen (Physik und Konventionen hinter diesem Operator)

• blas_threads_and_memory — Warum Matrixzerlegungen langsam sind — BLAS-Threads, Caches, Speicherlayout

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)

• feature_register — py -3.11 examples_3d/feature_register.py

Typkompatible Folge-Operatoren (nehmen descriptor als Eingabe)

fuse_to_voxel · shape_distance

Gleiche Kategorie (feature_register)

harris3d_keypoints · iss_keypoints · compute_fpfh · register_spin · register_fpfh · register_shot


*Provenance: feat_shot.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.