hdr_dynamic_range — OPTICS hdr op

• Data kinds: कोई नहीं → table (केवल arguments से तय होने वाला op — यह कोई image या data input नहीं लेता)

• Call: import fullseye as fs; fs.ledger.hdr_dynamic_range(exposures, eta=0.6, K=0.1, sigma_d_e=8.0, dark_offset_dn=4.0, bits=8, full_well_e=None, n_frames=400, n_levels=97, decades=None, seed=0) (implementation को सीधे call करना हो तो import hdrfusion; hdrfusion.hdr_dynamic_range(exposures, eta=0.6, K=0.1, sigma_d_e=8.0, dark_offset_dn=4.0, bits=8, full_well_e=None, n_frames=400, n_levels=97, decades=None, seed=0), registry से लेना हो तो opsoptics.get("hdr_dynamic_range"))

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

उपयोग

HDR capture की मापी गई dynamic range (EMVA 1288 परिभाषा) और उसका closed form (table)।

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

シミュで実測: 放射輝度の等比の階段(n_levels 段、各段 n_frames 画素 = 繰り返し)を hdr_exposure_series_simulate(線形、γ = 1)で露出の列に撮り、hdr_merge(weight="linear"、真の線形の逆応答)で合成し、段ごとに SNR = 平均 / 標準偏差。

• L_min: SNR が 1 を切る放射輝度(EMVA 1288 の絶対感度しきい値の HDR 版)。

• L_sat: 最短の露出の出力の分散が最大になる放射輝度(EMVA の飽和の定義)を、粗い階段で見つけた最大の段のまわりを細かい階段で測り直して決める。

• dr = L_sat / L_min、dr_db = 20 log10、dr_bits = log2。

閉形式(並べて返す): 低い側は全露出の和の SNR = 1 —— sensorchar.emva_sensitivity_threshold に σ_d → √P σ_d、K → K/√P を入れた μ_p.min を Σ t で割る。高い側は最短の露出が 2^bits − 1(または満杯)に届く放射輝度。露出 1 枚ならそのまま sensorchar.emva_dynamic_range。

Measured in simulation (EMVA 1288 definitions: SNR = 1 and the maximum of the variance), with the closed form side by side. The closed-form saturation is the maximum of the variance of a clipped Gaussian min(N(μ, σ²(μ)), c) with σ² = K²(σ_d² + μ_e) + 1/12 (exact censored- normal moments); L_clip_closed_form is the plain clip point of the mean, about 5 % higher (measured). ★Full-well clipping is approximated as a DN clip at offset + K·full_well.

पूरी 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। घोषित अपवाद: 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।

उपयोग की विस्तृत 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_hdr_glossy_metal_inspection — py -3.11 examples/poc_hdr_glossy_metal_inspection.py

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

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

इसी category के (hdr)

camera_response_debevec · camera_response_robertson · camera_response_linear · hdr_merge · exposure_fusion_mertens · hdr_exposure_series_simulate · hdr_radiance_error


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

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