scene op• Datenarten: table × table × table → rgbimage
• Aufruf: 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' (die Implementierung direkt: 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'; aus dem Register: opsoptics.get("render_optscene"))
Aufnahme für die Prüfung: reale Leuchten in physikalischen Einheiten platzieren und das direkte Licht zählen (mit Ground Truth).
Mehrfachreflexionen und Umgebungslicht für das Aussehen sind nicht enthalten. Wer ein schönes Bild braucht, nimmt render_studio ―― ein separater, anders gebauter Op; verwechselt man sie, verwischt die Grundlage der Photometrie. Rückgabe ist lineare RGB-Strahldichte (H, W, 3), vor dem Tone Mapping.
lights ist das Ergebnis von illumdesign.light_source (1 oder mehrere nebeneinander). ambient ist gleichmäßiges Umgebungslicht, depth die Rekursionstiefe durch Dielektrika, shadows=False schaltet Schlagschatten ab (schneller, aber unbrauchbar für Prüfungen, die Schatten voraussetzen). supersample erhöht die Abtastwerte pro 1 Pixel auf n×n ―― reale Pixel integrieren über ihre Fläche, daher verschwinden damit die Treppenstufen an Kanten und Bearbeitungsspuren (Kosten n²-fach).
3 Stellschrauben für die Massengenerierung (Geschwindigkeit ist eine Funktion des Generators):
• adaptive=True ―― zuerst mit 1 Abtastwert aufnehmen, dann nur Pixel mit geometrischen Kanten oder großem Leuchtdichtegradienten in n×n aufteilen. Auf flachen Flächen werden keine Abtastwerte verschwendet, daher schneller bei gleicher Kantenqualität.
• light_samples ―― dünnt die Emitterpunkte flächiger Lichtquellen auf diese Zahl aus (Helligkeit über Gewichte korrigiert). Verloren geht die Weichheit der Schattenkanten, nicht die absolute Helligkeit.
• saturate_at ―― Pixel über dieser Leuchtdichte werden nicht verfeinert (sie laufen ohnehin ins Weiß).
wavelength_nm ist die Wellenlänge der Lichtquelle. Sie geht in den Anteil ein, den eine Fläche der Rauheit σ spiegelnd zurückgibt, exp(-(4πσcosθ/λ)²), daher sieht dieselbe Fläche je nach Wellenlänge anders aus. Bei Breitband (Halogen) mit mehreren Wellenlängen aufnehmen und addieren, beim Laser mit einer einzigen Wellenlänge.
Mit environment lässt sich die Machart von Vorzeigebildern hier einmischen: die über die anisotrope Keule von Metallen abgetastete Umgebung wird mit environment_gain multipliziert und addiert. Gebürstetes Metall wirkt metallisch, weil sich die Umgebung entlang der Bürstspuren gestreckt spiegelt; mit Punktlichtern allein entstehen nur harte Streifen (Einsicht eines Nutzers vom 2026-09-05). Default ist off ―― damit nicht stillschweigend Terme fürs Aussehen in Prüfbilder gemischt werden, die eine photometrische Grundlage brauchen. Am einfachsten optscene.env_studio übergeben; eine eigene Funktion ((...,3) Richtung -> (...,) Helligkeit) geht auch.
Zum Runden für die Anzeige selbst **(1/2.2) anwenden. Um Verzeichnung, PSF, Randlichtabfall und Sensorrauschen eines realen Objektivs hinzuzufügen, lensimage.render_through_lens nachschalten; nur für Quantisierung und Ausleserauschen sensor_capture nachschalten.
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
• dataset_conventions — Konventionen für Trainingsdatensätze — COCO / YOLO / VOC und Fallstricke in der Sichtprüfung
• mv_cameras — Hersteller von Industriekameras (Sensorzuordnung, Zeilenkamera / TDI)
• mv_illumination_practice — Beleuchtung in der Praxis — Wellenlänge, Polarisation, Ansteuerung, Fremdlicht, Sicherheit
• mv_image_sensors — Industrielle Bildsensoren (vorwiegend aktuelle Produkte)
• virtual_machine_vision — Virtuelle Bildverarbeitung — Parameter erfassen und Objektmodell
• 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.
• virtual_machine_vision — py -3.11 examples/virtual_machine_vision.py
rgbimage als Eingabe)clearcoat_shade · wetness · defocus_blur · diffraction_blur · sensor_capture
scene)scene_material · scene_plane · scene_sphere · scene_box · scene_cylinder · surface_defect · surface_finish · random_defects
*Provenance: optscene.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.