The relevant line of code.
zebra.c
int underexposed = ev_to_raw(- (raw_info.dynamic_range - 100) / 100.0);
I can change the code and produce wanted results (for myself), but I don't understand the maths, to make this a user adjustable feature, with accurate code.
Ideally, I would like options ranging from -6 EV through -11 EV, representing the EV from saturation. And add some
transparency, so that we can see the detail behind the zebras, and also represent the original SNR=1 EV shadow point with opaque zebras.
I am stuck on exactly what ev_to_raw is doing. I assume it is converting the EV to raw, but I don't understand the maths for this conversion.
int FAST ev_to_raw(float ev)
{
int raw_max = MIN(raw_info.white_level, 16383) - raw_info.black_level;
return raw_info.black_level + powf(2, ev) * raw_max;
}
raw_max, I understand. Minimum white level value, of either the reported white level, or 16383, minus black level.
But powf, is
well above my comprehension level. And if I place the maths into wolfram, like so.
2048 + powf(2, 11) * 15000
I get no useful result.
The next problem, I don't understand how raw_info.dynamic_range is being calculated.
raw_info.dynamic_range = compute_dynamic_range(black_mean, black_stdev_x100, raw_info.white_level)
There are 3 values in the brackets, but I don't understand what is being done with 3 values separated by commas.
edit: If I understand correctly, it is simply an EV?
static int compute_dynamic_range(int black_mean, int black_stdev_x100, int white_level)
{
/**
* A = full well capacity / read-out noise
* DR in dB = 20 log10(A)
* DR in stops = dB / 6 = log2(A)
* I guess noise level is the RMS value, which is identical to stdev
*
* This is quite close to DxO measurements (within +/- 0.5 EV),
* except at very high ISOs where there seems to be noise reduction applied to raw data
*/
#ifdef RAW_DEBUG_DR
int mean = black_mean * 100;
int stdev = black_stdev_x100;
bmp_printf(FONT_MED, 50, 100, "mean=%d.%02d stdev=%d.%02d white=%d", mean/100, mean%100, stdev/100, stdev%100, white_level);
white_level = autodetect_white_level(15000);
#endif
int dr = (int)roundf((log2f(white_level - black_mean) - log2f(black_stdev_x100 / 100.0)) * 100);
#ifdef RAW_DEBUG_DR
bmp_printf(FONT_MED, 50, 120, "=> dr=%d.%02d", dr/100, dr%100);
#endif
/* dual ISO enabled? */
dr += dual_iso_get_dr_improvement();
return dr;
}