curvature op• Datenarten: curvature → pairs
• Aufruf: import fullseye as fs; fs.ledger.curvature_to_shape_index(curvature) (die Implementierung direkt: import reprconv; reprconv.curvature_to_shape_index(curvature); aus dem Register: opsreprconv.get("curvature_to_shape_index"))
• GPU: nein (nur CPU-Referenzimplementierung)
Hauptkrümmungen (N,2) → Formindex und Gekrümmtheit als pairs (N,2). Der Ausgang aus curvature.
Das (S, C) von Koenderink & van Doorn, *Surface shape and curvature scales*, Image and Vision Computing 10(8) 1992:
S = (2/pi) * atan2(k1 + k2, k1 - k2) (k1 >= k2, S in [-1, 1])
C = sqrt((k1^2 + k2^2) / 2) (Stärke der Krümmung)
Der Kern ist, dass es mit atan2 statt mit einer Division geschrieben ist: Weder an einem Kugel-Nabelpunkt (k1 == k2) noch auf einer Ebene (k1 == k2 == 0) tritt eine Division durch null auf, und der Hin- und Rückweg mit shape_index_to_curvature ist im ganzen Bereich exakt (gemessen max|Δ| = 4.6e-16). Implementiert man das Lehrbuch- atan((k1+k2)/(k1-k2)) unverändert, entsteht an Nabelpunkten NaN, und dieses NaN wird nachgelagert zu "dunklen Pixeln".
S = -1 ist eine Schale, 0 ein Sattel, +1 eine Kappe. C ist das formunabhängige "wie stark es gekrümmt ist".
Auf einer Ebene ist S nicht definiert (auch Koenderink & van Doorn schließen ebene Punkte aus): bei k1 = k2 = 0 liefert atan2(0, 0) = 0 S = 0 (denselben Wert wie ein Sattel), und C = 0 ist das einzige Merkmal, das sie unterscheidet. Für Punkte nahe einer Ebene (Krümmung in derselben Größenordnung wie das Schätzrauschen) landet S je nach Richtung des Rauschens irgendwo in [-1, 1]. Die Form nicht allein nach S klassifizieren — zuerst C mit einer Schwelle belegen und Ebenen entfernen (die Schwelle hat die Einheit der Krümmung = 1/Länge, also passend zur Skala der Daten wählen). Eine in der Red-Team-Prüfung vom 2026-11-05 bestätigte Spezifikation (die Werte bleiben unverändert: um den exakten Hin- und Rückweg und das Versprechen, kein NaN auszugeben, zu wahren).
Nur die Information über die Eingabereihenfolge kommt nicht zurück: Auch in der Reihenfolge (k2, k1) übergeben, wird intern auf k1 >= k2 umsortiert, daher kommt ein Hin- und Rückweg immer absteigend zurück (eine Konvention der Orientierung, kein Werteverlust).
Args:
curvature: (N, 2) [k1, k2] oder ein Tupel aus 2 gleich langen 1-D-Arrays
(das ist die rohe Rückgabe von principal_curvatures).
Returns:
(N, 2) float64. Spalte 0 = S in [-1, 1], Spalte 1 = C >= 0.
Raises:
ValueError: ungültige Form / nicht endlich.
• 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.
• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.
• poc_bga_ball_type_roundtrip — py -3.11 examples/poc_bga_ball_type_roundtrip.py
• representation_roundtrip — py -3.11 examples/representation_roundtrip.py
pairs als Eingabe)angles_to_normals · shape_index_to_curvature · pairs_to_signal · pairs_to_image2d · pairs_to_table · polar_to_cscalar · pairs_peak_x
curvature)shape_index_to_curvature · curvature_to_table
*Provenance: reprconv.py — REPRCONV 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.