surface_synth_psd — ROUGHNESS synth op

• Datenarten: keine → depth (ein Operator, der allein durch seine Argumente bestimmt ist — er nimmt kein Bild und keine Daten entgegen)

• Aufruf: import fullseye as fs; fs.ledger.surface_synth_psd(n, dx, hurst, lambda_lo, lambda_hi, sq, seed=0) (die Implementierung direkt: import roughness; roughness.surface_synth_psd(n, dx, hurst, lambda_lo, lambda_hi, sq, seed=0); aus dem Register: opsroughness.get("surface_synth_psd"))

• Rückgabewert über das Register: fullseye.ledger.surface_synth_psd(...) liefert nur den Wert des deklarierten Out-Typs depth (die zugrunde liegende Funktion gibt zusätzlich Hilfsinformationen zurück). Wird das Verworfene gebraucht, nutze fullseye.ledger.surface_synth_psd.raw(...) oder rufe roughness.surface_synth_psd direkt auf.

• Rückgabe der Funktion: (z, sq_analytic)

Verwendung

Synthetisiert ein Höhenfeld aus einer vorgegebenen PSD. Gibt (z, sq_analytic) zurück.

Setzt auf jede Mode im Band lambda_lo <= λ <= lambda_hi eine Amplitude A(q) ∝ q^-(H+1) (= flächenhafte PSD C(q) ∝ q^-2(H+1), selbstaffin) und macht nur die Phasen zufällig. Normiert das Ganze auf sq und gibt es zurück.

Argumente

n Gittergröße. Eine Ganzzahl ergibt n x n; (ny, nx) ist ebenfalls möglich.

dx Abtastabstand (quadratische Pixel).

hurst Hurst-Exponent H (0 < H < 1). Je größer, desto glatter.

lambda_lo Wellenlänge am kurzen Ende des Bands.

lambda_hi Wellenlänge am langen Ende des Bands.

sq Ziel-Sq (rms-Höhe innerhalb des Bands).

seed Zufallsstartwert für die Phasen.

★ Entscheidend ist, das analytische Sq mitzuliefern

Da die Amplituden fest sind und nur die Phasen variieren, folgt aus Parseval

<h²> = (1/(ny nx))² Σ_k A_k² unabhängig davon, wie die Phasen gezogen werden.

Die Ground Truth von Sq hängt also nicht von den Zufallszahlen ab. Gemessen: Die relative Abweichung zwischen z.std() und

sq_analytic beträgt, auch wenn seed, H, Band und Größe variiert werden,

höchstens 2.2e-16 (Tabelle unten). Erledigt man das mit "Zufallszahlen variieren und rms messen",

streut die Ground Truth selbst mit jeder Realisierung und vermischt sich mit den Fehlern nachgelagerter Stufen.

n H λ-Band sq |std/analytic-1| Kurtosis PTV/rms

128 0.30 4-32 0.5000 2.2e-16 3.084 7.97

256 0.50 4-64 0.0800 0.0e+00 3.005 7.85

256 0.80 2-64 0.0800 2.2e-16 2.893 6.92

512 0.80 2-64 0.0800 0.0e+00 3.113 8.25

512 0.95 8-256 2.0000 0.0e+00 2.542 5.69

★ Die Falle, in die der PoC getreten ist, ist in der Implementierung eingeschlossen

Macht man die Phase, um die Koeffizienten hermitesch zu machen, mit phi = (u - u[-k]) / 2

antisymmetrisch, wird sie zwar antisymmetrisch, aber die Phase ist nicht mehr gleichverteilt

(sie wird dreiecksverteilt und häuft sich nahe 0). Dann addieren sich alle Moden im Ursprung phasengleich,

und im Höhenfeld entsteht 1 Spitze. Gemessen mit demselben Startwert und demselben Band

(512², H=0.8, Band 2-64):

Phasenerzeugung PTV/rms Kurtosis |std/analytic-1|

antisymmetrisiert mit (u - u[-k])/2 55.00 71.81 0.0e+00

gleichverteilt nur je eine Paarhälfte 8.47 2.95 0.0e+00 ← korrekt

Bei beiden stimmt Sq exakt mit dem analytischen Wert überein. Ein Defekt, den man nicht bemerkt,

wenn man nur die Varianz ansieht; daher ist diese Funktion auf die Implementierung festgelegt, die gleichverteilte Zufallszahlen

nur für eine Hälfte jedes konjugierten Paars zieht, und die Tests prüfen auch Kurtosis und PTV/rms. Selbstkonjugierte Moden

(k = -k, 4 Punkte) müssen reelle Koeffizienten haben, daher wird statt einer Phase

ein Vorzeichen ±1 ausgewürfelt (eine auf 0 fixierte Phase würde alle zu +A verzerren).

fail-closed

• n kleiner als 8 / dx nicht positiv / hurst außerhalb von (0, 1).

• lambda_lo >= lambda_hi.

• lambda_lo unter der Nyquist-Wellenlänge 2*dx (nicht realisierbares Band).

• lambda_hi über der Messstrecke (nicht einmal 1 Periode passt hinein).

• sq nicht positiv.

• Nicht einmal 1 Mode liegt im Band (Gitter zu grob / Band zu schmal).

Ausführlicher Anwendungsleitfaden

• Leitfaden zur Familie surface_roughness

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.

• Der kanonische Algorithmus (Autor, Jahr) und seine Anwendungen stehen im Familienleitfaden oben.

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

• poc_polish_wipe_measure — py -3.11 examples/poc_polish_wipe_measure.py

• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py

Typkompatible Folge-Operatoren (nehmen depth als Eingabe)

surface_form_remove · surface_filter · surface_params · surface_psd

Gleiche Kategorie (synth)

—


*Provenance: roughness.py — ROUGHNESS 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.