watervision op• 数据种类:无 → table(仅由参数决定的算子 —— 不接受图像或数据输入)
• 调用: import fullseye as fs; fs.ledger.bottle_fit_from_pattern(u_map, x_mm, pixel_pitch_um, camera_distance_mm, background_distance_mm, known=None, free_background=False, rows_per_section=None, restarts=3) -> 'dict'(要直接调用实现,import watervision; watervision.bottle_fit_from_pattern(u_map, x_mm, pixel_pitch_um, camera_distance_mm, background_distance_mm, known=None, free_background=False, rows_per_section=None, restarts=3) -> 'dict';从台账取用则 opsoptics.get("bottle_fit_from_pattern"))
• GPU:无(仅 CPU 参考实现)
从背景图案的畸变反推瓶子 -> 字典(半径、壁厚、折射率、液面,以及各量能确定到什么程度)。
> 以下的详细说明为原文 —— 摘要与标题已翻译。
u_map (rows, cols) is the background coordinate (mm) each pixel looks at (the u_mm of bottle_background_map, or a phase-shifting measurement of it; NaN where unusable); x_mm the column positions in the plane of the axis, pixel_pitch_um the pitch, the camera and the pattern are camera_distance_mm and background_distance_mm from the axis (known from the set-up). The fill line is found first, from the jump of the map between rows (the liquid and the air bend the pattern differently): rows above it are the empty section, rows below the filled one (level_mm as in fill_level_from_image: (rows below the boundary) * pitch). Each section is reduced to one profile (the median over its rows, rows_per_section of them if given, the two rows next to the boundary left out) and a closed-form model of concentric circles, written without the tracer (an angle and an impact parameter per ray), is fitted by Levenberg-Marquardt over radius_mm, wall_mm, n_glass and n_liquid (the filled section; a bottle with no fill line is one section whose core index is fitted). known is a dict of values held fixed ("radius_mm", "wall_mm", "n_glass", "n_liquid"); free_background=True also fits the distance of the pattern. The start is a scan of the radius from the silhouette (where the map leaves the straight line) with restarts (1 to 3) different index starts; the table reports how far the starts that reach the same cost disagree (start_spread).
The table has radius_mm, wall_mm, n_glass, n_liquid, background_distance_mm, free (the fitted names), sigma (1 sigma of each free name from the Gauss-Newton covariance with the residual scatter as the noise, None if not free), corr (correlation matrix of the free names) with corr_names, cond (condition number of the Jacobian with unit-length
columns: a large value means some combination of the parameters is hardly seen), singular_values, weak_direction (the combination with the smallest singular value, one number per free name) and weak_rel_sigma (the 1 sigma relative change along it), residual_rms_mm, n_columns and columns_rejected (resolved pixels the model calls blocked), converged, iterations, level_found / level_mm / level_row / level_jump_mm (False and None when the rows do not
jump: an empty or a full bottle has no fill line to read; level_mm is then None), fill_state ("partial" or "uniform"). poorly_determined lists the fitted names whose 1 sigma exceeds 1 % of the value or that sit on a bound, and separated is True only when the fit converged and that list is empty. This is a rule of thumb for the error of the noise, not a guarantee: the 1 % was chosen after measuring (at 25 % the flag called 15-20 % of the wrong wall estimates, and 73-76 % of the trials with n_glass off by more than 0.02, separated; at 1 % none of 535 wrong trials in two disjoint seed sets), the covariance assumes the model is exact, and a model error such as an off-centre inner wall changes the estimates without changing the residual, the sigma or this flag. n_liquid is None when no row of the map is left in the filled section. Quantities that barely move the pattern (a thin wall against the glass index when the edge pixels are lost, the pattern distance against the liquid index) come back there, with a large sigma and cond; they are not separated, and the table says so rather than giving a number without it. The model assumes concentric circles with a uniform wall, a horizontal 2-D section, an ideal pinhole, a flat background, exactly known distances and pitch, no dispersion and a flat liquid surface; the maps of bottle_background_map obey the same assumptions, so a test on them proves consistency, not that a real bottle is recovered. A map with fewer than 12 usable columns, a wrong shape, an unknown known name or a camera not beyond one diameter are refused.
optics 的每个算子都先校验输入再计算(不让任何东西无声通过):
• 单位写进参数名 —— _mm / _um / _deg / _mrad。把 mm 和 µm 弄混不会崩溃,而是给出「看着合理却是错的答案」,所以用命名来防。这里绝不从数值大小去猜单位。
• 字符串一律 ValueError —— float('50') 会成功,于是未解析的配置值会被当成长度混进来(实测:thin_lens('50', '200') 曾返回看着合理的 66.667 mm)。bool 也按 True == 1 的隐式提升拒绝。
• complex / masked array 一律 ValueError(仅接受实数槽位;拒绝无声丢弃虚部或剥掉掩码)。所有输入中的 NaN/Inf 一律 ValueError。但已声明的缺测除外:bottle_fit_from_pattern 的 u_map 以 NaN 接收未能测得的像素(∞ 仍被拒绝)。
• 逐项点名拒绝除零及其近亲:焦距 0、曲率半径 0、折射率 <= 0、全不透明光阑(全为 0,归一化变成 0/0)、总和 <= 0 的 PSF、S0 = 0 的 Stokes 矢量、物体位于前焦点(像在无穷远)。
• 只有两个算子会返回非有限值,而且都写进了契约:depth_of_field 在超焦距以外返回 far_mm = inf(这正是超焦距的定义),gaussian_beam 在束腰处返回 wavefront_radius_mm = inf(平面波前的曲率半径)。两者都同时返回一个有限的搭档(far_is_infinite / curvature_per_mm)。除此之外的无声 NaN/Inf 都在内部检出并 ValueError ——「float64 溢出了」和「答案是无穷大」是两种不同的主张,不能拿后者的脸去交付前者。但已声明的缺测除外:bottle_background_map 对光线不可用的像素(全反射等)在 u_mm 中返回 NaN,并同时返回 valid 掩码和数量。
• 尺寸上限:生成网格受 optics.MAX_GRID(4096)限制,传入的场/PSF/光阑受 optics.MAX_FIELD_ELEMENTS(2^24),ABCD 元件序列受 optics.MAX_SYSTEM_ELEMENTS(1024),Zernike 受 MAX_ZERNIKE_TERMS(512)/ MAX_ZERNIKE_ORDER(40)/ MAX_ZERNIKE_BASIS(2^25)。以 fail-closed 堵住「小参数引发巨大内部分配」的路径(实测:n_max=40 × 4096² 需要 108 GB)。
• 物理上不可能的状态同样拒绝:偏振度 > 1 的 Stokes 矢量、负透过率、负强度、n-|m| 为奇数等非法 Zernike 指标。
• 示例数据目录(下载 URL / 许可证) —— 2-D 用 skimage.data(BSD/公有领域)加合成图,3-D 给出真实数据源(Stanford/PDS 等)的下载 URL。
• 算子来历与参考文献 —— 该算子族所依据的研究/方法出处。
• 算法的正典(作者、年份)与用途见上面的族使用指南。
• poc_bottle_pattern_inverse — py -3.11 examples/poc_bottle_pattern_inverse.py
table 作为输入)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 · bottle_background_map · wet_surface_appearance · wet_dry_inspection_pair · underwater_inspection_image · caustic_floor_segmentation
*Provenance: watervision.py — OPTICS 算子登记表。本条目由 tools/opdocs.py md 自动生成(请勿手工编辑)。*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.