plenoptic op• Data kinds: lightfield × table → table
• Call: import fullseye as fs; fs.ledger.plenoptic_refocus_depth(lf, system, slope) (implementation को सीधे call करना हो तो import plenoptic; plenoptic.plenoptic_refocus_depth(lf, system, slope), registry से लेना हो तो opsoptics.get("plenoptic_refocus_depth"))
• GPU: नहीं (केवल CPU reference implementation)
light-field refocus slope को मीटर में object distance में बदलें।
> नीचे का विस्तृत विवरण मूल text में है — सारांश और headings का अनुवाद हो चुका है।
*slope* is in the unit of lightfield.lf_refocus and lightfield.lf_depth_from_focus on a field from plenoptic_decode: decoded spatial samples (lenslets) of parallax per view step. Zero slope is the main-lens conjugate of the MLA plane and maps to the configured object distance.
Paraxial model of the unfocused (1.0) camera, in the geometry plenoptic_capture traces. plenoptic_decode samples U views across one lenslet pitch, so one view step moves the exit-pupil coordinate by dX = (pitch/U) * xp_radius / (microimage_diameter/2). A point imaged delta behind the MLA plane, with the exit pupil D in front of it, shifts on the MLA by dX * delta/(D+delta) per view, hence slope = (dX/pitch) * delta/(D+delta); Newton's equation of the paraxial main lens turns the image position into the object distance.
Before 2026-11-04 the image shift was slope * angular_step * pitch with angular_step = pixel_pitch/mla_to_sensor -- a factor 1/angular_step**2 (~3000x for the PoC camera) too small, so every measured slope mapped back to the focus distance. The relation is now gated against rays traced forward through the prescription (tests/test_plenoptic.py): rel. error below 1e-6 for an ideal lens and 2e-4 for the PoC's three-element lens.
Sign: follows plenoptic_capture's non-inverting pixel-to-pupil map, which is the opposite of a physical lenslet; negate real-sensor slopes.
Limits: it is paraxial. Spherical aberration of a real aperture moves the best-focus slope of the full pupil away from the paraxial one -- for the PoC lens at F/3.7 the decoded 1.0 m plane sits at slope -0.029, not 0 (measured in examples/poc_plenoptic_camera.py). depth_resolution_m is half the depth span of a slope change of +-1/(U-1): one decoded sample of parallax across the full angular baseline.
Raises ValueError: *lf* not (V,U,H,W), V != U (one slope cannot describe two different per-view pupil steps), fewer than two views, a focused (2.0) system (its MLA is not at the main-lens image plane, so slope means something else), a non-finite slope, or a slope whose image point lies at or beyond the exit pupil (slope*pitch/dX >= 1).
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। घोषित अपवाद: bottle_fit_from_pattern का u_map न मापे जा सके पिक्सेल को NaN के रूप में लेता है (अनंत अब भी अस्वीकार)।
• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: 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 हुआ" और "उत्तर अनंत है" अलग-अलग दावे हैं, इसलिए पहले को दूसरे का चेहरा पहनाकर नहीं लौटाया जाता। घोषित अपवाद: bottle_background_map जिन पिक्सेल की किरण अनुपयोगी है (पूर्ण आंतरिक परावर्तन आदि) उनके लिए u_mm में NaN लौटाता है, साथ में valid मास्क और गिनती भी।
• 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_plenoptic_camera — py -3.11 examples/poc_plenoptic_camera.py
table को input के रूप में लेते हैं)abcd_matrix · wavefront_stats · sfr_from_edge · paraxial_trace · seidel_coefficients · spot_stats · tolerance_analysis · wavefront_from_opd
plenoptic)mla_surface · plenoptic_system · plenoptic_capture · plenoptic_mla_calibrate · plenoptic_decode
*Provenance: plenoptic.py — OPTICS operator registry. यह per-op note tools/opdocs.py md से अपने-आप generate होता है (हाथ से edit न करें)।*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.