underwater_image — OPTICS watermedia op

• Data kinds: rgbimage × image2d × image2d → table

• Call: import fullseye as fs; fs.ledger.underwater_image(image, depth_map_m, distance_map_m, water_type='jerlov_I', wavelengths_um=None, illumination='daylight', backscatter=True, apply_ambient=False, beta_b_ratio=1.0, backscatter_ratio=0.02) -> 'dict' (implementation को सीधे call करना हो तो import watermedia; watermedia.underwater_image(image, depth_map_m, distance_map_m, water_type='jerlov_I', wavelengths_um=None, illumination='daylight', backscatter=True, apply_ambient=False, beta_b_ratio=1.0, backscatter_ratio=0.02) -> 'dict', registry से लेना हो तो opsoptics.get("underwater_image"))

• GPU: नहीं (केवल CPU reference implementation)

उपयोग

पानी के माध्यम से रिकॉर्ड किए गए दृश्य की छवि (संशोधित Jaffe–McGlamery मॉडल) -> dict।

> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।

Following Akkaynak & Treibitz (2018) the recorded image is I = J exp(-beta_D r) + B_inf (1 - exp(-beta_B r)): the direct signal J of the object attenuated along the camera-object distance r with a wavelength-dependent coefficient, plus backscatter, the veiling light B_inf that builds up along the same path with its own coefficient. image is (H, W, K), non-negative: the appearance of the object at zero distance, per band (K = 3 is RGB with the effective wavelengths 0.61 / 0.54 / 0.465 um, other K need wavelengths_um). depth_map_m is the depth of the scene below the surface and distance_map_m the distance to the camera, each (H, W) or a scalar. beta_D is the diffuse attenuation Kd of water_attenuation (used as the attenuation along the line of sight, an approximation that Akkaynak & Treibitz show to depend on range) and beta_B = beta_b_ratio beta_D. The veiling light is the single-scattering value B_inf = E(z) b_b / (2 c) with b_b = backscatter_ratio b and E(z) = E_0 exp(-Kd z) the daylight left at the depth (an assumption, not a measurement). illumination is "daylight" (flat relative spectrum 1) or a (K,) relative spectrum at the surface. With apply_ambient the object is also dimmed by the ambient light at its depth, J = image E(z); without it image is taken as it already is at the object, so that distance 0 returns it exactly. backscatter=False leaves pure Beer-Lambert. The table has image (the recording), direct, backscatter, transmission (exp(-beta_D r)), beta_D, beta_B, veiling_light (H, W, K), ambient (E(z)/E_0), wavelengths_um and, for RGB, red_to_blue_kd_ratio. Non-finite or negative inputs are refused.

पूरी family का input contract (fail-closed)

optics के सभी ops गणना से पहले input की जाँच करते हैं (कुछ भी चुपचाप पास नहीं होता):

• Unit argument के नाम में ही लिखी होती है — _mm / _um / _deg / _mrad। mm और µm की गड़बड़ी crash नहीं करती, बल्कि "सही दिखने वाला पर गलत उत्तर" देती है, इसलिए नाम से इसे रोका जाता है। मान के आकार से unit का अनुमान बिल्कुल नहीं लगाया जाता।

• String से ValueError — float('50') सफल हो जाता है, इसलिए बिना parse किया config value length के रूप में निकल जाता (मापा गया: thin_lens('50', '200') सही दिखने वाला 66.667 mm लौटा रहा था)। bool को भी True == 1 वाले implicit promotion के रूप में अस्वीकार किया जाता है।

• complex / masked array से ValueError (केवल real-valued slots; imaginary part को चुपचाप छोड़ना या mask हटाना अस्वीकार)। हर input पर NaN/Inf से ValueError।

• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: focal length 0, radius of curvature 0, refractive index <= 0, पूरी तरह opaque aperture (सब 0, इसलिए normalisation 0/0), ऐसा PSF जिसका योग <= 0 हो, S0 = 0 वाला Stokes vector, और front focal point पर रखा object (image अनंत पर)।

• केवल 2 ops non-finite value लौटाते हैं, और वह भी contract के रूप में लिखा हुआ: depth_of_field hyperfocal distance से आगे far_mm = inf (hyperfocal distance की परिभाषा यही है) और gaussian_beam waist पर wavefront_radius_mm = inf (plane wavefront की radius of curvature)। दोनों साथ में एक finite साथी (far_is_infinite / curvature_per_mm) भी लौटाते हैं। इसके अलावा कोई भी चुपचाप आया NaN/Inf अंदर ही पकड़ा जाता है और ValueError देता है — "float64 overflow हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता।

• Size की सीमा: generate होने वाले grid के लिए optics.MAX_GRID (4096), दिए गए field/PSF/aperture के लिए optics.MAX_FIELD_ELEMENTS (2^24), ABCD element chain के लिए optics.MAX_SYSTEM_ELEMENTS (1024), Zernike के लिए MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25)। छोटे argument से बहुत बड़ा internal allocation होने वाले रास्तों (मापा गया: n_max=40 × 4096² पर 108 GB) को fail-closed ढंग से बंद किया गया है।

• भौतिक रूप से असंभव states भी अस्वीकार: degree of polarisation > 1 वाला Stokes vector, ऋणात्मक transmittance, ऋणात्मक intensity, और n-|m| odd जैसे अमान्य Zernike indices।

उपयोग की विस्तृत guide

• optics_imaging family guide

संदर्भ (sample data, साहित्य)

• 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 में दिए गए हैं।

चलाए जा सकने वाले उदाहरण (verified samples जो सच में यह op call करते हैं)

• poc_water_transparent_media — py -3.11 examples/poc_water_transparent_media.py

वे अगले ops जिनसे type जुड़ता है (table को input के रूप में लेते हैं)

abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd

इसी category के (watermedia)

ocean_spectrum · ocean_height_field · fresnel_water_air · snell_window · refracted_view · water_attenuation · phase_function_hg · scattering_phase_petzold


*Provenance: watermedia.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.