surface_filter — ROUGHNESS prepare op

• Datenarten: depth → depth

• Aufruf: import fullseye as fs; fs.ledger.surface_filter(z, dx, lambda_c=None, lambda_s=None, kind='gaussian', end_effect='reject', dy=None) (die Implementierung direkt: import roughness; roughness.surface_filter(z, dx, lambda_c=None, lambda_s=None, kind='gaussian', end_effect='reject', dy=None); aus dem Register: opsroughness.get("surface_filter"))

• Rückgabewert über das Register: fullseye.ledger.surface_filter(...) 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_filter.raw(...) oder rufe roughness.surface_filter direkt auf.

• Rückgabe der Funktion: (roughness, waviness)

Verwendung

Zerlegt ein Höhenfeld in Rauheit und Welligkeit (Gauß-Filter nach ISO 16610-21).

Rückgabe ist (roughness, waviness). roughness ist der Anteil kürzer als λc, waviness der längere, und sofern nicht end_effect="reject", stimmt roughness + waviness exakt mit der Eingabe (der Primärfläche nach Anwendung von λs) überein.

Argumente

z Höhenfeld z[i, j] (Zeile = y, Spalte = x).

dx, dy Abtastabstände. dy=None bedeutet quadratische Pixel.

lambda_c langwellige Grenzwellenlänge (Grenze Rauheit / Welligkeit). Bei None keine Trennung

(waviness ist ein Null-Array).

lambda_s kurzwellige Grenzwellenlänge (S-Filter gegen Rauschen). Mit None deaktiviert.

kind nur "gaussian". Alles andere löst eine Ausnahme aus, statt stillschweigend ersetzt zu werden.

end_effect "reject" (Standard) / "mirror" / "wrap". Siehe unten.

dy Abtastabstand in Zeilenrichtung (None = dx).

★ Randbehandlung (end_effect) — der Grund, warum dieser op geschrieben wurde

Die Faltung braucht an den Rändern über den Kernradius λc/2 hinweg "Daten von dort, wo keine sind".

Die Norm (ISO 16610-28) setzt voraus, dass der Auswertebereich an beiden Enden um je λc/2 beschnitten wird.

• "reject" (Standard) — verwirft an beiden Enden ceil(λc/2/pitch) Abtastwerte. Die Ausgabe ist ein kleineres Array als die Eingabe. Der verworfene Bereich ist "nicht gemessen", daher ist dies die einzige Option ohne Lüge.

• "mirror" — setzt spiegelbildlich fort und gibt dieselbe Form zurück. Nimmt an, dass die Fläche an den Rändern eine gerade Funktion ist.

• "wrap" — zyklische Faltung (wie FFT). Nimmt an, dass auf das linke Ende das rechte Ende folgt.

Gemessen. Die Ground Truth ist eine 704x704-Fläche, zuerst gefiltert und dann auf die mittleren 512x512 zugeschnitten

(die Antwort, berechnet mit echten Daten außerhalb der Ränder). dx=1, λc=80,

Randstreifen = äußere 40 Abtastwerte, dort beträgt der rms der Ground Truth 0.1932.

Flächenzustand end_effect rms-Fehler Randstreifen rms-Fehler Mitte

geneigt wrap 4.3883 (2272 %) 0.0e+00 (0.000 %)

geneigt mirror 0.1765 ( 91 %) 0.0e+00 (0.000 %)

Neigung entfernt wrap 0.0111 ( 5.7 %) 4.4e-15 (0.000 %)

Neigung entfernt mirror 0.0115 ( 5.9 %) 4.4e-15 (0.000 %)

(beliebig) reject — keine Rückgabe — 0.0e+00 (0.000 %)

4 Erkenntnisse:

1. Die Randbehandlung wirkt nur am Rand. Die Mitte stimmt bei allen exakt mit der Ground Truth überein (selbstverständlich, da der Kern die Ränder nicht erreicht, aber geprüft).

2. Die schlechteste Kombination ist "wrap mit verbliebener Neigung" — der Randfehler beträgt das 23-fache der Ground Truth selbst. Da angenommen wird, dass auf das linke Ende das rechte folgt, entsteht an der Nahtstelle der 2 unterschiedlich hohen Kanten eine Stufe.

3. Ist die Neigung entfernt, gibt es zwischen wrap und mirror keinen Unterschied (5.7 % gegen 5.9 %, wrap etwas besser). Nicht "zyklische Faltung ist immer schlecht", sondern "sie zu verwenden, ohne die Neigung zu entfernen, ist schlecht" ist richtig.

4. Der Preis von reject ist Fläche. Bei 512x512 und λc=80 werden 28.8 % verworfen (432x432 bleiben). Der verworfene Anteil wächst mit 1 - (1 - λc/L)², daher geht fast die Hälfte verloren, sobald λc 1/4 der Messstrecke übersteigt.

★ Entspricht die Übertragung der Norm? (gemessen, λc=80, dx=1, Sinus mit ganzzahliger Periode per Projektion gemessen)

λ Welligkeit ISO-Normwert Differenz

16 0.000806 0.000000 +8.1e-04

32 0.017206 0.013139 +4.1e-03

40 0.058676 0.062500 -3.8e-03

64 0.342826 0.338564 +4.3e-03

80 0.509549 0.500000 +9.6e-03 ← Maximum

128 0.772150 0.762799 +9.4e-03

256 0.937944 0.934550 +3.4e-03

Bei der Grenzwellenlänge selbst 0.5095 statt 0.5000 (relativ +1.9 %). Ursache ist

die von der Norm vorgegebene Kappung ±λc/2 (= 2.67 σ), durch die 0.8 % der Ausläufer wegfallen.

Erweitert man die Kappung auf 4 σ (±0.75 λc), fällt der maximale Fehler auf 9e-05

(gemessen), aber der von reject verworfene Streifen wird 1.5-mal so breit. Wir haben uns entschieden, der Norm zu folgen und die Abweichung zu dokumentieren. Die Summe aus Rauheit und Welligkeit stimmt stets exakt mit der Eingabe überein

(roughness + waviness = 1.000000 in der Tabelle oben), daher verschiebt sich nur die Aufteilungsgrenze

um 1.9 %; Energie verschwindet weder, noch entsteht sie.

fail-closed

• kind nicht "gaussian" / end_effect keiner der 3 bekannten Werte.

• lambda_c und lambda_s beide None (ein Aufruf, der nichts tut).

• Grenzwellenlänge unter der Nyquist-Wellenlänge 2*pitch oder über der Messstrecke.

• lambda_s >= lambda_c (das Band wird leer).

• nach dem Beschneiden mit "reject" bleibt kein Array übrig.

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_surface_roughness — py -3.11 examples/poc_surface_roughness.py

Typkompatible Folge-Operatoren (nehmen depth als Eingabe)

surface_form_remove · surface_params · surface_psd

Gleiche Kategorie (prepare)

surface_form_remove


*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.