prepare op• Data kinds: depth → depth
• Call: import fullseye as fs; fs.ledger.surface_form_remove(z, dx, order=1, method='ls', thresh=None, dy=None, iters=200, seed=0) (implementation को सीधे call करना हो तो import roughness; roughness.surface_form_remove(z, dx, order=1, method='ls', thresh=None, dy=None, iters=200, seed=0), registry से लेना हो तो opsroughness.get("surface_form_remove"))
• Ledger के ज़रिए return value: fullseye.ledger.surface_form_remove(...) केवल घोषित out type depth का value लौटाता है (मूल function सहायक जानकारी भी लौटाता है)। जो हिस्सा छोड़ दिया गया है उसकी ज़रूरत हो तो fullseye.ledger.surface_form_remove.raw(...) का उपयोग करें, या roughness.surface_form_remove को सीधे call करें।
• मूल function का return: (residual, coeffs)
grid पर ही plane / quadric surface हटाता है। (residual, coeffs) लौटाता है।
Arguments
z height field।
dx, dy sampling intervals। dy=None का अर्थ square pixels।
order 1 = plane, 2 = quadric surface।
method "ls" (least squares) या "ransac" (robust)।
thresh RANSAC inlier threshold (height की इकाई में)। None पर least-squares residuals का robust spread
2.5 x 1.4826 x MAD इस्तेमाल होता है।
iters RANSAC trials की संख्या। seed के ज़रिए deterministic।
coeffs field centre को origin मानकर physical coordinates में monomial coefficients हैं। order=1 के लिए ये [c0, gx, gy] हैं, जिनमें gx/gy सीधे gradient हैं; order=2 के लिए ये [c0, gx, gy, cxx, cxy, cyy] हैं (x^2, xy, y^2 क्रम में)।
★ यह grid को grid के रूप में ही क्यों लेता है
मौजूदा fit_plane / fit_plane_ransac केवल (N,3) point clouds स्वीकार करते हैं।
उन्हें 512² height field देने के लिए हर बार column_stack से 262144x3 = 6.3 MB में फैलाना पड़ता है
(measured)। यह op grid को grid के रूप में लेता है और basis को
1-D vectors के outer products से बनाता है, इसलिए फैलाने की ज़रूरत नहीं।
★ लागत (measured, 1024x1024, iters=200)
method="ls" 47 ms बनाम method="ransac" 1.8 s (38 गुना)।
RANSAC हर trial पर 1024² points के residuals दोबारा गिनता है, इसलिए यह iters के साथ linear बढ़ता है।
अगर केवल roughness देखनी है, तो "LS + λc high-pass" 1/40 लागत पर समान उत्तर देता है
(नीचे के measurements देखें) — इसी कारण RANSAC default नहीं है।
★ गड्ढा — robustness की ज़रूरत "गहरी scratches" के लिए नहीं बल्कि "चौड़े outliers" के लिए है।
लेकिन जब outliers बहुमत बन जाते हैं, तो RANSAC भी टूट जाता है।
एक तरफ़ इकट्ठी 3 µm गहराई की 4 scratches वाली 512x512 surface पर, scratches की केवल चौड़ाई बदलकर measured
(0.050/-0.025 का tilt डालकर हटाया जाता है; ground truth scratches सहित surface खुद है):
scratch HWHM area ratio LS Sq error RANSAC Sq error gain
4 µm 5.6 % -1.94 % -0.39 % 5.0x
12 µm 16.3 % -6.47 % -3.03 % 2.1x
24 µm 31.0 % -13.79 % -11.53 % 1.2x
40 µm 46.0 % -23.80 % -23.56 % 1.0x
3 बातें पढ़ी जा सकती हैं:
• मायने गहराई के नहीं बल्कि area ratio के हैं। "गहरी scratch = robust fit ज़रूरी" जल्दबाज़ी का निष्कर्ष है; सही रूप है "चौड़े outliers = robust fit ज़रूरी"।
• Error हमेशा कम की ओर आता है — क्योंकि least squares "scratches के एक तरफ़ इकट्ठा होने से बनी असली asymmetry" को भी plane में सोख लेता है। Pass/fail निर्णयों में यह ख़तरनाक दिशा में गलत होता है।
• 46 % area ratio पर RANSAC भी मदद नहीं करता (gain 1.0x)। जब outliers लगभग आधा हिस्सा घेर लेते हैं, तो RANSAC का majority vote खुद scratches को चुनता है। Robust fitting "outliers अल्पसंख्यक हैं" की मान्यता पर टिका tool है, और वह मान्यता कहाँ टूटती है यह केवल table से दिखाया जा सकता है।
★ गड्ढा — λc को downstream रखने से LS और RANSAC का अंतर गायब हो जाता है
उसी surface (HWHM 4 µm) पर बाद में λc=80 µm high-pass लगाने पर,
Sq error LS +0.00 % / RANSAC -0.00 % है (ऊपर की table में 5.0x का अंतर)।
हटाया गया अतिरिक्त plane शुद्ध लंबी wavelength है, इसलिए high-pass बस वही चीज़
एक बार और फेंक देता है। Fit की robustness उन workflows में मायने रखती है जिनमें λc नहीं लगता (flatness, form deviation)। अगर केवल roughness देखनी है, तो क्रम ही आपको बचा लेता है।
ध्यान दें कि plane खुद LS से भी अच्छी तरह मिलता है: ऊपर की surface में डाले गए gradients
0.050 / -0.025 के लिए यह 0.050006 / -0.025127 लौटाता है (measured)।
fail-closed
• order 1 या 2 के अलावा / method "ls" या "ransac" के अलावा।
• thresh धनात्मक नहीं या finite नहीं।
• RANSAC ज़रूरी संख्या में inliers इकट्ठा नहीं कर पाता (degenerate surface)।
• 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_polish_wipe_measure — py -3.11 examples/poc_polish_wipe_measure.py
• poc_pv_thermal_survey — py -3.11 examples/poc_pv_thermal_survey.py
• poc_surface_roughness — py -3.11 examples/poc_surface_roughness.py
depth को input के रूप में लेते हैं)surface_filter · 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.