prepare op• Data kinds: depth → depth
• Call: import fullseye as fs; fs.ledger.surface_filter(z, dx, lambda_c=None, lambda_s=None, kind='gaussian', end_effect='reject', dy=None) (implementation को सीधे call करना हो तो import roughness; roughness.surface_filter(z, dx, lambda_c=None, lambda_s=None, kind='gaussian', end_effect='reject', dy=None), registry से लेना हो तो opsroughness.get("surface_filter"))
• Ledger के ज़रिए return value: fullseye.ledger.surface_filter(...) केवल घोषित out type depth का value लौटाता है (मूल function सहायक जानकारी भी लौटाता है)। जो हिस्सा छोड़ दिया गया है उसकी ज़रूरत हो तो fullseye.ledger.surface_filter.raw(...) का उपयोग करें, या roughness.surface_filter को सीधे call करें।
• मूल function का return: (roughness, waviness)
height field को roughness और waviness में अलग करता है (ISO 16610-21 का Gaussian filter)।
(roughness, waviness) लौटाता है। roughness λc से छोटा component है, waviness लंबा वाला, और जब तक end_effect="reject" न हो, roughness + waviness इनपुट (λs लगाने के बाद की primary surface) से बिल्कुल मेल खाता है।
Arguments
z height field z[i, j] (row = y, column = x)।
dx, dy sampling intervals। dy=None का अर्थ square pixels।
lambda_c long-wavelength cutoff (roughness / waviness के बीच की सीमा)। None पर कोई विभाजन नहीं
(waviness zeros का array है)।
lambda_s short-wavelength cutoff (noise हटाने वाला S-filter)। None पर बंद।
kind केवल "gaussian"। कुछ और देने पर चुपचाप बदलने की बजाय exception raise होता है।
end_effect "reject" (default) / "mirror" / "wrap"। नीचे देखें।
dy rows के साथ sampling interval (None = dx)।
★ सिरों का handling (end_effect) — यह op लिखे जाने का कारण
Convolution को सिरों पर kernel radius λc/2 तक "वहाँ का data जहाँ data है ही नहीं" चाहिए।
Standard (ISO 16610-28) मानता है कि evaluation area दोनों सिरों पर λc/2 से काटा जाता है।
• "reject" (default) — दोनों सिरों पर ceil(λc/2/pitch) samples फेंक देता है। आउटपुट इनपुट से छोटा array है। फेंका गया region "मापा नहीं गया" है, इसलिए यही एकमात्र विकल्प है जो कोई झूठ नहीं बोलता।
• "mirror" — mirror करके बढ़ाता है और समान shape लौटाता है। मानता है कि सिरों पर surface even function है।
• "wrap" — circular convolution (FFT जैसा)। मानता है कि बाएँ सिरे के आगे दायाँ सिरा आता है।
Measured। Ground truth एक 704x704 surface है जिसे पहले filter करके फिर बीच के 512x512 तक crop किया गया
(सिरों के बाहर असली data मौजूद रहते हुए निकाला गया उत्तर)। dx=1, λc=80,
end band = बाहरी 40 samples, जहाँ ground-truth rms 0.1932 है।
surface end_effect end-band rms error center rms error
tilted wrap 4.3883 (2272 %) 0.0e+00 (0.000 %)
tilted mirror 0.1765 ( 91 %) 0.0e+00 (0.000 %)
tilt removed wrap 0.0111 ( 5.7 %) 4.4e-15 (0.000 %)
tilt removed mirror 0.0115 ( 5.9 %) 4.4e-15 (0.000 %)
(any) reject — not returned — 0.0e+00 (0.000 %)
4 बातें पढ़ने लायक:
1. सिरों का handling केवल सिरों पर मायने रखता है। Centre हर स्थिति में ground truth से बिल्कुल मेल खाता है (स्वाभाविक, क्योंकि kernel सिरों तक नहीं पहुँचता, लेकिन जाँचा गया)।
2. सबसे बुरा संयोजन "tilt छोड़कर wrap" है — सिरे का error ground truth का 23 गुना है। चूँकि यह मानता है कि बाएँ सिरे के आगे दायाँ सिरा आता है, अलग ऊँचाई वाले 2 किनारों के जोड़ पर एक step उठ जाता है।
3. Tilt हटाने के बाद wrap और mirror में अंतर नहीं रहता (5.7 % बनाम 5.9 %, wrap थोड़ा बेहतर)। "Circular convolution हमेशा बुरा है" नहीं, बल्कि "tilt हटाए बिना इसका इस्तेमाल बुरा है" सही है।
4. Reject की कीमत area है। 512x512 और λc=80 पर यह 28.8 % फेंक देता है (432x432 बचता है)। फेंका गया हिस्सा 1 - (1 - λc/L)² के रूप में बढ़ता है, इसलिए जब λc evaluation length के 1/4 से ज़्यादा हो जाए, तो लगभग आधा खो जाता है।
★ क्या transmission वैसा है जैसा standard कहता है? (measured, λc=80, dx=1, पूर्णांक period वाली sines projection से मापी गईं)
λ waviness ISO value diff
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 ← max
128 0.772150 0.762799 +9.4e-03
256 0.937944 0.934550 +3.4e-03
ठीक cutoff wavelength पर यह 0.5000 नहीं, 0.5095 है (relative +1.9 %)। कारण है
standard द्वारा तय truncation ±λc/2 (= 2.67 σ), जो tails का 0.8 % छोड़ देता है।
Truncation को 4 σ (±0.75 λc) तक चौड़ा करने से अधिकतम error 9e-05 तक घटता है
(measured), लेकिन reject द्वारा फेंका गया band 1.5 गुना चौड़ा हो जाता है। हमने standard का पालन करना और विचलन को document करना चुना। Roughness और waviness का योग हमेशा इनपुट से बिल्कुल मेल खाता है
(ऊपर की table में roughness + waviness = 1.000000), इसलिए केवल बाँटने वाली सीमा
1.9 % खिसकती है; कोई energy न गायब होती है न प्रकट होती है।
fail-closed
• kind "gaussian" के अलावा / end_effect 3 ज्ञात मानों के अलावा।
• lambda_c और lambda_s दोनों None हैं (ऐसी call जो कुछ नहीं करती)।
• Nyquist wavelength 2*pitch से नीचे, या evaluation length से आगे का cutoff।
• lambda_s >= lambda_c (band ख़ाली हो जाता है)।
• "reject" से काटने के बाद कोई array नहीं बचता।
• surface_roughness family guide
• Sample data catalog (DL URL / license) — 2-D के लिए skimage.data (BSD/public) + synthetic, 3-D के लिए real data sources (Stanford/PDS आदि) के DL URL।
• Operators का स्रोत और संदर्भ — इस op family के मूल research/methods के स्रोत।
• Algorithm का मानक स्रोत (लेखक, वर्ष) और उपयोग ऊपर की family usage guide में दिए गए हैं।
• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py
depth को input के रूप में लेते हैं)surface_form_remove · surface_params · surface_psd
prepare)*Provenance: roughness.py — ROUGHNESS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.