enhancements to Tone Mapping issue1714

This commit is contained in:
jdc
2015-04-18 06:49:34 +02:00
parent 0b6616e3c9
commit 23424a45c8
11 changed files with 409 additions and 364 deletions

View File

@@ -578,6 +578,7 @@ HISTORY_MSG_356;Wavelet edgedetect thresholdHi
HISTORY_MSG_357;Wavelet Denoise link
HISTORY_MSG_358;Wavelet Contrast Hue curve
HISTORY_MSG_359;Hot/Dead - Threshold
HISTORY_MSG_360;TM Gamma
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: <b>Alt-s</b>
HISTORY_SNAPSHOTS;Snapshots
@@ -1337,6 +1338,7 @@ TP_EPD_EDGESTOPPING;Edge stopping
TP_EPD_LABEL;Tone Mapping
TP_EPD_REWEIGHTINGITERATES;Reweighting iterates
TP_EPD_SCALE;Scale
TP_EPD_GAMMA;Gamma
TP_EPD_STRENGTH;Strength
TP_EPD_TOOLTIP;Tone mapping is possible via Lab mode (standard) and CIECAM02 mode.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)"
TP_EXPOSURE_AUTOLEVELS;Auto Levels

View File

@@ -761,8 +761,13 @@ SSEFUNCTION float *EdgePreservingDecomposition::CompressDynamicRange(float *Sour
if(Compressed == NULL) Compressed = u;
//Apply compression, detail boost, unlogging. Compression is done on the logged data and detail boost on unlogged.
float temp = CompressionExponent - 1.0f;
// float temp = CompressionExponent - 1.0f;
float temp;
if(DetailBoost>0.f) {
float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2)
temp = 1.2f*xlogf( -betemp);
}
else temp= CompressionExponent - 1.0f;
#ifdef __SSE2__
#ifdef _OPENMP
#pragma omp parallel

View File

@@ -5092,6 +5092,7 @@ if(!params->epd.enabled) return;
float stren=params->epd.strength;
float edgest=params->epd.edgeStopping;
float sca=params->epd.scale;
float gamm=params->epd.gamma;
float rew=params->epd.reweightingIterates;
unsigned int i, N = Wid*Hei;
float Qpro= ( 4.0 / c_) * ( a_w + 4.0 ) ;//estimate Q max if J=100.0
@@ -5106,7 +5107,7 @@ if(!params->epd.enabled) return;
#pragma omp parallel for
for (int i=0; i<Hei; i++)
for (int j=0; j<Wid; j++)
ncie->Q_p[i][j] = ncie->Q_p[i][j]/(Qpro);
ncie->Q_p[i][j] = gamm*ncie->Q_p[i][j]/(Qpro);
float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents.
float DetailBoost = stren;
@@ -5125,7 +5126,7 @@ if(!params->epd.enabled) return;
#endif
for (int i=0; i<Hei; i++)
for (int j=0; j<Wid; j++) {
ncie->Q_p[i][j]=ncie->Q_p[i][j]*Qpro;
ncie->Q_p[i][j]=(ncie->Q_p[i][j]*Qpro)/gamm;
ncie->M_p[i][j]*=s;
}
/*
@@ -5180,31 +5181,39 @@ if(!params->epd.enabled) return;
float stren=params->epd.strength;
float edgest=params->epd.edgeStopping;
float sca=params->epd.scale;
float gamm=params->epd.gamma;
float rew=params->epd.reweightingIterates;
//Pointers to whole data and size of it.
float *L = lab->L[0];
float *a = lab->a[0];
float *b = lab->b[0];
unsigned int i, N = lab->W*lab->H;
EdgePreservingDecomposition epd = EdgePreservingDecomposition(lab->W, lab->H);
//Due to the taking of logarithms, L must be nonnegative. Further, scale to 0 to 1 using nominal range of L, 0 to 15 bit.
float minL = FLT_MAX;
float maxL = 0.f;
#pragma omp parallel
{
float lminL = FLT_MAX;
float lmaxL = 0.f;
#pragma omp for
for(i = 0; i < N; i++)
for(i = 0; i < N; i++) {
if(L[i] < lminL) lminL = L[i];
if(L[i] > lmaxL) lmaxL = L[i];
}
#pragma omp critical
if(lminL < minL) minL = lminL;
if(lmaxL > maxL) maxL = lmaxL;
}
if(minL > 0.0f) minL = 0.0f; //Disable the shift if there are no negative numbers. I wish there were just no negative numbers to begin with.
#pragma omp parallel for
for(i = 0; i < N; i++)
L[i] = (L[i] - minL)/32767.0f;
//{L[i] = (L[i] - minL)/32767.0f;
{L[i] = (L[i] - minL)/maxL;
L[i]*=gamm;
}
//Some interpretations.
float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents.
float DetailBoost = stren;
@@ -5230,7 +5239,8 @@ fclose(f);*/
for(int ii = 0; ii < N; ii++)
a[ii] *= s,
b[ii] *= s,
L[ii] = L[ii]*32767.0f + minL;
//L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL;
L[ii] = L[ii]*maxL*(1.f/gamm) + minL;
}

