watervision op• Datenarten: rgbimage × image2d → table
• Aufruf: import fullseye as fs; fs.ledger.underwater_inspection_image(scene_albedo, distance_map_m, water_type, light='camera', lamp_power=1.0, camera_distance_m=None, depth_m=2.0, exposure_photons=10000.0, fov_deg=60.0, beam_exponent=6.0) -> 'dict' (die Implementierung direkt: import watervision; watervision.underwater_inspection_image(scene_albedo, distance_map_m, water_type, light='camera', lamp_power=1.0, camera_distance_m=None, depth_m=2.0, exposure_photons=10000.0, fov_deg=60.0, beam_exponent=6.0) -> 'dict'; aus dem Register: opsoptics.get("underwater_inspection_image"))
• GPU: nein (nur CPU-Referenzimplementierung)
Inspektionsbild eines Schiffsrumpfs oder Rohrs: eine Lampe an der Kamera beleuchtet eine Wand durch das Wasser -> dict (Bild, SNR pro Pixel).
> Die ausführliche Beschreibung unten ist der Originaltext — Zusammenfassung und Überschriften sind übersetzt.
A thin layer over watermedia.underwater_image (the Akkaynak and Treibitz form: direct signal plus backscatter veil). scene_albedo is (H, W) or (H, W, 3) and distance_map_m (H, W) the camera-to-surface distance (> 0). light="camera": the only light is a lamp at the camera of lamp_power (relative power at 1 m); the wall is lit by lamp_power exp(-c r) / r^2 (beam attenuation c of the water at 0.61 / 0.54 / 0.465 um), reflects its albedo and the return path attenuates with Kd. The lamp also lights the water in front of the lens: the veil of the water type's single-scattering backscatter grows as 1 - exp(-Kd r) and is weighted by the lamp's beam pattern, cos(theta)^beam_exponent with theta the angle of the pixel from the axis (fov_deg across the width): strongest in the centre, where the lamp and the camera look at the same water. A baseline between lamp and camera, camera_distance_m (default
None: the lamp is at the camera), reduces the overlap of the lit and the seen water by 1 / (1 + (baseline / r)^2). light="ambient": daylight at depth_m and a veil of the daylight, uniform over the image (lamp_power is not used). light="both": the lamp and the daylight together (the signals and the veils add).
snr = sqrt(N) direct / sqrt(direct + backscatter + 1e-12) is the shot-noise limited signal to noise of the direct signal against its own shot noise and the shot noise of the veil (N = exposure_photons per unit radiance): it falls with distance because the direct term falls and the veil grows. snr_clear is the same expression for water that does not attenuate or scatter (equal to snr as the distance tends to 0). The table has image (H, W, 3), direct, backscatter, snr, snr_clear, snr_mean (over the three bands), veil_profile (H, W), transmission, beam_attenuation_c, kd, water_type and light. A zero or negative distance, an albedo outside [0, 1], an unknown water type and a bad light are refused.
Jeder optics-Operator prüft seine Eingabe vor der Berechnung (nichts rutscht stillschweigend durch):
• Einheiten stecken im Argumentnamen — _mm / _um / _deg / _mrad. Eine Verwechslung von mm und µm stürzt nicht ab, sondern liefert eine plausibel aussehende falsche Antwort; der Name verhindert das. Aus der Größenordnung wird nie auf die Einheit geschlossen.
• Strings lösen ValueError aus — float('50') gelingt, sodass ein ungeparster Konfigurationswert als Länge durchrutschen würde (gemessen: thin_lens('50', '200') lieferte plausible 66,667 mm). bool wird als implizite Hochstufung True == 1 ebenfalls abgelehnt.
• complex / Masked Arrays lösen ValueError aus (nur reelle Slots; das stille Verwerfen des Imaginärteils bzw. Abstreifen der Maske wird abgelehnt). NaN/Inf löst bei jeder Eingabe ValueError aus.
• Division durch null und Verwandtes wird namentlich abgelehnt: Brennweite 0, Krümmungsradius 0, Brechzahl <= 0, undurchlässige Blende (alles 0, die Normierung wird 0/0), PSF mit Summe <= 0, Stokes-Vektor mit S0 = 0 und ein Objekt im vorderen Brennpunkt (Bild im Unendlichen).
• Nur zwei Operatoren liefern einen nicht-endlichen Wert, und beide halten das vertraglich fest: depth_of_field liefert jenseits der hyperfokalen Distanz far_mm = inf (genau das bedeutet die hyperfokale Distanz), und gaussian_beam liefert an der Taille wavefront_radius_mm = inf (der Krümmungsradius einer ebenen Wellenfront). Beide liefern zusätzlich einen endlichen Partner (far_is_infinite / curvature_per_mm). Jedes andere stille NaN/Inf wird intern erkannt und löst ValueError aus — "float64 ist übergelaufen" und "die Antwort ist unendlich" sind verschiedene Aussagen; die erste wird nie im Gewand der zweiten geliefert.
• Größenobergrenzen: erzeugte Gitter durch optics.MAX_GRID (4096), übergebene Felder/PSFs/Blenden durch optics.MAX_FIELD_ELEMENTS (2^24), ABCD-Elementketten durch optics.MAX_SYSTEM_ELEMENTS (1024), Zernike durch MAX_ZERNIKE_TERMS (512) / MAX_ZERNIKE_ORDER (40) / MAX_ZERNIKE_BASIS (2^25). Damit werden Pfade fail-closed geschlossen, in denen ein kleines Argument eine riesige interne Allokation auslöst (gemessen: n_max=40 × 4096² braucht 108 GB).
• Physikalisch unmögliche Zustände werden ebenfalls abgelehnt: Stokes-Vektor mit Polarisationsgrad > 1, negative Transmission, negative Intensität und ungültige Zernike-Indizes wie ungerades n-|m|.
• Leitfaden zur Familie optics_imaging
• 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.
• poc_water_inspection_images — py -3.11 examples/poc_water_inspection_images.py
table als Eingabe)abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd
watervision)caustic_irradiance · bottle_image · fill_level_from_image · wet_surface_appearance · wet_dry_inspection_pair · caustic_floor_segmentation
*Provenance: watervision.py — OPTICS 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.