render_optscene — OPTICS scene op

• Data kinds: table × table × table → rgbimage

• Call: import fullseye as fs; fs.ledger.render_optscene(scene, camera, lights, ambient: 'float' = 0.0, depth: 'int' = 2, shadows: 'bool' = True, supersample: 'int' = 1, adaptive: 'bool' = False, light_samples: 'int' = None, edge_threshold: 'float' = 0.06, saturate_at: 'float' = None, wavelength_nm: 'float' = 550.0, environment=None, environment_gain: 'float' = 1.0, environment_samples: 'int' = 12) -> 'np.ndarray' (implementation को सीधे call करना हो तो import optscene; optscene.render_optscene(scene, camera, lights, ambient: 'float' = 0.0, depth: 'int' = 2, shadows: 'bool' = True, supersample: 'int' = 1, adaptive: 'bool' = False, light_samples: 'int' = None, edge_threshold: 'float' = 0.06, saturate_at: 'float' = None, wavelength_nm: 'float' = 550.0, environment=None, environment_gain: 'float' = 1.0, environment_samples: 'int' = 12) -> 'np.ndarray', registry से लेना हो तो opsoptics.get("render_optscene"))

उपयोग

inspection के लिए shoot करता है: असली lighting fixtures को physical units में रखकर direct light गिनता है (ground truth सहित)।

दिखावट के लिए multiple reflections या ambient light शामिल नहीं हैं। सुंदर picture चाहिए तो render_studio का उपयोग करें ―― अलग तरीके से बना एक अलग op; दोनों को मिलाने से photometry का आधार गड़बड़ा जाता है। tone mapping से पहले की linear RGB radiance (H, W, 3) लौटाता है।

lights illumdesign.light_source का परिणाम है (1 या कई साथ-साथ)। ambient एकसमान ambient light है, depth dielectrics के पार recursion की गहराई, shadows=False cast shadows बंद करता है (तेज़, पर shadows मानने वाले inspections के लिए अनुपयोगी)। supersample प्रति 1 pixel samples को n×n तक बढ़ाता है ―― असली pixels अपने area पर integrate करते हैं, इसलिए यह edges और machining marks पर सीढ़ीनुमा jaggies हटाता है (लागत n² गुना)।

बड़े पैमाने पर generation के लिए 3 knobs (गति generator का एक feature है):

• adaptive=True ―― पहले 1 sample से छोड़ें, फिर केवल geometric edges या बड़े luminance gradients वाले pixels को n×n में बाँटें। सपाट surfaces पर कोई sample बर्बाद नहीं होता, इसलिए edge quality बनाए रखते हुए यह तेज़ हो जाता है।

• light_samples ―― area lights के emitter points को इस संख्या तक घटाता है (brightness weights से सुधारी जाती है)। जो खोता है वह shadow edges की कोमलता है, absolute brightness नहीं।

• saturate_at ―― इस luminance से ऊपर के pixels refine नहीं होते (वे वैसे भी सफ़ेद पर clip होते हैं)।

wavelength_nm light source की wavelength है। यह उस अंश में आती है जो roughness σ वाली surface specular के रूप में लौटाती है, exp(-(4πσcosθ/λ)²), इसलिए वही surface wavelength के अनुसार अलग दिखती है। broadband (halogen) के लिए कई wavelengths पर shoot करके जोड़ें; laser के लिए एक wavelength पर shoot करें।

environment देने से display pictures बनाने का तरीका इसमें मिलाया जा सकता है: metals के anisotropic lobe से खींचा गया environment environment_gain से गुणा करके जोड़ा जाता है। brushed metal metal जैसा इसलिए दिखता है क्योंकि environment brush marks के साथ खिंचकर परावर्तित होता है; केवल point lights से यह केवल कठोर धारियाँ बनती हैं (2026-09-05 की user अंतर्दृष्टि)। default बंद है ―― ताकि photometric आधार चाहने वाली inspection images में दिखावट के terms चुपचाप न मिलें। optscene.env_studio देना आसान तरीका है; अपना function ((...,3) direction -> (...,) brightness) भी काम करता है।

display के लिए round करने हेतु, **(1/2.2) खुद लगाएँ। असली lens का distortion, PSF, vignetting और sensor noise जोड़ने के लिए, बाद में lensimage.render_through_lens लगाएँ; केवल quantization और read noise के लिए, बाद में sensor_capture लगाएँ।

पूरी 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।

• शून्य से भाग और उससे जुड़े मामलों को नाम लेकर अस्वीकार किया जाता है: 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।

उपयोग की विस्तृत guide

• optics_imaging family guide

पृष्ठभूमि guides (इस op के पीछे की physics और conventions)

• dataset_conventions — Training dataset के conventions — COCO / YOLO / VOC और visual inspection में सावधानियाँ

• mv_cameras — Industrial camera निर्माता (sensor mapping, line scan / TDI)

• mv_illumination_practice — Lighting व्यवहार में — wavelength, polarisation, drive modes, ambient light, safety

• mv_image_sensors — Industrial image sensors (मुख्यतः मौजूदा products)

• virtual_machine_vision — Virtual machine vision — parameters की सूची और एक object model

संदर्भ (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 करते हैं)

• virtual_machine_vision — py -3.11 examples/virtual_machine_vision.py

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

clearcoat_shade · wetness · defocus_blur · diffraction_blur · sensor_capture

इसी category के (scene)

scene_material · scene_plane · scene_sphere · scene_box · scene_cylinder · surface_defect · surface_finish · random_defects


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

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