@photivra/engine 0.2.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -0
- package/CITATION.cff +1 -1
- package/README.md +59 -10
- package/dist/camera/equivalent-focal-length.d.ts +34 -0
- package/dist/camera/equivalent-focal-length.d.ts.map +1 -0
- package/dist/camera/equivalent-focal-length.js +33 -0
- package/dist/camera/equivalent-focal-length.js.map +1 -0
- package/dist/camera/field-of-view.d.ts +40 -3
- package/dist/camera/field-of-view.d.ts.map +1 -1
- package/dist/camera/field-of-view.js +66 -24
- package/dist/camera/field-of-view.js.map +1 -1
- package/dist/core/calculation-result.d.ts.map +1 -1
- package/dist/core/calculation-result.js +14 -2
- package/dist/core/calculation-result.js.map +1 -1
- package/dist/core/configuration-error.d.ts +9 -0
- package/dist/core/configuration-error.d.ts.map +1 -0
- package/dist/core/configuration-error.js +13 -0
- package/dist/core/configuration-error.js.map +1 -0
- package/dist/core/evidence-provenance.d.ts +40 -0
- package/dist/core/evidence-provenance.d.ts.map +1 -0
- package/dist/core/evidence-provenance.js +79 -0
- package/dist/core/evidence-provenance.js.map +1 -0
- package/dist/core/image-formation.d.ts +70 -0
- package/dist/core/image-formation.d.ts.map +1 -0
- package/dist/core/image-formation.js +335 -0
- package/dist/core/image-formation.js.map +1 -0
- package/dist/index.d.ts +15 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.d.ts +91 -0
- package/dist/motion/camera-rotation.d.ts.map +1 -0
- package/dist/motion/camera-rotation.js +157 -0
- package/dist/motion/camera-rotation.js.map +1 -0
- package/dist/optics/focus-breathing.d.ts +73 -0
- package/dist/optics/focus-breathing.d.ts.map +1 -0
- package/dist/optics/focus-breathing.js +77 -0
- package/dist/optics/focus-breathing.js.map +1 -0
- package/dist/optics/illumination-vignetting.d.ts +59 -0
- package/dist/optics/illumination-vignetting.d.ts.map +1 -0
- package/dist/optics/illumination-vignetting.js +107 -0
- package/dist/optics/illumination-vignetting.js.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts +117 -0
- package/dist/optics/lateral-chromatic-aberration.d.ts.map +1 -0
- package/dist/optics/lateral-chromatic-aberration.js +228 -0
- package/dist/optics/lateral-chromatic-aberration.js.map +1 -0
- package/dist/optics/psf-foundation.d.ts +102 -0
- package/dist/optics/psf-foundation.d.ts.map +1 -0
- package/dist/optics/psf-foundation.js +164 -0
- package/dist/optics/psf-foundation.js.map +1 -0
- package/dist/optics/radial-distortion.d.ts +131 -0
- package/dist/optics/radial-distortion.d.ts.map +1 -0
- package/dist/optics/radial-distortion.js +227 -0
- package/dist/optics/radial-distortion.js.map +1 -0
- package/dist/output/capture-geometry.d.ts +278 -0
- package/dist/output/capture-geometry.d.ts.map +1 -0
- package/dist/output/capture-geometry.js +562 -0
- package/dist/output/capture-geometry.js.map +1 -0
- package/dist/schema/validation.d.ts +1 -8
- package/dist/schema/validation.d.ts.map +1 -1
- package/dist/schema/validation.js +2 -11
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/architecture.d.ts +40 -0
- package/dist/sensor/architecture.d.ts.map +1 -0
- package/dist/sensor/architecture.js +98 -0
- package/dist/sensor/architecture.js.map +1 -0
- package/dist/sensor/radiometry-readiness.d.ts +111 -0
- package/dist/sensor/radiometry-readiness.d.ts.map +1 -0
- package/dist/sensor/radiometry-readiness.js +294 -0
- package/dist/sensor/radiometry-readiness.js.map +1 -0
- package/dist/sensor/sensor-geometry.d.ts +99 -0
- package/dist/sensor/sensor-geometry.d.ts.map +1 -0
- package/dist/sensor/sensor-geometry.js +71 -0
- package/dist/sensor/sensor-geometry.js.map +1 -0
- package/dist/simulation/poc-simulation.d.ts +93 -1
- package/dist/simulation/poc-simulation.d.ts.map +1 -1
- package/dist/simulation/poc-simulation.js +308 -24
- package/dist/simulation/poc-simulation.js.map +1 -1
- package/docs/API_STYLE.md +36 -2
- package/docs/ARCHITECTURE.md +179 -1
- package/docs/IMAGE_FORMATION.md +151 -0
- package/docs/MOTION_AND_SIGNAL.md +52 -1
- package/docs/PHYSICS_FOUNDATION.md +190 -3
- package/docs/POC_API.md +73 -7
- package/docs/PROVENANCE.md +24 -0
- package/docs/PSF_FOUNDATION.md +133 -0
- package/docs/STABILIZATION.md +17 -4
- package/docs/USAGE.md +714 -3
- package/package.json +3 -2
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -7,6 +7,7 @@ Photivra separates a reusable scientific core from optional composition and tran
|
|
|
7
7
|
The browser-safe root package currently owns:
|
|
8
8
|
|
|
9
9
|
- unit-explicit camera, sensor, lens, exposure, focus, scene, and motion contracts;
|
|
10
|
+
- additive sensor-foundation contracts that separate physical imaging area from native effective image raster;
|
|
10
11
|
- deterministic camera/optics/exposure/crop calculations;
|
|
11
12
|
- the explicitly approximate stabilization-equivalent camera-shake model;
|
|
12
13
|
- sensor signal/noise primitives;
|
|
@@ -18,6 +19,179 @@ The root package has no runtime npm dependencies. CI walks the root import graph
|
|
|
18
19
|
|
|
19
20
|
Comparison, optimization, real-camera calibration databases, renderer effects, and full optical simulation are **not** current root-package capabilities.
|
|
20
21
|
|
|
22
|
+
The sensor foundation intentionally keeps physical image-formation geometry separate from digital sampling. `SensorImagingArea` represents the photosensitive imaging dimensions used for image formation; `NativeImageRaster` represents effective image samples and does not imply one image sample equals one physical photodiode. Derived sampling pitch is geometric spacing only, not fill factor or photon-collection area.
|
|
23
|
+
|
|
24
|
+
Capture geometry builds on that foundation without mutating native sensor identity:
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
physical imaging area + native raster
|
|
28
|
+
↓
|
|
29
|
+
native active-capture rectangle
|
|
30
|
+
↓
|
|
31
|
+
physical camera orientation
|
|
32
|
+
↓
|
|
33
|
+
oriented active capture
|
|
34
|
+
↓
|
|
35
|
+
digital/output crop
|
|
36
|
+
↓
|
|
37
|
+
output raster
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Native coordinates use a top-left origin with +X right and +Y down and remain invariant under physical camera rotation. Exact point, vector, and half-open rectangle transforms map between native and oriented capture coordinates for 0°/90°/180°/270° rotations. This keeps later CFA phase, rolling-readout direction, motion-vector transforms, and camera-shake transforms anchored to one stable sensor coordinate system. Display/file transforms remain separate from physical capture orientation.
|
|
41
|
+
|
|
42
|
+
Active capture retains its physical bounds and center offset relative to the optical axis. Off-center crops therefore use asymmetric angular bounds instead of being silently recentered. Output raster resampling must preserve the output-crop aspect ratio; implicit geometric stretching is rejected.
|
|
43
|
+
|
|
44
|
+
Equivalent focal length is also layered on top of physical capture geometry rather than stored as lens identity. The engine keeps physical `focalLengthMm` authoritative and derives diagonal-based 35 mm equivalence from the active physical capture area. Focus distance and final digital/output crop do not redefine this conventional capture-equivalent quantity.
|
|
45
|
+
|
|
46
|
+
Sensor architecture is a separate descriptive layer. Illumination (FSI/BSI), integration/stacking, readout capabilities, and color-sampling family are independent evidence-backed facts. Their presence alone has no image-quality effect in the engine. Evidence origin is modeled independently from reuse rights, scalar facts may cite multiple evidence records, and multi-valued capabilities carry evidence per value. Omitted facts remain unknown rather than being inferred. Capture-mode semantics, readout timing, reconstruction, and calibrated radiometry consume these facts only through later explicit models.
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Image-formation ownership and ordering
|
|
50
|
+
|
|
51
|
+
The root package exports `getImageFormationContract()` as the canonical semantic map for current and future image-formation work.
|
|
52
|
+
|
|
53
|
+
It defines five scientific domains:
|
|
54
|
+
|
|
55
|
+
1. scene/ray geometry;
|
|
56
|
+
2. lens mapping plus pupil/throughput;
|
|
57
|
+
3. field- and wavelength-dependent PSF;
|
|
58
|
+
4. time-dependent exposure/readout;
|
|
59
|
+
5. sensor sampling through orientation/output/display.
|
|
60
|
+
|
|
61
|
+
The graph is a **dependency/ownership graph**, not a literal renderer filter list. Hard upstream dependencies are acyclic; explicit couplings record interactions that must not be split into scientifically independent post-effects.
|
|
62
|
+
|
|
63
|
+
Important consequences:
|
|
64
|
+
|
|
65
|
+
- focus breathing is projection/lens mapping;
|
|
66
|
+
- lateral CA is wavelength/channel-dependent field mapping;
|
|
67
|
+
- illumination vignetting is throughput-only;
|
|
68
|
+
- mechanical/pupil vignetting can affect both throughput and PSF/bokeh;
|
|
69
|
+
- diffraction belongs to the pupil/PSF domain;
|
|
70
|
+
- camera rotation should be time-parameterized so global and rolling readout consume one motion model;
|
|
71
|
+
- exposure duration and readout timing remain independent;
|
|
72
|
+
- future sensor ordering is reserved from optical stack/CFA sampling through charge/noise/ADC/reconstruction before oriented/output transforms.
|
|
73
|
+
|
|
74
|
+
Renderer implementations may optimize or approximate only when they preserve the engine-owned semantics. Geometric warps use inverse destination-to-source sampling, premultiplied alpha, and stable depth/occlusion order.
|
|
75
|
+
|
|
76
|
+
See `docs/IMAGE_FORMATION.md`.
|
|
77
|
+
|
|
78
|
+
## Radiometry readiness boundary
|
|
79
|
+
|
|
80
|
+
Radiometry prerequisites are represented separately from the composed POC and from low-level signal/noise primitives. `parseRadiometryReadinessProfile()` validates declared scene spectral radiance, optical transmission, pupil/vignetting behavior, photosite collection-area semantics, exposure integration, and sensor response together with evidence and uncertainty declarations.
|
|
81
|
+
|
|
82
|
+
`assessRadiometryReadiness()` distinguishes:
|
|
83
|
+
|
|
84
|
+
- `not-ready`: one or more required components are absent;
|
|
85
|
+
- `approximate-only`: all required components exist, but one or more are approximate or lack quantified uncertainty;
|
|
86
|
+
- `calibrated-ready`: every required component is declared calibrated and carries quantified uncertainty.
|
|
87
|
+
|
|
88
|
+
These states describe the declared prerequisite package only. They do **not** prove that cited evidence is scientifically correct, do not derive photon counts, and never enable photon/noise output in `simulatePocCamera()` automatically.
|
|
89
|
+
|
|
90
|
+
Geometric sample pitch is explicitly insufficient as a photosite photon-collection area. A radiometric profile must supply either an effective collection area or a geometric cell area plus explicit fill factor. Calibration artifacts are identified by stable IDs and SHA-256 checksums rather than being embedded implicitly in geometry metadata.
|
|
91
|
+
|
|
92
|
+
## Composition boundary at POC API 0.20
|
|
93
|
+
|
|
94
|
+
The sensor/capture/architecture/radiometry modules are public root-engine foundations. POC simulation API 0.20 composes the geometry foundation through final output/viewing semantics while keeping older callers valid.
|
|
95
|
+
|
|
96
|
+
The POC now composes:
|
|
97
|
+
|
|
98
|
+
- physical sensor width/height plus native effective raster dimensions;
|
|
99
|
+
- shared sensor-geometry metrics, including physical crop factor, raster-derived megapixels, and X/Y geometric sampling pitch;
|
|
100
|
+
- the legacy same-aspect centered `crop.factor` path for compatibility;
|
|
101
|
+
- an opt-in staged `capture` path for physical orientation, native active-capture rectangle, oriented digital/output crop, and final output raster;
|
|
102
|
+
- active-capture and final-output FOV, including asymmetric bounds for off-center physical or digital crop;
|
|
103
|
+
- diagonal-based 35 mm-equivalent focal length derived from active physical capture while physical focal length remains authoritative;
|
|
104
|
+
- capture-mode equivalent-viewing CoC based on the final retained physical viewing area rather than output pixel count;
|
|
105
|
+
- orientation-aware post-output subject framing with explicit retained physical bounds/FOV;
|
|
106
|
+
- additive image-plane→native-raster conversion plus oriented-capture and final-output motion/camera-shake vector diagnostics;
|
|
107
|
+
- explicit oriented-capture→output pixel scale for renderer sampling/blur conversion;
|
|
108
|
+
- one representative horizontal-pitch path for existing blur/sampling calculations, with a fail-closed guard for materially non-square sampling;
|
|
109
|
+
- the established projection, DOF/defocus, diffraction, motion, exposure, aperture-shape, and camera-shake models.
|
|
110
|
+
|
|
111
|
+
Compatibility boundaries remain explicit:
|
|
112
|
+
|
|
113
|
+
- staged capture geometry cannot be combined with legacy `crop.factor` other than `1`;
|
|
114
|
+
- legacy `subjectCrop` response remains for legacy mode, while staged capture reports post-output framing under `capture.subjectFraming`;
|
|
115
|
+
- explicit physical CoC remains caller-owned; equivalent-viewing CoC is a separately labeled approximation based on final retained physical viewing area;
|
|
116
|
+
- existing legacy motion/camera-shake fields retain their image-plane (+X right, +Y up) meaning rather than being reinterpreted; capture diagnostics explicitly convert to native raster (+Y down) before orientation.
|
|
117
|
+
|
|
118
|
+
The POC still does **not** consume:
|
|
119
|
+
|
|
120
|
+
- `SensorArchitectureProfile`;
|
|
121
|
+
- `RadiometryReadinessProfile` or calibrated photon/noise output.
|
|
122
|
+
|
|
123
|
+
That separation is deliberate. Further foundation APIs should remain independently testable and only enter the POC through explicit contract/version changes and migration review.
|
|
124
|
+
|
|
125
|
+
## PSF/pupil foundation
|
|
126
|
+
|
|
127
|
+
The field/wavelength PSF domain now has an explicit public foundation through `getPsfFoundationContract()` and `calculatePsfFoundationComponents()`.
|
|
128
|
+
|
|
129
|
+
The foundation provides:
|
|
130
|
+
- stable contribution IDs and implementation/reservation status;
|
|
131
|
+
- field/depth/spectral/pupil context;
|
|
132
|
+
- existing geometric-defocus and circular-Airy diagnostics with their original provenance;
|
|
133
|
+
- an explicit `not-composed` policy.
|
|
134
|
+
|
|
135
|
+
It does not invent a combined PSF, MTF, or lens-sharpness score.
|
|
136
|
+
|
|
137
|
+
Future non-circular diffraction, mechanical pupil clipping, field curvature, field-dependent aberration, and bokeh models should extend this contribution/context model rather than replacing existing defocus/diffraction APIs.
|
|
138
|
+
|
|
139
|
+
Preview and reference render paths may use different computational fidelity, but must preserve contribution identities and engine-owned semantics.
|
|
140
|
+
|
|
141
|
+
## Standalone illumination-throughput foundation
|
|
142
|
+
|
|
143
|
+
The lens-field/pupil domain now includes generic illumination vignetting as field-dependent linear throughput.
|
|
144
|
+
|
|
145
|
+
The engine owns:
|
|
146
|
+
- physical field-radius normalization;
|
|
147
|
+
- the declared operating envelope;
|
|
148
|
+
- full-envelope extrema validation;
|
|
149
|
+
- the linear throughput factor and stop-loss diagnostic.
|
|
150
|
+
|
|
151
|
+
Renderer backends consume that factor in a linear working domain. They must not reinterpret this stage as gamma-space darkening, coordinate warp, or pupil clipping.
|
|
152
|
+
|
|
153
|
+
Mechanical/pupil vignetting remains part of future pupil/PSF work because it can change both throughput and bokeh/PSF shape.
|
|
154
|
+
|
|
155
|
+
## Standalone lateral-CA field-mapping foundation
|
|
156
|
+
|
|
157
|
+
The lens-field domain also exposes generic red/green/blue channel-dependent radial mapping.
|
|
158
|
+
|
|
159
|
+
The green channel is the reference/common geometric field map. A shared base distortion is combined with explicit red/blue coefficient offsets, so ordinary distortion and chromatic separation remain semantically distinct without requiring two renderer warps.
|
|
160
|
+
|
|
161
|
+
The engine owns both forward per-channel coordinates and inverse per-channel destination-to-source sampling. Backends should not implement lateral CA as arbitrary finished-image channel offsets or apply the same base distortion twice.
|
|
162
|
+
|
|
163
|
+
This is deliberately not a spectral/CFA/colorimetric model. Wavelength-dependent optics, longitudinal CA, wavelength-dependent PSFs, and calibrated lens profiles remain separate future work.
|
|
164
|
+
|
|
165
|
+
## Standalone radial field-mapping foundation
|
|
166
|
+
|
|
167
|
+
The lens-field/pupil domain now also exposes generic radial distortion through paired forward and inverse mappings.
|
|
168
|
+
|
|
169
|
+
The engine, rather than a renderer backend, owns:
|
|
170
|
+
- coefficient normalization against a declared physical image-plane radius;
|
|
171
|
+
- the valid maximum normalized field radius;
|
|
172
|
+
- strict monotonicity/invertibility checks;
|
|
173
|
+
- deterministic inverse destination-to-source mapping.
|
|
174
|
+
|
|
175
|
+
This prevents WebGPU/WebGL2 implementations from inventing separate distortion equations.
|
|
176
|
+
|
|
177
|
+
The radial-distortion slice is optical-axis-centered only. Tangential/decentered distortion and calibrated lens profiles remain future work. Lateral chromatic aberration and illumination vignetting are implemented as separate standalone foundations and are not part of the radial-distortion model.
|
|
178
|
+
|
|
179
|
+
## Standalone focus-breathing foundation
|
|
180
|
+
|
|
181
|
+
The lens-field/pupil domain now has a partial standalone foundation through `calculateFocusBreathingProjection()` and `calculateFocusBreathingFieldOfView()`.
|
|
182
|
+
|
|
183
|
+
These functions apply an explicit caller-declared scale to the ideal thin-lens projection for one focus state. They do not infer a breathing curve, identify a real lens, or mutate physical focal length.
|
|
184
|
+
|
|
185
|
+
The model remains standalone and is not composed into `simulatePocCamera()` yet. Generic radial distortion, lateral chromatic aberration, and illumination vignetting are separately implemented standalone foundations and must not be silently coupled into focus breathing. Mechanical/pupil vignetting, pupil/PSF coupling, and calibrated lens profiles remain future work.
|
|
186
|
+
|
|
187
|
+
## Standalone spatial camera-rotation foundation
|
|
188
|
+
|
|
189
|
+
The root engine exposes `calculateCameraRotationImageMapping()` as a low-level implementation of the image-formation contract's time-parameterized camera-rotation placement.
|
|
190
|
+
|
|
191
|
+
It is intentionally **not** composed into `simulatePocCamera()` yet. The existing POC and `estimateCameraShakeBlur()` retain their backwards-compatible global shake approximation.
|
|
192
|
+
|
|
193
|
+
The new primitive provides deterministic yaw/pitch/roll rotation geometry only. It does not model camera translation, stabilization control laws, rolling-readout scheduling, or scene-depth-dependent parallax.
|
|
194
|
+
|
|
21
195
|
## Repository-local Node POC transport
|
|
22
196
|
|
|
23
197
|
The repository contains a minimal Node-only HTTP transport under `src/api` for contributor integration testing.
|
|
@@ -30,7 +204,7 @@ This transport is intentionally **not** part of the public `@photivra/engine` pa
|
|
|
30
204
|
|
|
31
205
|
Future capabilities should compose onto the scientific core rather than silently widening unrelated models. Examples include:
|
|
32
206
|
|
|
33
|
-
-
|
|
207
|
+
- composed use of the standalone spatial camera-rotation model plus future depth-aware camera translation;
|
|
34
208
|
- panning and rolling/global shutter;
|
|
35
209
|
- flash;
|
|
36
210
|
- spectral/color modeling;
|
|
@@ -49,3 +223,7 @@ Capabilities should remain discoverable and explicitly versioned rather than bei
|
|
|
49
223
|
This repository contains the Apache-2.0 scientific/business-logic package together with its tests, documentation, schemas, validation, and contributor tooling.
|
|
50
224
|
|
|
51
225
|
The published npm package intentionally exposes only the browser-safe scientific root surface; repository-local development tooling such as the Node POC transport remains outside the published package.
|
|
226
|
+
|
|
227
|
+
## Version surfaces
|
|
228
|
+
|
|
229
|
+
The root library contract and the composed POC simulation contract are versioned independently. `ENGINE_API_VERSION` describes the root browser-safe engine surface. `POC_SIMULATION_API_VERSION` describes the request/response behavior of `simulatePocCamera()` and the repository-local POC HTTP transport. Package versioning remains separate from both.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Image-Formation Contract
|
|
2
|
+
|
|
3
|
+
Photivra's image-formation contract defines **scientific ownership, coordinate semantics, and dependency/coupling boundaries** for current and future camera effects.
|
|
4
|
+
|
|
5
|
+
It is not a claim that every stage is implemented, and it is not a requirement that renderers execute one literal serial filter chain.
|
|
6
|
+
|
|
7
|
+
Use:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import { getImageFormationContract } from "@photivra/engine";
|
|
11
|
+
|
|
12
|
+
const contract = getImageFormationContract();
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Five scientific domains
|
|
16
|
+
|
|
17
|
+
The contract groups image formation into five domains:
|
|
18
|
+
|
|
19
|
+
1. **scene / ray geometry**
|
|
20
|
+
2. **lens mapping + pupil / throughput**
|
|
21
|
+
3. **field- and wavelength-dependent PSF**
|
|
22
|
+
4. **time-dependent exposure / readout**
|
|
23
|
+
5. **native sensor sampling -> orientation -> output / display**
|
|
24
|
+
|
|
25
|
+
These are scientific ownership domains. Some effects couple more than one domain.
|
|
26
|
+
|
|
27
|
+
Examples:
|
|
28
|
+
|
|
29
|
+
- focus breathing changes projection/magnification and therefore couples lens mapping to scene projection;
|
|
30
|
+
- lateral chromatic aberration is wavelength/channel-dependent field mapping and may share wavelength basis with the PSF model;
|
|
31
|
+
- illumination vignetting is throughput-only;
|
|
32
|
+
- mechanical/pupil vignetting can change both throughput and PSF/bokeh shape;
|
|
33
|
+
- diffraction consumes the effective pupil and belongs to the PSF domain;
|
|
34
|
+
- rolling readout couples native sensor timing to temporal integration;
|
|
35
|
+
- camera rotation should be evaluable as a function of physical exposure time so global and rolling readout can consume the same motion model.
|
|
36
|
+
|
|
37
|
+
## Coordinate spaces
|
|
38
|
+
|
|
39
|
+
The contract explicitly distinguishes:
|
|
40
|
+
|
|
41
|
+
- `scene-metric` — scene/world metric coordinates;
|
|
42
|
+
- `image-plane-metric` — optical-axis origin, +X right, +Y up, millimetres;
|
|
43
|
+
- `native-sensor-physical` — optical-axis origin, +X right, +Y down, millimetres;
|
|
44
|
+
- `native-raster` — top-left origin, +X right, +Y down, pixels;
|
|
45
|
+
- `oriented-capture-raster` — explicit physical-orientation transform of native raster coordinates;
|
|
46
|
+
- `output-raster` — digital crop/resampling result;
|
|
47
|
+
- `display` — consumer/display coordinates, which are never authoritative camera-science coordinates.
|
|
48
|
+
|
|
49
|
+
Native sensor/raster coordinates remain invariant under physical camera orientation.
|
|
50
|
+
|
|
51
|
+
Use `mapOrientedPhysicalUvToImagePlanePoint()` and
|
|
52
|
+
`mapImagePlanePointToOrientedPhysicalUv()` when a renderer or integration
|
|
53
|
+
boundary must cross between a normalized oriented physical raster region and
|
|
54
|
+
the pre-orientation `image-plane-metric` space. These transforms explicitly
|
|
55
|
+
undo/apply physical orientation and convert the capture contract's physical
|
|
56
|
+
+Y-down basis to/from the optical image plane's +Y-up basis. They do not apply
|
|
57
|
+
projection, distortion, crop, or lens equations, and asymmetric physical bounds
|
|
58
|
+
remain asymmetric.
|
|
59
|
+
|
|
60
|
+
## Partial ordering and coupling
|
|
61
|
+
|
|
62
|
+
`requiredUpstreamStages` defines hard scientific dependencies.
|
|
63
|
+
|
|
64
|
+
`coupledStages` identifies interactions that must not be treated as independent post-processes.
|
|
65
|
+
|
|
66
|
+
The required-dependency graph is acyclic. Coupling may be bidirectional because it describes shared scientific state rather than execution order.
|
|
67
|
+
|
|
68
|
+
An implementation may combine stages for performance only when the combination is mathematically equivalent and the public stage/effect semantics remain intact.
|
|
69
|
+
|
|
70
|
+
## PSF contribution foundation
|
|
71
|
+
|
|
72
|
+
The `field-wavelength-psf` stage has a dedicated public foundation documented in [PSF and Pupil Foundation](PSF_FOUNDATION.md).
|
|
73
|
+
|
|
74
|
+
Current implementation:
|
|
75
|
+
- geometric defocus-circle diagnostic;
|
|
76
|
+
- ideal circular-pupil Airy first-zero diagnostic;
|
|
77
|
+
- explicit field/depth/wavelength/pupil context.
|
|
78
|
+
|
|
79
|
+
Reserved contributions:
|
|
80
|
+
- non-circular diffraction;
|
|
81
|
+
- mechanical pupil clipping;
|
|
82
|
+
- field curvature;
|
|
83
|
+
- field-dependent aberration;
|
|
84
|
+
- field-dependent bokeh.
|
|
85
|
+
|
|
86
|
+
No combined PSF is currently calculated.
|
|
87
|
+
|
|
88
|
+
## Temporal basis
|
|
89
|
+
|
|
90
|
+
Physical time is measured in **seconds from exposure start**.
|
|
91
|
+
|
|
92
|
+
A normalized `[0,1]` shutter parameter may be derived for an algorithm, but it is not the authoritative time coordinate.
|
|
93
|
+
|
|
94
|
+
Exposure duration and sensor readout timing are independent:
|
|
95
|
+
|
|
96
|
+
- global readout does not mean zero motion blur;
|
|
97
|
+
- rolling readout changes when different native sensor locations are sampled/integrated;
|
|
98
|
+
- native readout direction remains defined in native sensor coordinates even when the camera is physically rotated.
|
|
99
|
+
|
|
100
|
+
This allows later rolling-shutter work to consume the same time-parameterized camera-motion model used for global exposure.
|
|
101
|
+
|
|
102
|
+
## Renderer semantics
|
|
103
|
+
|
|
104
|
+
Renderer implementations may use a bounded real-time preview approximation or a higher-fidelity deterministic reference evaluation, but both must consume the same engine-owned scientific contract.
|
|
105
|
+
|
|
106
|
+
For geometric warps:
|
|
107
|
+
|
|
108
|
+
- destination samples are inverse-mapped to source locations;
|
|
109
|
+
- premultiplied-alpha semantics are preserved;
|
|
110
|
+
- scene depth/occlusion order is preserved across warps;
|
|
111
|
+
- renderer backend choice may change implementation/fidelity, not model semantics.
|
|
112
|
+
|
|
113
|
+
## Reserved sensor ordering
|
|
114
|
+
|
|
115
|
+
The contract reserves a future sensor path without claiming it is implemented:
|
|
116
|
+
|
|
117
|
+
```text
|
|
118
|
+
optical PSF
|
|
119
|
+
-> sensor optical stack (OLPF / cover glass / microlens)
|
|
120
|
+
-> photosite / CFA sampling
|
|
121
|
+
-> photon / charge statistics
|
|
122
|
+
-> electronic read noise / conversion
|
|
123
|
+
-> ADC / quantization
|
|
124
|
+
-> reconstruction (demosaic / remosaic / capture-mode combination)
|
|
125
|
+
-> physical orientation transform
|
|
126
|
+
-> output crop / resampling
|
|
127
|
+
-> display processing
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Temporal exposure/readout couples into the photosite/charge stages rather than acting as an unrelated display blur.
|
|
131
|
+
|
|
132
|
+
## Current implementation status
|
|
133
|
+
|
|
134
|
+
Each stage is labeled:
|
|
135
|
+
|
|
136
|
+
- `existing-foundation` — the root engine already contains the relevant foundation;
|
|
137
|
+
- `partial-foundation` — some low-level science exists, but the full stage contract is not implemented; spatial camera rotation in the temporal domain plus declared-scale focus breathing, radial distortion, RGB-channel lateral CA, and illumination throughput in the lens-field domain are current examples;
|
|
138
|
+
- `reserved-contract` — ordering/ownership is reserved for future work only.
|
|
139
|
+
|
|
140
|
+
Do not infer capabilities from a stage merely because it is present in the contract.
|
|
141
|
+
|
|
142
|
+
## Test Fixture relationship
|
|
143
|
+
|
|
144
|
+
The private Test Fixture may provide deterministic browser regression targets, but it is not the scientific source of truth for the open engine.
|
|
145
|
+
|
|
146
|
+
Engine analytical/invariant tests establish model correctness. Test Fixture images provide secondary integration and renderer evidence.
|
|
147
|
+
|
|
148
|
+
In particular:
|
|
149
|
+
|
|
150
|
+
- the LDR/sRGB optics target may verify deterministic field/channel mapping behavior;
|
|
151
|
+
- it does not establish spectral lens calibration, MTF, RAW/CFA truth, HDR radiometry, or real-lens performance.
|
|
@@ -21,10 +21,49 @@ Projected displacement therefore depends on:
|
|
|
21
21
|
- object velocity;
|
|
22
22
|
- optional sensor pixel pitch for pixel-domain reporting.
|
|
23
23
|
|
|
24
|
+
The low-level motion primitive still accepts one scalar pixel pitch. The newer sensor-geometry API preserves independent X/Y geometric pitch. The composed POC therefore fails closed when X/Y pitch differs by more than 1% rather than silently applying horizontal pitch to materially different vertical sampling.
|
|
25
|
+
|
|
24
26
|
The model can represent a representative point moving laterally and/or along the optical axis. It does **not** yet model an extended object's changing apparent scale across the exposure, rotational subject motion, acceleration, deformation, or occlusion changes. A large object moving significantly in depth can therefore exhibit real scale blur that this point-displacement primitive does not describe.
|
|
25
27
|
|
|
26
28
|
Camera motion is not folded into subject motion. Camera shake is modeled separately by `estimateCameraShakeBlur()`; panning detection/intent is not currently modeled.
|
|
27
29
|
|
|
30
|
+
The returned `deltaXmm`/`deltaYmm` components are legacy camera/image-plane components: +X right and +Y up. They are preserved for compatibility.
|
|
31
|
+
|
|
32
|
+
Capture raster coordinates use +X right and +Y down. POC API 0.19 therefore converts a legacy image-plane vector to native raster axes as `{ x, y: -y }` before applying the native↔oriented rotation helper. The additive capture diagnostics expose `nativeRasterDeltaPixels`, `orientedCaptureDeltaPixels`, and `outputDeltaPixels`; the legacy motion fields are not reinterpreted.
|
|
33
|
+
|
|
34
|
+
## Spatial camera rotation
|
|
35
|
+
|
|
36
|
+
`calculateCameraRotationImageMapping()` now provides the rotation-only primitive reserved by the image-formation contract.
|
|
37
|
+
|
|
38
|
+
The function:
|
|
39
|
+
|
|
40
|
+
- accepts one image-plane point at exposure start;
|
|
41
|
+
- uses physical time in seconds from exposure start;
|
|
42
|
+
- accepts constant pitch/yaw/roll angular velocity resolved in the camera axes at exposure start;
|
|
43
|
+
- integrates the simultaneous angular velocity as one axis-angle vector;
|
|
44
|
+
- transforms the stationary world ray by the inverse camera rotation;
|
|
45
|
+
- returns field-position-dependent image-plane displacement;
|
|
46
|
+
- optionally reports axis-aware geometric sample displacement.
|
|
47
|
+
|
|
48
|
+
For pure yaw/pitch, image displacement varies with field position because the rectilinear projection denominator changes away from the optical axis. Pure roll leaves the optical-axis center fixed while rotating off-axis points.
|
|
49
|
+
|
|
50
|
+
This is camera **rotation only**. Translation is excluded because parallax requires scene depth.
|
|
51
|
+
|
|
52
|
+
The returned image-plane/sample components use +X right and +Y up. Native raster remains +X right/+Y down and requires the existing explicit coordinate transform at capture composition boundaries.
|
|
53
|
+
|
|
54
|
+
## Temporal image-formation basis
|
|
55
|
+
|
|
56
|
+
The image-formation contract defines physical time in **seconds from exposure start**.
|
|
57
|
+
|
|
58
|
+
A future spatial camera-rotation model should be evaluable at arbitrary physical times rather than returning only one finished full-frame displacement. That allows global exposure and later rolling readout to consume the same camera-motion model.
|
|
59
|
+
|
|
60
|
+
Exposure duration and sensor readout timing are independent concepts:
|
|
61
|
+
|
|
62
|
+
- global readout can still contain subject/camera motion blur;
|
|
63
|
+
- rolling readout changes the exposure/readout schedule across native sensor locations;
|
|
64
|
+
- physical orientation does not redefine native sensor scan direction;
|
|
65
|
+
- depth-dependent camera translation is not part of the initial rotational-flow model because parallax depends on scene depth.
|
|
66
|
+
|
|
28
67
|
## Exposure relations
|
|
29
68
|
|
|
30
69
|
`calculateExposureValue100()` implements EV100 from aperture and shutter duration.
|
|
@@ -48,7 +87,19 @@ These functions do **not** derive incident photon counts from scene imagery.
|
|
|
48
87
|
|
|
49
88
|
They do not currently model dark current, fixed-pattern noise, PRNU/DSNU, ADC quantization, clipping/full-well behavior, CFA/demosaic, downstream denoising, or a particular commercial sensor.
|
|
50
89
|
|
|
51
|
-
The composed POC intentionally does not expose photon/noise output
|
|
90
|
+
The composed POC intentionally does not expose photon/noise output.
|
|
91
|
+
|
|
92
|
+
The root package now includes a **radiometry-readiness gate** that validates whether a declared prerequisite package contains scene spectral radiance, optical transmission, pupil/vignetting behavior, explicit photosite collection-area semantics, exposure integration, sensor response, evidence, and uncertainty declarations.
|
|
93
|
+
|
|
94
|
+
Readiness is deliberately separate from signal/noise calculation:
|
|
95
|
+
|
|
96
|
+
- `not-ready`: prerequisite categories are missing;
|
|
97
|
+
- `approximate-only`: all categories exist, but at least one is approximate or has unquantified uncertainty;
|
|
98
|
+
- `calibrated-ready`: all categories are declared calibrated with quantified uncertainty.
|
|
99
|
+
|
|
100
|
+
These states describe the declared prerequisite package only. They do not prove a calibration is correct, do not calculate incident photons, and never enable photon/noise output in `simulatePocCamera()` automatically.
|
|
101
|
+
|
|
102
|
+
Geometric pixel/sample pitch is not accepted as photon-collection area. An explicit effective collection area or geometric cell area plus fill factor is required.
|
|
52
103
|
|
|
53
104
|
## Provenance
|
|
54
105
|
|
|
@@ -14,14 +14,71 @@ where `d` is the relevant sensor dimension and `v` is the projection/image-plane
|
|
|
14
14
|
|
|
15
15
|
When no focus distance is supplied, `v = f` is the infinity-focus/pinhole compatibility approximation. When focus distance is supplied, `v` is the ideal Gaussian thin-lens image distance.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
For a centered sensor interval, the usual symmetric form is sufficient. For an off-center sensor interval, Photivra uses signed sensor-plane bounds relative to the optical axis:
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
`FOV = atan(x_max / v) - atan(x_min / v)`
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
This preserves asymmetric left/right or top/bottom angular limits instead of pretending every active crop is centered.
|
|
22
|
+
|
|
23
|
+
### Sensor geometry, sampling, capture, and crop
|
|
24
|
+
|
|
25
|
+
Photivra separates physical image-formation geometry from digital sampling.
|
|
26
|
+
|
|
27
|
+
`SensorImagingArea` represents the physical photosensitive area used for image formation. It is not a sensor package/die dimension.
|
|
28
|
+
|
|
29
|
+
`NativeImageRaster` represents the effective native image-sampling grid. It does not imply that one output/image sample corresponds one-to-one with one physical photodiode. Generic active/output rasters use `RasterDimensions`.
|
|
30
|
+
|
|
31
|
+
Geometric sample pitch is derived independently on each axis:
|
|
32
|
+
|
|
33
|
+
- `pitchX = imagingWidth / nativePixelWidth`;
|
|
34
|
+
- `pitchY = imagingHeight / nativePixelHeight`.
|
|
35
|
+
|
|
36
|
+
These pitches are geometric sample spacing only. They are not fill factor, effective collection area, or photon-collection area.
|
|
37
|
+
|
|
38
|
+
The capture pipeline is staged:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
physical imaging area + native raster
|
|
42
|
+
↓
|
|
43
|
+
native active-capture rectangle
|
|
44
|
+
↓
|
|
45
|
+
physical camera orientation
|
|
46
|
+
↓
|
|
47
|
+
oriented active capture
|
|
48
|
+
↓
|
|
49
|
+
digital/output crop
|
|
50
|
+
↓
|
|
51
|
+
output raster
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Native raster coordinates use a top-left origin with +X right and +Y down. Integer rectangles are half-open. Physical camera rotation does not redefine the native coordinate system; Photivra transforms points, vectors, and rectangles explicitly between native and oriented coordinates.
|
|
55
|
+
|
|
56
|
+
For the generic sensor model, active physical dimensions and optical-axis offset are derived by assuming the native sampling grid uniformly spans the declared physical imaging area. This assumption is recorded because a future calibrated camera profile may need explicit physical active-area data instead.
|
|
57
|
+
|
|
58
|
+
An off-center active rectangle changes both retained physical extent and angular position relative to the optical axis. It must therefore use asymmetric angular bounds rather than a centered FOV formula.
|
|
59
|
+
|
|
60
|
+
For an off-center rectangular active area, the two opposite-corner diagonal angular spans need not be equal. `calculateActiveCaptureFieldOfView()` reports both and uses the larger span for its compatibility `diagonalDegrees` summary.
|
|
61
|
+
|
|
62
|
+
Output crop/resampling is digital geometry. It does not mutate physical sensor identity or active-capture geometry. Output raster aspect ratio must remain consistent with the selected output crop; implicit geometric stretching is rejected.
|
|
63
|
+
|
|
64
|
+
Centered crop dimensions are derived from a linear crop factor while preserving source aspect ratio, subject to integer pixel flooring.
|
|
22
65
|
|
|
23
66
|
Subject-height framing crop computes the additional same-aspect crop needed to target a requested subject-height fraction. It assumes the crop can be positioned around the subject and does not check subject position against image edges.
|
|
24
67
|
|
|
68
|
+
### Crop factor and 35 mm-equivalent focal length
|
|
69
|
+
|
|
70
|
+
Physical crop factor is diagonal-based relative to a 36 × 24 mm reference frame:
|
|
71
|
+
|
|
72
|
+
`cropFactor = diagonal_35mm / activeCaptureDiagonal`
|
|
73
|
+
|
|
74
|
+
Conventional 35 mm-equivalent focal length is:
|
|
75
|
+
|
|
76
|
+
`equivalentFocalLength = actualFocalLength × cropFactor`
|
|
77
|
+
|
|
78
|
+
The actual focal length remains the optical focal length. Equivalent focal length is a derived framing convention; it does not replace physical focal length in projection or depth-of-field calculations.
|
|
79
|
+
|
|
80
|
+
Photivra bases equivalence on the active physical capture area, not later digital/output crop. Physical orientation leaves the active diagonal unchanged and therefore does not change diagonal-based equivalent focal length. Different aspect ratios can still produce different horizontal/vertical FOV even when the single diagonal-equivalent number is the same.
|
|
81
|
+
|
|
25
82
|
### Projection, focus extension, object size, and motion
|
|
26
83
|
|
|
27
84
|
Field of view, projected fronto-parallel object size, projected representative-point subject motion, and camera-shake projection support two explicit projection modes:
|
|
@@ -37,18 +94,110 @@ The focus-aware model improves internal consistency with thin-lens DOF/defocus c
|
|
|
37
94
|
|
|
38
95
|
Projected subject motion is a representative-point displacement model with constant linear world velocity. It does not yet describe scale blur of an extended object whose magnification changes materially during the exposure.
|
|
39
96
|
|
|
97
|
+
### Generic illumination vignetting
|
|
98
|
+
|
|
99
|
+
The engine exposes a generic rotationally symmetric **relative linear illumination** model:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
T(rho) = 1 + r2*rho² + r4*rho⁴ + r6*rho⁶
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
where `rho` is ideal image-plane field radius divided by the caller-declared physical normalization radius.
|
|
106
|
+
|
|
107
|
+
The optical axis is normalized to `T(0) = 1`.
|
|
108
|
+
|
|
109
|
+
The declared `maximumNormalizedRadius` is a scientific operating envelope. Photivra evaluates the polynomial endpoints and all real internal extrema over the full interval and rejects profiles that:
|
|
110
|
+
|
|
111
|
+
- produce zero/negative throughput; or
|
|
112
|
+
- exceed the center-normalized throughput of 1.
|
|
113
|
+
|
|
114
|
+
The result is a linear-light multiplicative attenuation plus equivalent positive stop loss.
|
|
115
|
+
|
|
116
|
+
This slice is **not mechanical/pupil vignetting**. It does not clip the pupil or change bokeh/PSF shape. It also does not claim calibrated radiometry or named-lens behavior.
|
|
117
|
+
|
|
118
|
+
### Generic lateral chromatic aberration
|
|
119
|
+
|
|
120
|
+
The standalone lateral-CA foundation uses the green channel as the reference field mapping.
|
|
121
|
+
|
|
122
|
+
A shared base radial-distortion profile defines the common geometric lens mapping. Red and blue coefficient offsets are added to that base before each channel is mapped:
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
green coefficients = base
|
|
126
|
+
red coefficients = base + red offset
|
|
127
|
+
blue coefficients = base + blue offset
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
This keeps ordinary geometric distortion and lateral chromatic separation distinct while allowing one renderer pass to consume the combined per-channel mapping.
|
|
131
|
+
|
|
132
|
+
The model deliberately does **not** represent CA as finished-image RGB blur. Forward mapping reports per-channel field coordinates and vector separation; inverse mapping reports the per-channel ideal source coordinate required for one distorted destination.
|
|
133
|
+
|
|
134
|
+
All combined channel profiles share one physical normalization radius and operating envelope and must remain individually invertible.
|
|
135
|
+
|
|
136
|
+
The RGB labels are representative renderer channels only. The model does not define wavelengths, sensor CFA responses, longitudinal chromatic aberration, wavelength-dependent PSFs, or calibrated real-lens color behavior.
|
|
137
|
+
|
|
138
|
+
### Generic radial distortion
|
|
139
|
+
|
|
140
|
+
The engine includes a standalone rotationally symmetric radial field-mapping approximation:
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
p_distorted = p_ideal × (1 + k1 r² + k2 r⁴ + k3 r⁶)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
where `r` is image-plane radius divided by a caller-declared physical normalization radius.
|
|
147
|
+
|
|
148
|
+
The declared `maximumNormalizedRadius` is part of the scientific contract. Photivra checks the derivative of the radial mapping over that interval and rejects profiles that are not strictly one-to-one. This makes deterministic inverse destination-to-source sampling well-defined.
|
|
149
|
+
|
|
150
|
+
The model is centered on the optical axis and does not yet include tangential/decentering terms. Coefficients are generic inputs, not real-lens calibration data.
|
|
151
|
+
|
|
152
|
+
### Declared-scale focus breathing
|
|
153
|
+
|
|
154
|
+
The root engine exposes a generic focus-breathing projection approximation.
|
|
155
|
+
|
|
156
|
+
For one selected focus state:
|
|
157
|
+
|
|
158
|
+
```text
|
|
159
|
+
effective projection distance
|
|
160
|
+
= ideal thin-lens image distance × caller-declared breathing projection scale
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Scale `1` exactly preserves the existing thin-lens projection.
|
|
164
|
+
|
|
165
|
+
The model intentionally does not infer a focus-breathing curve. It represents focus-dependent framing/magnification only when the caller supplies the scale for that state. Physical focal length remains unchanged.
|
|
166
|
+
|
|
167
|
+
This simplified scale does not model principal-plane movement, pupil magnification, distortion, aberrations, or a named commercial lens. Those require separate models and, for calibrated profiles, defensible provenance.
|
|
168
|
+
|
|
40
169
|
### Thin-lens focus and depth of field
|
|
41
170
|
|
|
42
171
|
The geometric depth-of-field model uses the conventional hyperfocal/near/far equations with a caller-supplied acceptable circle of confusion.
|
|
43
172
|
|
|
44
173
|
The circle-of-confusion criterion is a viewing/acceptability input, not a physical sensor threshold. The optional equivalent-viewing helper scales a caller-supplied reference criterion by sensor-diagonal ratio and is explicitly labeled an approximation.
|
|
45
174
|
|
|
175
|
+
In composed POC capture mode, the equivalent-viewing helper uses the final retained physical image region that will be enlarged to the assumed final viewing size. Active capture, digital output crop, and centered subject framing can therefore change the viewing criterion; output pixel resolution alone cannot. This changes only the viewing/acceptability convention, not the physical optical blur. An explicit caller-supplied `circleOfConfusionMm` is never rescaled.
|
|
176
|
+
|
|
46
177
|
The model is not a macro calibration model and does not include diffraction, pupil magnification, aberrations, focus breathing, or lens-specific principal-plane behavior in its DOF criterion.
|
|
47
178
|
|
|
48
179
|
### Defocus circle
|
|
49
180
|
|
|
50
181
|
Defocus is calculated geometrically by comparing the selected sensor plane for the focus distance with the ideal image plane for the subject distance and projecting an ideal circular entrance-pupil cone to the sensor.
|
|
51
182
|
|
|
183
|
+
### PSF/pupil foundation
|
|
184
|
+
|
|
185
|
+
The engine now exposes a PSF/pupil foundation that evaluates existing geometric defocus and circular diffraction diagnostics in one explicit context while keeping the numerical contributions separate.
|
|
186
|
+
|
|
187
|
+
The context declares:
|
|
188
|
+
|
|
189
|
+
- physical image-plane field position;
|
|
190
|
+
- a comparison-only field normalization radius;
|
|
191
|
+
- focus and subject depth;
|
|
192
|
+
- monochromatic wavelength basis;
|
|
193
|
+
- ideal circular f-number-derived pupil size.
|
|
194
|
+
|
|
195
|
+
The current foundation does **not** calculate a combined point-spread function or MTF. Defocus-circle diameter and Airy first-zero diameter are not added together or collapsed into one sharpness value.
|
|
196
|
+
|
|
197
|
+
Reserved future contributions include non-circular diffraction, mechanical pupil clipping, field curvature, field-dependent aberration structure, and field-dependent bokeh.
|
|
198
|
+
|
|
199
|
+
Illumination vignetting remains outside the PSF contribution list because it is currently modeled as throughput-only.
|
|
200
|
+
|
|
52
201
|
### Diffraction
|
|
53
202
|
|
|
54
203
|
For an ideal circular aperture, first-zero Airy diameter is:
|
|
@@ -79,6 +228,44 @@ The current model returns one global image-plane vector. It does not compute the
|
|
|
79
228
|
|
|
80
229
|
Equivalent stabilization stops attenuate angular displacement by `2^-stops`; that attenuation is explicitly an educational approximation rather than a real IBIS/OIS or CIPA performance model.
|
|
81
230
|
|
|
231
|
+
### Radiometry readiness boundary
|
|
232
|
+
|
|
233
|
+
Absolute scene luminance or relative exposure alone is not enough to derive a defensible photon count.
|
|
234
|
+
|
|
235
|
+
Before any future composed photon simulation, Photivra requires an explicit prerequisite package covering:
|
|
236
|
+
|
|
237
|
+
- scene spectral radiance or a documented spectral approximation;
|
|
238
|
+
- optical transmission;
|
|
239
|
+
- pupil/vignetting behavior;
|
|
240
|
+
- photosite collection-area semantics;
|
|
241
|
+
- exposure integration;
|
|
242
|
+
- sensor spectral response / quantum efficiency;
|
|
243
|
+
- evidence and uncertainty/limitation metadata for each component.
|
|
244
|
+
|
|
245
|
+
`assessRadiometryReadiness()` can classify a declared package as `not-ready`, `approximate-only`, or `calibrated-ready`. This classification validates the declared model/evidence structure; it does not prove that the calibration is scientifically correct and does not itself calculate photons.
|
|
246
|
+
|
|
247
|
+
Geometric sample pitch is intentionally insufficient as a collection-area model. A profile must provide either an effective collection area or geometric cell area plus explicit fill factor.
|
|
248
|
+
|
|
249
|
+
Approximate inputs remain approximate even when every prerequisite category is present. A calibrated-ready declaration requires calibrated components with quantified uncertainty.
|
|
250
|
+
|
|
251
|
+
The composed POC continues to emit no photon/photoelectron/SNR output from scene settings. Low-level `calculatePhotoelectrons()` remains a separate primitive for callers that already possess a defensible incident-photon count and QE.
|
|
252
|
+
|
|
253
|
+
## Image-formation domain boundary
|
|
254
|
+
|
|
255
|
+
Future optical and sensor models must follow `getImageFormationContract()`.
|
|
256
|
+
|
|
257
|
+
The contract intentionally avoids describing all image formation as independent serial post-processing. Some quantities are coupled:
|
|
258
|
+
|
|
259
|
+
- focus-dependent projection and lens mapping;
|
|
260
|
+
- wavelength-dependent field mapping and PSF basis;
|
|
261
|
+
- pupil clipping, throughput, and bokeh/PSF shape;
|
|
262
|
+
- time-varying scene/camera mapping and sensor readout schedule;
|
|
263
|
+
- native sensor sampling and reconstruction.
|
|
264
|
+
|
|
265
|
+
Current analytical primitives remain valid and separately named. Adding a broader stage must not silently reinterpret existing focal length, defocus, diffraction, motion, crop, or sensor-sampling outputs.
|
|
266
|
+
|
|
267
|
+
Reserved sensor stages in the contract are ordering placeholders only; they do not establish OLPF, CFA, photon, ADC, or reconstruction capabilities.
|
|
268
|
+
|
|
82
269
|
## Source provenance
|
|
83
270
|
|
|
84
271
|
These implementations were written independently from established mathematical/physical relations. No third-party source code, calibration dataset, table, or model weight is incorporated by these scientific modules.
|