watervision op• Data kinds: कोई नहीं → table (केवल arguments से तय होने वाला op — यह कोई image या data input नहीं लेता)
• Call: import fullseye as fs; fs.ledger.bottle_image(radius_mm, wall_mm, height_mm, fill_fraction, n_glass, n_liquid, meniscus_mm=0.0, bubbles=None, camera_distance_mm=500.0, pixel_pitch_um=20.0, size=None, light='backlight', n_air=1.0) -> 'dict' (implementation को सीधे call करना हो तो import watervision; watervision.bottle_image(radius_mm, wall_mm, height_mm, fill_fraction, n_glass, n_liquid, meniscus_mm=0.0, bubbles=None, camera_distance_mm=500.0, pixel_pitch_um=20.0, size=None, light='backlight', n_air=1.0) -> 'dict', registry से लेना हो तो opsoptics.get("bottle_image"))
• GPU: नहीं (केवल CPU reference implementation)
तरल से आंशिक रूप से भरी बेलनाकार बोतल का पार्श्व दृश्य, पंक्ति-दर-पंक्ति ray tracing से -> dict।
> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।
The bottle (outer radius radius_mm, glass wall wall_mm, height height_mm, axis vertical, base at z = 0) is looked at by a pinhole camera camera_distance_mm from the axis. Every image row is the horizontal cross-section at its height: the ray of a pixel is traced through the circles of the section (outer wall, inner wall, the edge of the liquid in a meniscus row, bubbles) with the vector form of Snell's law and the unpolarised Fresnel transmittance at each interface. Total internal reflection reflects the ray (at most 24 interface events are followed; a ray still wandering then is counted in unresolved_rays and left dark). The liquid (n_liquid) fills the bottle up to fill_fraction * height_mm; meniscus_mm lets it climb the wall by that much as (rho / r_inner)^6. bubbles is a list of (x_mm, z_mm, r_mm) (or with a fourth y_mm along the viewing axis; default 0): air spheres in the liquid, drawn as their circle in each row they cross. pixel_pitch_um is the sampling pitch in the plane of the axis, so 1000 / pixel_pitch_um pixels are 1 mm there; size is (rows, cols) (default: the rows exactly cover the height, the width is 1.15 times the diameter); row j is at z = height - (j + 0.5) pitch.
light="backlight": a diffuse panel of radiance 1 behind the bottle that emits only within +-8 degrees of the viewing axis (soft edge 1 degree): a pixel is lit when its ray leaves the bottle inside that cone, times the product of the Fresnel transmittances. The empty bottle bends rays little and is lit to near the edges; the filled one is a cylindrical lens, so only a central band (half width alpha / (1/f - 1/dc) with the paraxial focal length f of watermedia.cylinder_lens_caustic) is lit and the flanks go dark; an air bubble in the liquid is a diverging lens and shows as a dark ring. light="frontlight": a matt wall of radiance 0.8 behind, a dim dome plus a soft box at 35 degrees, and the first Fresnel reflection of the outer wall (R times the environment radiance), which gives the glint and the bright rim at grazing view. Interior reflections other than total internal reflection are not followed, the rows are independent (no vertical refraction at the shoulder or the base), and rows without bubbles or meniscus are computed once per kind (the empty and the full section), so rows of equal geometry are bit identical.
The table has image (rows, cols; no pixel exceeds 1), x_mm, z_mm, pixel_pitch_mm, magnification_px_per_mm, fill_row_from_top (the first liquid row), liquid_rows (rows with liquid; about fill_fraction height / pitch), fill_z_mm, paraxial_efl_mm and band_half_width_mm_paraxial (the predicted half width of the lit band of the filled bottle, inf when the lens does not converge within the camera distance), central_transmittance_empty / ..._filled (the product of the normal-incidence Fresnel transmittances of the four interfaces on the axis), unresolved_rays and the inputs echoed. n_glass <= 1, n_liquid <= 1, n_air < 1 or not below both, a fill outside [0, 1], a wall not thinner than the radius, a meniscus that does not fit and a bubble outside the liquid are refused.
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।
• 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_water_inspection_images — py -3.11 examples/poc_water_inspection_images.py
table को input के रूप में लेते हैं)abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd
watervision)caustic_irradiance · fill_level_from_image · wet_surface_appearance · wet_dry_inspection_pair · underwater_inspection_image · caustic_floor_segmentation
*Provenance: watervision.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.