![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
Functions | |
| ciecam16_J (L, Lw, La, surround) | |
| _sigmoid_scale (limit_x, limit_y, tx, ty, slope, power) | |
| curve_factory (black_ev, white_ev, contrast_param, latitude_pct, balance_pct, toe_power, shoulder_power, shoulder_slope_matched=False) | |
| main () | |
Variables | |
| float | GREY = 0.1845 |
| float | SAFETY_MARGIN = 0.01 |
| float | BLACK_TARGET = 0.01517634 / 100.0 |
| float | WHITE_TARGET = 1.0 |
Derive the default filmic RGB tone curve from an appearance match instead of taste.
Principle: the tone curve is the luminance mapping between two *known* viewing
states, so its default is a solvable problem, not an opinion:
scene state : diffuse white ~1000 cd/m2 outdoors, observer adapted to it,
average surround, no flare (the scene is the reference);
display state : SDR monitor ~100 cd/m2 white, dim surround, veiling flare
0.1% of white (demanding viewing : dim room, good display —
office-flare fits crush near-blacks, see --flare help).
For each scene exposure (EV around mid-gray) we compute the perceived lightness
J under the scene state with CIECAM16 (achromatic path), then ask which display
luminance produces the same J under the display state — flare included. The
unconstrained match cannot fit the display range, so we least-squares the
filmic curve family onto it with two weights:
- a content-mass prior (where photographs hold detail), and
- a JND-visibility smoothness term: the rendering may not introduce
perceptual-lightness curvature (d2J/dEV2) sharper than the appearance
match itself contains anywhere. Without it the toe/shoulder powers rail
("hold the match, clip hard") because errors at extreme EVs are cheap.
The curve model below replicates the C v3 geometry EXACTLY
(filmic_v3_compute_geometry / _nodes_from_legacy + the spline v4 sigmoid
segments), so the fitted parameters are directly the module's user parameters.
In particular the user 'contrast' is normalized by DR/8 and gamma-compensated,
as in the C code.
Usage:
python3.12 tools/derive_filmic_default_curve.py
... --scene-white 5000 --display-white 200 --flare 0.01 # variants
Changing shipped defaults from these numbers is a product decision:
run, look, then decide.
|
protected |
Definition at line 72 of file derive_filmic_default_curve.py.
Referenced by curve_factory().
| derive_filmic_default_curve.ciecam16_J | ( | L, | |
| Lw, | |||
| La, | |||
| surround | |||
| ) |
Perceived lightness J of an achromatic stimulus of luminance L (cd/m2) seen against a ~20% background under a white of Lw, adaptation La.
Definition at line 51 of file derive_filmic_default_curve.py.
Referenced by main().
| derive_filmic_default_curve.curve_factory | ( | black_ev, | |
| white_ev, | |||
| contrast_param, | |||
| latitude_pct, | |||
| balance_pct, | |||
| toe_power, | |||
| shoulder_power, | |||
shoulder_slope_matched = False |
|||
| ) |
Returns curve(x): normalized log input -> display-linear output. Parameters are the module's user parameters, v3 geometry, perceptual sigmoid. shoulder_slope_matched=True reproduces the shipped 'perceptual' shoulder : a slope-matched power roll-off (exponent = slope*dx/dy, ignores shoulder_power), matching filmic_rgb_compute_spline in the C code.
Definition at line 78 of file derive_filmic_default_curve.py.
References _sigmoid_scale(), max, and min.
| derive_filmic_default_curve.main | ( | ) |
Definition at line 156 of file derive_filmic_default_curve.py.
References ciecam16_J(), and main().
Referenced by main().
| float derive_filmic_default_curve.BLACK_TARGET = 0.01517634 / 100.0 |
Definition at line 46 of file derive_filmic_default_curve.py.
| float derive_filmic_default_curve.GREY = 0.1845 |
Definition at line 44 of file derive_filmic_default_curve.py.
| float derive_filmic_default_curve.SAFETY_MARGIN = 0.01 |
Definition at line 45 of file derive_filmic_default_curve.py.
| float derive_filmic_default_curve.WHITE_TARGET = 1.0 |
Definition at line 47 of file derive_filmic_default_curve.py.