EVILS

Exploration of “Exposure Value Invariant Luminance Scaling” by Troy Sobotka

Source image

ClearAll["Global`*"]

(* Source: aces_gamut_mapping_vwg_test_images/m_smekal_A009C002_190210_R0EI.aces.exr in BT.709 *)
(* Mathematica's Gaussian resampling algorithm gives better results but to keep the file small we embed our own resized copy generated using Affinity Photo and a Bicubic filter. *)
(*image=ImageResize[Image[INSERT_IMAGE],Scaled[0.25],Resampling->"Gaussian"];*)
image =Image[];

Aesthetic curve

SiragusanoSmith[x_,contrast_,middleGreyIn_,middleGreyOut_,ev_]:=Block[
{
radiometricMax=2.0^ev*middleGreyIn,
inputScale=((radiometricMax*middleGreyIn)*(middleGreyOut^(1.0/contrast)-1.0))/(middleGreyIn-(radiometricMax*middleGreyOut^(1.0/contrast))),
outputScale=(radiometricMax/(radiometricMax+inputScale))^-contrast
},
outputScale*(x/(x+inputScale))^contrast
]

Manipulate[
LogLinearPlot[SiragusanoSmith[x,contrast,middleGreyIn,middleGreyOut,ev],{x,0.0001,2^ev*middleGreyIn},ImageSize->Large,PlotRange->{0.0, 1.1}],
{{contrast,1.2},1.0,2.0},
{{middleGreyIn,0.18},0.1,0.9},
{{middleGreyOut,0.18},0.1,0.9},
{{ev,5.5},1.0,20.0}
]

Exposure Value Invariant Luminance Scaling

luminance[x_]:=Dot[x,{0.2126729,0.7151521,0.0721750}]

EVILS[x_,l_]:=Block[
{maxChroma,maxChromaLuminance,maxReserves,maxReservesLuminance,luminanceDiff,luminanceDiffScalar,chromaScalar},
maxChroma=x/Max[x];
maxChromaLuminance=luminance[maxChroma];
maxReserves=1.0-maxChroma;
maxReservesLuminance=luminance[maxReserves];
luminanceDiff=Clip[l-maxChromaLuminance,{0.0001,256.0}];
luminanceDiffScalar=luminanceDiff/Clip[maxReservesLuminance,{0.0001,256.0}];
chromaScalar=(l-luminanceDiff)/maxChromaLuminance;
chromaScalar*maxChroma+luminanceDiffScalar*maxReserves
]

exposedEVILS[x_,contrast_,middleGreyIn_,middleGreyOut_,ev_]:= EVILS[x,SiragusanoSmith[luminance[x],contrast,middleGreyIn,middleGreyOut,ev]]

SetOptions[$FrontEnd,DynamicEvaluationTimeout->20]
Manipulate[
ImageApply[Clip[exposedEVILS[Clip[2.0^exposure*#,{0.00001,256.0}],contrast,middleGreyIn,middleGreyOut,ev],{0.0,1.0}]^(1/2.2)&,image],
{{exposure,0.0},-10.0,10.0},
{{contrast,1.2},1.0,2.0},
{{middleGreyIn,0.18},0.1,0.9},
{{middleGreyOut,0.18},0.1,0.9},
{{ev,5.5},1.0,20.0}
]