AcresCameraModel.h#
Acres/Source/Acres/AcresCameraModel.h Generated
Photometric and geometric model of a machine-vision RGB camera, applied on the CPU to the scene-capture render.
Unreal renders an ideal pinhole image (a USceneCaptureComponent2D writing into a render target, set up in AcresSensors.cpp) that is a little wider than the output. FAcresCameraModel::Process then builds the delivered image pixel by pixel. Chain per output pixel:
distorted pixel -> undistorted ray (Brown-Conrady inverse, precomputed) -> lateral chromatic aberration (radial scale of the ray per colour) -> rolling-shutter row rotation/translation -> pinhole projection into the wider render -> bilinear sample of the CFA colour in linear light (sRGB decoded) -> vignetting -> electrons (PRNU, shot + dark + read noise) -> ADC (black level, bits) -> ISP (black subtract, Malvar-He-Cutler or bilinear demosaic, sRGB encode).
The render is display-referred (tone-mapped), so "linear" means the inverse sRGB curve of the 8-bit image, not scene radiance. Settings come from the sensors.json blocks camera.lens, camera.rolling_shutter and camera.photometric. Pure C++: no Unreal objects, and Process runs on Unreal's thread pool.
FAcresCameraModelConfig#
Camera model settings (sensors.json camera.lens / camera.rolling_shutter / camera.photometric).
Normalized coordinates are x = (u - cx) / fx, y = (v - cy) / fy with the optical axes x right, y down, z forward.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
Enabled |
bool |
true |
Master switch. False (or -SensorCameraIdeal) delivers the ideal pinhole render with no processing. Derived in ApplyCommandLine as Distortion || RollingShutter || Sensor. |
|
Distortion |
bool |
true |
Apply the lens model: distortion, principal point offset, vignetting and chromatic aberration (camera.lens.enabled). | |
K1, K2, K3, P1, P2 |
double |
OpenCV plumb_bob / Brown-Conrady coefficients on normalized undistorted coordinates: radial K1, K2, K3 and tangential P1, P2 (dimensionless). | ||
PrincipalOffsetXPx, PrincipalOffsetYPx |
double |
Principal point minus image centre, pixels (x right, y down). Applied only with Distortion on. | ||
FxPx, FyPx, CxPx, CyPx |
double |
Explicit output intrinsics, pixels, as a recorded camera_info gives them (OpenCV K: fx, fy, cx, cy; camera.lens.intrinsics). FxPx <= 0 (the default) derives fx = fy from the horizontal FOV and the principal point from the image centre plus the offset above. | ||
RadialMinSlope |
double |
0 |
Radial extension beyond the calibrated field (camera.lens.radial_min_slope): when above 0, the polynomial r_d(r) = r (1 + k1 r^2 + k2 r^4 + k3 r^6) is used out to the radius where its slope dr_d/dr falls to this value, and continues as a straight line with that slope beyond it. A strong barrel calibration (the Purdue Reolink's k1 = -0.55) turns back before the image corners; the real lens keeps mapping wider rays there. 0 = off. | |
RadialLimitR |
double |
0 |
Derived by FAcresCameraModel::Initialize: the undistorted radius where the extension starts (0 = none). | |
Vignetting |
FString |
TEXT("poly") |
Vignetting model: "poly" (V = 1 + a2 r^2 + a4 r^4), "cos4" (cos^4 of the ray angle) or "none". | |
VignetteA2, VignetteA4 |
double |
VignetteA2, VignetteA4: "poly" coefficients, with r the distorted normalized radius. | ||
ChromaticAberrationPx |
double |
.7 |
Lateral chromatic aberration at the image corner, pixels: red is pushed outward, blue inward (0-5). | |
RenderScale |
double |
1. |
Render focal length = output fx x scale (0.5-2). | |
RenderMargin |
double |
.02 |
Extra fractional field of view around what the distorted image needs, so rolling-shutter shifts stay inside the render (0-0.2). | |
RollingShutter |
bool |
true |
Simulate the row-by-row readout of a rolling-shutter sensor. | |
ReadoutS |
double |
s | .025 |
Time from the first to the last row, s (0-0.1). |
AssumedDepthM |
double |
m | 15. |
Single scene depth used to turn camera translation into image motion, m (0 = rotation only). |
Sensor |
bool |
true |
Simulate the Bayer sensor, ADC and demosaic (camera.photometric.enabled). | |
Noise |
bool |
true |
Add PRNU, shot, dark and read noise (off with -SensorCameraNoNoise or -SensorNoNoise). | |
PixelPitchUm |
double |
2.8 |
Pixel pitch, micrometres (reported only). | |
FullWellE |
double |
10000 |
Full-well capacity, electrons. | |
ReadNoiseE |
double |
2.5 |
Read noise, electrons RMS. | |
DarkCurrentEps |
double |
50 |
Dark current, electrons per second. | |
PrnuStd |
double |
.01 |
Pixel gain non-uniformity, fraction (sigma). | |
BaseIso |
double |
100 |
ISO at unity analog gain. | |
AdcBits |
int |
12 |
ADC resolution in bits (8-16). | |
BlackLevelDn |
double |
256 |
ADC offset added to every pixel, DN (must stay below a quarter of the range). | |
Cfa |
FString |
TEXT("RGGB") |
Bayer layout of the top-left 2x2 block, "RGGB", "BGGR", "GRBG" or "GBRG". | |
Demosaic |
FString |
TEXT("malvar") |
"malvar" (Malvar, He and Cutler 2004 5x5 filters) or "bilinear". |
FAcresCameraModelConfig::Parse#
Reads the "lens", "rolling_shutter" and "photometric" sub-objects of the sensors.json "camera" block.
| Argument | Description |
|---|---|
CameraBlock |
The "camera" JSON object. Missing keys keep their defaults. |
FAcresCameraModelConfig::ApplyCommandLine#
Applies -SensorCameraIdeal, -SensorCameraNoRollingShutter, -SensorCameraNoNoise, -SensorCameraNoDistortion, -SensorCameraReadout=<s> and the global -SensorNoNoise (same as -SensorCameraNoNoise), then recomputes Enabled.
| Argument | Description |
|---|---|
CommandLine |
The command line to read (null: the process's; "" gives the file settings with the derived values updated, as the sensor profile's reference needs). |
FAcresCameraModelConfig::Validate#
Checks every parameter against its supported range; stops the game with a checkf message if not.
FAcresCameraModelConfig::ToJson#
Serialises the settings with the same keys as sensors.json.
Returns: A JSON object with "enabled", "lens", "rolling_shutter" and "photometric".
FAcresCameraOverrides#
Switches used by the self-test to turn individual effects off while keeping the rest of the pipeline.
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
Vignetting, Noise, Aberration |
bool |
Vignetting, Noise, Aberration: false disables that effect for one Process call. |
FAcresCameraModel#
A calibrated virtual camera: intrinsics, precomputed undistortion table, PRNU map and the per-frame image pipeline.
The recorder builds one in Start with Initialize, sizes the scene-capture render target from RenderWidth x RenderHeight and RenderHfovDeg, and for every captured frame calls Process on a thread-pool task. After Initialize the object is read-only, so one instance can be shared by several threads.
Example
FAcresCameraModel Model;
Model.Initialize(Config.CameraModel, 1920, 1080, 90, 1. / 333, 100, 42);
TArray<FColor> Image;
Model.Process(RenderPixels.GetData(), Motion, FrameIndex, Image); // 1920 x 1080 sensor image
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
FOverrides |
using |
FAcresCameraOverrides |
Short alias for the self-test switches. | |
RenderWidth, RenderHeight |
int |
Render target the scene capture must produce: wider FOV so distortion and rolling shutter never sample outside it. RenderWidth, RenderHeight in pixels. | ||
RenderHfovDeg |
double |
° | 90 |
Render horizontal FOV, degrees. |
RenderFx |
double |
0 |
Render focal length, pixels. RenderCx, | |
RenderCx |
double |
0 |
See above. | |
RenderCy |
double |
0 |
Render principal point, pixels (the exact centre). | |
Width, Height |
int |
Output (distorted) image size in pixels. | ||
Fx, Fy, Cx, Cy, EffectiveHfovDeg, EffectiveVfovDeg |
double |
Output intrinsics, OpenCV pixel-centre convention (pixels): Fx, Fy focal lengths, Cx, Cy principal point. EffectiveHfovDeg / EffectiveVfovDeg: true field of view of the distorted image through the principal point, degrees. | ||
PrnuSequenceBase |
static constexpr uint64 |
0x10000 |
PRNU stream sequence offset (65536), kept clear of the row-numbered frame-noise sequences. |
FAcresCameraModel::FromUnrealBody#
Converts motion in the Unreal body frame (x forward, y right, z up; left-handed) to the optical frame.
The axis map is a reflection (determinant -1), so the linear velocity maps directly but the angular velocity, a pseudovector, changes sign.
| Argument | Description |
|---|---|
AngularBody |
Angular velocity in the Unreal body frame, rad/s. |
VelocityBodyMps |
Camera point velocity in the Unreal body frame, m/s. |
Returns: The same motion in optical axes.
FAcresCameraModel::Initialize#
Computes intrinsics, render size, the undistortion table, sRGB lookup tables and the PRNU map.
fx = fy = Width / (2 tan(HfovDeg / 2)); cx = (Width - 1) / 2 + principal offset (OpenCV pixel centres). Each output pixel's undistorted ray is found by Newton iteration on the forward distortion model (at most 30 iterations, stop at 1e-12). The render is the smallest even-sized pinhole image, at focal fx x RenderScale, that contains every ray grown by the CA scale and RenderMargin.
| Argument | Description |
|---|---|
Config |
Model settings; validated again here. |
Width |
Output image width, pixels. |
Height |
Output image height, pixels. |
HfovDeg |
Pinhole-equivalent horizontal FOV that defines fx, degrees. |
ShutterS |
Exposure time, s (dark-current integration). |
Iso |
ISO; analog gain = Iso / BaseIso. |
Seed |
Master seed for the PRNU map and the per-frame noise streams. |
Note
Stops the game (checkf) if the distortion cannot be inverted to 1e-3 px, folds over inside the field of view, or needs a render larger than 8192 px.
FAcresCameraModel::IsActive#
True when the model processes frames (false = ideal pinhole passthrough).
FAcresCameraModel::Process#
Turns one render into one sensor image.
| Argument | Description |
|---|---|
In |
RenderWidth x RenderHeight sRGB pixels (row-major, as read back from the render target). |
Motion |
Camera motion in optical axes, for the rolling-shutter warp. |
FrameIndex |
Frame counter; selects the noise stream so each frame gets fresh, reproducible noise. |
Out |
Receives Width x Height sRGB pixels, alpha 255. |
RawOut |
Optional; receives the Width x Height Bayer mosaic in ADC counts (DN). |
Ov |
Self-test switches. |
Note
Thread-safe (const, no shared mutable state); requires IsActive(). Rows run in parallel with ParallelFor (Unreal's parallel loop over the task graph).
FAcresCameraModel::MapToRender#
Maps an output pixel to its sampling position in the render, for the green channel (no CA), exactly as Process does. Used by the self-test for verification.
| Argument | Description |
|---|---|
U |
Output column, pixels. |
V |
Output row, pixels (sets the rolling-shutter time offset). |
Motion |
Camera motion in optical axes. |
Returns: Render pixel coordinates (u, v).
FAcresCameraModel::UndistortedRay#
Undistorted normalized ray (x/z, y/z) of output pixel (U, V), from the precomputed table.
| Argument | Description |
|---|---|
U |
Output column, pixels. |
V |
Output row, pixels. |
Returns: Normalized undistorted coordinates (dimensionless).
FAcresCameraModel::NoiseInitState#
PCG32 init state of the per-frame noise streams: Seed + 3027 + (FrameIndex + 1) x 1000003. The stream sequence is the row number.
| Argument | Description |
|---|---|
Seed |
Master seed. |
FrameIndex |
Frame counter. |
Returns: The init state for FAcresPcg32::Seed.
FAcresCameraModel::PrnuInitState#
PCG32 init state of the fixed PRNU map: Seed + 3027 (sequence PrnuSequenceBase + row).
FAcresCameraModel::ManifestJson#
Describes the model for episode.json "camera_model": settings, render geometry, gain, electrons per DN and plain-text notes on the pipeline, signal domain, rolling-shutter approximation and noise seeding.
FAcresCameraModel::RunSelfTest#
Runs synthetic checks and writes them to Dir.
Writes camera_selftest.json (intrinsics, flat-field levels with raw SHA-1 and timings, a 9 x 7 grid of geometry samples with and without a test motion), 128 x 128 raw DN crops raw_srgbNNN.u16 of six flat grey levels, and checker_motion.png. Triggered by -SensorCameraSelfTest; useful for checking the lens and sensor model after a change.
| Argument | Description |
|---|---|
Dir |
Output folder (created if missing). |
Returns: Empty string on success, otherwise an error message.
FAcresCameraModel::Config#
The validated settings in use.
FAcresCameraModel::ElectronsPerDn#
Electrons per ADC count at the current gain: full well at gain / (2^bits - 1 - black level).
FMotion#
Motion of the camera during readout, in the right-handed optical frame (x right, y down, z forward).
| Name | Type | Unit | Default | Description |
|---|---|---|---|---|
AngularRadps |
FVector |
rad/s | FVector::ZeroVector |
Camera angular velocity, rad/s. |
VelocityMps |
FVector |
m/s | FVector::ZeroVector |
Camera linear velocity, m/s. |