View File

@@ -384,6 +384,8 @@ enum ProcEvent {
EvWavlinkedg=356,
EvWavCHCurve=357,
EvPreProcessHotDeadThresh=358,
EvEPDgamma=359,
NUMOFEVENTS
};
}

View File

@@ -845,7 +845,8 @@ void ProcParams::setDefaults () {
dirpyrDenoise.setDefaults();
epd.enabled = false;
epd.strength = 0.25;
epd.strength = 0.8;
epd.gamma = 1.0;
epd.edgeStopping = 1.4;
epd.scale = 1.0;
epd.reweightingIterates = 0;
@@ -1427,6 +1428,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
//Save epd.
if (!pedited || pedited->epd.enabled) keyFile.set_boolean ("EPD", "Enabled", epd.enabled);
if (!pedited || pedited->epd.strength) keyFile.set_double ("EPD", "Strength", epd.strength);
if (!pedited || pedited->epd.gamma) keyFile.set_double ("EPD", "Gamma", epd.gamma);
if (!pedited || pedited->epd.edgeStopping) keyFile.set_double ("EPD", "EdgeStopping", epd.edgeStopping);
if (!pedited || pedited->epd.scale) keyFile.set_double ("EPD", "Scale", epd.scale);
if (!pedited || pedited->epd.reweightingIterates) keyFile.set_integer ("EPD", "ReweightingIterates", epd.reweightingIterates);
@@ -2228,6 +2230,7 @@ if (keyFile.has_group ("Directional Pyramid Denoising")) {//TODO: No longer an a
if (keyFile.has_group ("EPD")) {
if(keyFile.has_key("EPD", "Enabled")) { epd.enabled = keyFile.get_boolean ("EPD", "Enabled"); if (pedited) pedited->epd.enabled = true; }
if(keyFile.has_key("EPD", "Strength")) { epd.strength = keyFile.get_double ("EPD", "Strength"); if (pedited) pedited->epd.strength = true; }
if(keyFile.has_key("EPD", "Gamma")) { epd.gamma = keyFile.get_double ("EPD", "Gamma"); if (pedited) pedited->epd.gamma = true; }
if(keyFile.has_key("EPD", "EdgeStopping")) { epd.edgeStopping = keyFile.get_double ("EPD", "EdgeStopping"); if (pedited) pedited->epd.edgeStopping = true; }
if(keyFile.has_key("EPD", "Scale")) { epd.scale = keyFile.get_double ("EPD", "Scale"); if (pedited) pedited->epd.scale = true; }
if(keyFile.has_key("EPD", "ReweightingIterates")) { epd.reweightingIterates = keyFile.get_integer ("EPD", "ReweightingIterates"); if (pedited) pedited->epd.reweightingIterates = true; }
@@ -2880,6 +2883,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& dirpyrDenoise.passes == other.dirpyrDenoise.passes
&& epd.enabled == other.epd.enabled
&& epd.strength == other.epd.strength
&& epd.gamma == other.epd.gamma
&& epd.edgeStopping == other.epd.edgeStopping
&& epd.scale == other.epd.scale
&& epd.reweightingIterates == other.epd.reweightingIterates

View File

@@ -588,6 +588,7 @@ class EPDParams{
public:
bool enabled;
double strength;
double gamma;
double edgeStopping;
double scale;
int reweightingIterates;

View File

@@ -380,6 +380,8 @@ DIRPYREQUALIZER, //EvWavedgedetectthr
DIRPYREQUALIZER, //EvWavedgedetectthr2
DIRPYREQUALIZER, //EvWavlinkedg
DIRPYREQUALIZER, //EvWavCHCurve
DARKFRAME //EvPreProcessHotDeadThresh
DARKFRAME, //EvPreProcessHotDeadThresh
SHARPENING //EvEPDgamma
};

View File

@@ -27,22 +27,26 @@ EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPa
setEnabledTooltipMarkup(M("TP_EPD_TOOLTIP"));
strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -2.0, 2.0, 0.01, 0.25));
strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.8));
gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.));
edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4));
scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 1.0));
reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0));
strength->setAdjusterListener(this);
gamma->setAdjusterListener(this);
edgeStopping->setAdjusterListener(this);
scale->setAdjusterListener(this);
reweightingIterates->setAdjusterListener(this);
strength->show();
gamma->show();
edgeStopping->show();
scale->show();
reweightingIterates->show();
pack_start(*strength);
pack_start(*gamma);
pack_start(*edgeStopping);
pack_start(*scale);
pack_start(*reweightingIterates);
@@ -53,6 +57,7 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite
if(pedited){
strength->setEditedState(pedited->epd.strength ? Edited : UnEdited);
gamma->setEditedState(pedited->epd.gamma ? Edited : UnEdited);
edgeStopping->setEditedState(pedited->epd.edgeStopping ? Edited : UnEdited);
scale->setEditedState(pedited->epd.scale ? Edited : UnEdited);
reweightingIterates->setEditedState(pedited->epd.reweightingIterates ? Edited : UnEdited);
@@ -62,6 +67,7 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite
setEnabled(pp->epd.enabled);
strength->setValue(pp->epd.strength);
gamma->setValue(pp->epd.gamma);
edgeStopping->setValue(pp->epd.edgeStopping);
scale->setValue(pp->epd.scale);
reweightingIterates->setValue(pp->epd.reweightingIterates);
@@ -71,6 +77,7 @@ void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdite
void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited){
pp->epd.strength = strength->getValue();
pp->epd.gamma = gamma->getValue();
pp->epd.edgeStopping = edgeStopping->getValue();
pp->epd.scale = scale->getValue();
pp->epd.reweightingIterates = reweightingIterates->getValue();
@@ -78,6 +85,7 @@ void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited)
if(pedited){
pedited->epd.strength = strength->getEditedState();
pedited->epd.gamma = gamma->getEditedState();
pedited->epd.edgeStopping = edgeStopping->getEditedState();
pedited->epd.scale = scale->getEditedState();
pedited->epd.reweightingIterates = reweightingIterates->getEditedState();
@@ -87,17 +95,20 @@ void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited)
void EdgePreservingDecompositionUI::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited){
strength->setDefault(defParams->epd.strength);
gamma->setDefault(defParams->epd.gamma);
edgeStopping->setDefault(defParams->epd.edgeStopping);
scale->setDefault(defParams->epd.scale);
reweightingIterates->setDefault(defParams->epd.reweightingIterates);
if(pedited){
strength->setDefaultEditedState(pedited->epd.strength ? Edited : UnEdited);
gamma->setDefaultEditedState(pedited->epd.gamma ? Edited : UnEdited);
edgeStopping->setDefaultEditedState(pedited->epd.edgeStopping ? Edited : UnEdited);
scale->setDefaultEditedState(pedited->epd.scale ? Edited : UnEdited);
reweightingIterates->setDefaultEditedState(pedited->epd.reweightingIterates ? Edited : UnEdited);
}else{
strength->setDefaultEditedState(Irrelevant);
gamma->setDefaultEditedState(Irrelevant);
edgeStopping->setDefaultEditedState(Irrelevant);
scale->setDefaultEditedState(Irrelevant);
reweightingIterates->setDefaultEditedState(Irrelevant);
@@ -108,6 +119,8 @@ void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval){
if(listener && getEnabled()){
if(a == strength)
listener->panelChanged(EvEPDStrength, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == gamma)
listener->panelChanged(EvEPDgamma, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == edgeStopping)
listener->panelChanged(EvEPDEdgeStopping, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == scale)
@@ -132,6 +145,7 @@ void EdgePreservingDecompositionUI::setBatchMode(bool batchMode){
ToolPanel::setBatchMode(batchMode);
strength->showEditedCB();
gamma->showEditedCB();
edgeStopping->showEditedCB();
scale->showEditedCB();
reweightingIterates->showEditedCB();

View File

@@ -26,6 +26,7 @@
class EdgePreservingDecompositionUI : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel {
protected:
Adjuster *strength;
Adjuster *gamma;
Adjuster *edgeStopping;
Adjuster *scale;
Adjuster *reweightingIterates;

View File

@@ -201,6 +201,7 @@ void ParamsEdited::set (bool v) {
dirpyrDenoise.rgbmethod = v;
epd.enabled = v;
epd.strength = v;
epd.gamma = v;
epd.edgeStopping = v;
epd.scale = v;
epd.reweightingIterates = v;
@@ -600,6 +601,7 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
epd.enabled = epd.enabled && p.epd.enabled == other.epd.enabled;
epd.strength = epd.strength && p.epd.strength == other.epd.strength;
epd.gamma = epd.gamma && p.epd.gamma == other.epd.gamma;
epd.edgeStopping = epd.edgeStopping && p.epd.edgeStopping == other.epd.edgeStopping;
epd.scale = epd.scale && p.epd.scale == other.epd.scale;
epd.reweightingIterates = epd.reweightingIterates && p.epd.reweightingIterates == other.epd.reweightingIterates;
@@ -999,6 +1001,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (epd.enabled) toEdit.epd.enabled = mods.epd.enabled;
if (epd.strength) toEdit.epd.strength = mods.epd.strength;
if (epd.gamma) toEdit.epd.gamma = mods.epd.gamma;
if (epd.edgeStopping) toEdit.epd.edgeStopping = mods.epd.edgeStopping;
if (epd.scale) toEdit.epd.scale = mods.epd.scale;
if (epd.reweightingIterates) toEdit.epd.reweightingIterates = mods.epd.reweightingIterates;

View File

@@ -291,6 +291,7 @@ class EPDParamsEdited{
public:
bool enabled;
bool strength;
bool gamma;
bool edgeStopping;
bool scale;
bool reweightingIterates;