From 6d154bcdae6890a77a0374119464ee91ce533325 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 24 Mar 2020 11:29:50 +0100 Subject: [PATCH 1/4] Wavelet - Give possibility to use old algo SH residual image --- rtdata/languages/default | 2 ++ rtengine/ipwavelet.cc | 48 +++++++++++++++++++++++++++++++++++++++- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 +++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 42 +++++++++++++++++++++++++++++++++-- rtgui/wavelet.h | 7 ++++-- 8 files changed, 106 insertions(+), 5 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index fe6ddaa7c..3229e1015 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -802,6 +802,7 @@ HISTORY_MSG_WAVSIGMA;Sigma HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVUSHAMET;Clarity method +HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2243,6 +2244,7 @@ TP_WAVELET_NPLOW;Low TP_WAVELET_NPNONE;None TP_WAVELET_NPTYPE;Neighboring pixels TP_WAVELET_NPTYPE_TOOLTIP;This algorithm uses the proximity of a pixel and eight of its neighbors. If less difference, edges are reinforced. +TP_WAVELET_OLDSH;Old algorithm using negatives values TP_WAVELET_OPACITY;Opacity Blue-Yellow TP_WAVELET_OPACITYW;Contrast balance d/v-h curve TP_WAVELET_OPACITYWL;Final local contrast diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 758a9147b..54d103b7b 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -63,6 +63,7 @@ struct cont_params { float conresH; float radius; float chrores; + bool oldsh; float hueres; float sky; float b_l, t_l, b_r, t_r; @@ -387,6 +388,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.conresH = waparams.resconH; cp.radius = waparams.radius; cp.chrores = waparams.reschro; + cp.oldsh = waparams.oldsh; //cp.hueres=waparams.reshue; cp.hueres = 2.f; cp.th = float(waparams.thr); @@ -1689,7 +1691,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } - if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step + if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step LabImage *temp = nullptr; temp = new LabImage(W_L, H_L); #ifdef _OPENMP @@ -1721,6 +1723,50 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } + if((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step +#ifdef _OPENMP + #pragma omp for nowait +#endif + + for (int i = 0; i < W_L * H_L; i++) { + float LL = WavCoeffs_L0[i]; + float LL100 = LL / 327.68f; + float tran = 5.f;//transition + //shadow + float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? + + if(cp.th > (100.f - tran)) { + tran = 100.f - cp.th; + } + + if(LL100 < cp.th) { + float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th + float kk = aalp * LL100 + alp; + WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f); + } else if(LL100 < cp.th + tran) { + float ath = -cp.conres / tran; + float bth = cp.conres - ath * cp.th; + WavCoeffs_L0[i] *= (1.f + (LL100 * ath + bth) / 200.f); + } + + //highlight + tran = 5.f; + + if(cp.thH < (tran)) { + tran = cp.thH; + } + + if(LL100 > cp.thH) { + WavCoeffs_L0[i] *= (1.f + cp.conresH / 200.f); + } else if(LL100 > (cp.thH - tran)) { + float athH = cp.conresH / tran; + float bthH = cp.conresH - athH * cp.thH; + WavCoeffs_L0[i] *= (1.f + (LL100 * athH + bthH) / 200.f); + } + } + } + + #ifdef _OPENMP #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e795d9bd9..879423961 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2243,6 +2243,7 @@ WaveletParams::WaveletParams() : lipst(false), avoid(false), showmask(false), + oldsh(true), tmr(false), strength(100), balance(0), @@ -2343,6 +2344,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && lipst == other.lipst && avoid == other.avoid && showmask == other.showmask + && oldsh == other.oldsh && tmr == other.tmr && strength == other.strength && balance == other.balance @@ -3562,6 +3564,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.edgthresh, "Wavelet", "ThrEdg", wavelet.edgthresh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.avoid, "Wavelet", "AvoidColorShift", wavelet.avoid, keyFile); saveToKeyfile(!pedited || pedited->wavelet.showmask, "Wavelet", "Showmask", wavelet.showmask, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.oldsh, "Wavelet", "Oldsh", wavelet.oldsh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.tmr, "Wavelet", "TMr", wavelet.tmr, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigma, "Wavelet", "Sigma", wavelet.sigma, keyFile); saveToKeyfile(!pedited || pedited->wavelet.rescon, "Wavelet", "ResidualcontShadow", wavelet.rescon, keyFile); @@ -4654,6 +4657,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "Lipst", pedited, wavelet.lipst, pedited->wavelet.lipst); assignFromKeyfile(keyFile, "Wavelet", "AvoidColorShift", pedited, wavelet.avoid, pedited->wavelet.avoid); assignFromKeyfile(keyFile, "Wavelet", "Showmask", pedited, wavelet.showmask, pedited->wavelet.showmask); + assignFromKeyfile(keyFile, "Wavelet", "Oldsh", pedited, wavelet.oldsh, pedited->wavelet.oldsh); assignFromKeyfile(keyFile, "Wavelet", "TMr", pedited, wavelet.tmr, pedited->wavelet.tmr); if (ppVersion < 331) { // wavelet.Lmethod was a string before version 331 diff --git a/rtengine/procparams.h b/rtengine/procparams.h index aabe1e7ae..2eb18781d 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1211,6 +1211,7 @@ struct WaveletParams { bool lipst; bool avoid; bool showmask; + bool oldsh; bool tmr; int strength; int balance; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 48ba4c341..66a302f55 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -494,6 +494,7 @@ void ParamsEdited::set(bool v) wavelet.ushamethod = v; wavelet.avoid = v; wavelet.showmask = v; + wavelet.oldsh = v; wavelet.tmr = v; wavelet.Lmethod = v; wavelet.CLmethod = v; @@ -1090,6 +1091,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.ushamethod = wavelet.ushamethod && p.wavelet.ushamethod == other.wavelet.ushamethod; wavelet.avoid = wavelet.avoid && p.wavelet.avoid == other.wavelet.avoid; wavelet.showmask = wavelet.showmask && p.wavelet.showmask == other.wavelet.showmask; + wavelet.oldsh = wavelet.oldsh && p.wavelet.oldsh == other.wavelet.oldsh; wavelet.tmr = wavelet.tmr && p.wavelet.tmr == other.wavelet.tmr; wavelet.Lmethod = wavelet.Lmethod && p.wavelet.Lmethod == other.wavelet.Lmethod; wavelet.CLmethod = wavelet.CLmethod && p.wavelet.CLmethod == other.wavelet.CLmethod; @@ -2945,6 +2947,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.showmask = mods.wavelet.showmask; } + if (wavelet.oldsh) { + toEdit.wavelet.oldsh = mods.wavelet.oldsh; + } + if (wavelet.tmr) { toEdit.wavelet.tmr = mods.wavelet.tmr; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index d2707ec11..9e50031fb 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -508,6 +508,7 @@ struct WaveletParamsEdited { bool ushamethod; bool avoid; bool showmask; + bool oldsh; bool tmr; bool c[9]; bool ch[9]; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 7d9a65f2a..e314ee018 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -79,10 +79,11 @@ Wavelet::Wavelet() : avoid(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_AVOID")))), tmr(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_BALCHRO")))), showmask(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_SHOWMASK")))), + oldsh(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_OLDSH")))), neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.2, 2.5, 0.01, 1.))), - rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), 0, 100, 1, 0))), - resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), 0, 100, 1, 0))), + rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), -100, 100, 1, 0))), + resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), -100, 100, 1, 0))), reschro(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0))), tmrs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSTRENGTH"), -1.0, 2.0, 0.01, 0.0))), edgs(Gtk::manage(new Adjuster(M("TP_WAVELET_TMEDGS"), 0.1, 4.0, 0.01, 1.4))), @@ -175,6 +176,7 @@ Wavelet::Wavelet() : EvWavscale = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSCALE"); EvWavradius = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVRADIUS"); EvWavsigma = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSIGMA"); + EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -675,6 +677,9 @@ Wavelet::Wavelet() : // Residual Image ToolParamBlock* const resBox = Gtk::manage(new ToolParamBlock()); + oldsh->set_active(true); + oldshConn = oldsh->signal_toggled().connect(sigc::mem_fun(*this, &Wavelet::oldshToggled)); + resBox->pack_start(*oldsh); rescon->setAdjusterListener(this); resBox->pack_start(*rescon, Gtk::PACK_SHRINK); @@ -1200,6 +1205,9 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) showmaskConn.block(true); showmask->set_active(pp->wavelet.showmask); showmaskConn.block(false); + oldshConn.block(true); + oldsh->set_active(pp->wavelet.oldsh); + oldshConn.block(false); tmrConn.block(true); tmr->set_active(pp->wavelet.tmr); tmrConn.block(false); @@ -1230,6 +1238,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) lastlipst = pp->wavelet.lipst; lastavoid = pp->wavelet.avoid; lastshowmask = pp->wavelet.showmask; + lastoldsh = pp->wavelet.oldsh; lasttmr = pp->wavelet.tmr; sigma->setValue(pp->wavelet.sigma); rescon->setValue(pp->wavelet.rescon); @@ -1380,6 +1389,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) clshape->setUnChanged(!pedited->wavelet.wavclCurve); avoid->set_inconsistent(!pedited->wavelet.avoid); showmask->set_inconsistent(!pedited->wavelet.showmask); + oldsh->set_inconsistent(!pedited->wavelet.oldsh); tmr->set_inconsistent(!pedited->wavelet.tmr); edgthresh->setEditedState(pedited->wavelet.edgthresh ? Edited : UnEdited); rescon->setEditedState(pedited->wavelet.rescon ? Edited : UnEdited); @@ -1564,6 +1574,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.enabled = getEnabled(); pp->wavelet.avoid = avoid->get_active(); pp->wavelet.showmask = showmask->get_active(); + pp->wavelet.oldsh = oldsh->get_active(); pp->wavelet.tmr = tmr->get_active(); pp->wavelet.sigma = sigma->getValue(); pp->wavelet.rescon = rescon->getValue(); @@ -1654,6 +1665,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.enabled = !get_inconsistent(); pedited->wavelet.avoid = !avoid->get_inconsistent(); pedited->wavelet.showmask = !showmask->get_inconsistent(); + pedited->wavelet.oldsh = !oldsh->get_inconsistent(); pedited->wavelet.tmr = !tmr->get_inconsistent(); pedited->wavelet.median = !median->get_inconsistent(); pedited->wavelet.medianlev = !medianlev->get_inconsistent(); @@ -3120,6 +3132,32 @@ void Wavelet::showmaskToggled() } } +void Wavelet::oldshToggled() +{ + if (multiImage) { + if (oldsh->get_inconsistent()) { + oldsh->set_inconsistent(false); + oldshConn.block(true); + oldsh->set_active(false); + oldshConn.block(false); + } else if (lastoldsh) { + oldsh->set_inconsistent(true); + } + + lastoldsh = oldsh->get_active(); + } + + if (listener && (multiImage || getEnabled())) { + if (oldsh->get_inconsistent()) { + listener->panelChanged(EvWavoldsh, M("GENERAL_UNCHANGED")); + } else if (oldsh->get_active()) { + listener->panelChanged(EvWavoldsh, M("GENERAL_ENABLED")); + } else { + listener->panelChanged(EvWavoldsh, M("GENERAL_DISABLED")); + } + } +} + void Wavelet::tmrToggled() { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index d3b66657e..7aede083f 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -79,6 +79,7 @@ private: rtengine::ProcEvent EvWavscale; rtengine::ProcEvent EvWavradius; rtengine::ProcEvent EvWavsigma; + rtengine::ProcEvent EvWavoldsh; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -98,6 +99,7 @@ private: void TilesmethodChanged(); void avoidToggled(); void showmaskToggled (); + void oldshToggled (); void cbenabToggled(); void contrastMinusPressed(); void contrastPlusPressed(); @@ -166,6 +168,7 @@ private: Gtk::CheckButton* const avoid; Gtk::CheckButton* const tmr; Gtk::CheckButton* const showmask; + Gtk::CheckButton* const oldsh; Gtk::Button* const neutralchButton; Adjuster* correction[9]; @@ -281,13 +284,13 @@ private: sigc::connection enableChromaConn, enableContrastConn, enableEdgeConn, enableFinalConn, enableclariConn; sigc::connection enableNoiseConn, enableResidConn, enableToningConn; - sigc::connection medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn, showmaskConn; + sigc::connection medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn, showmaskConn, oldshConn; sigc::connection neutralPressedConn; sigc::connection contrastPlusPressedConn; sigc::connection contrastMinusPressedConn; sigc::connection neutralchPressedConn; - bool lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab, lastshowmask; + bool lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab, lastshowmask, lastoldsh; int nextnlevel; IdleRegister idle_register; From 60c341c236b0f20f298d0785eab2fe0b62268521 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 24 Mar 2020 11:30:31 +0100 Subject: [PATCH 2/4] Wavelet - more --- rtengine/ipwavelet.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 54d103b7b..a899f5a9a 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1722,6 +1722,9 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } +#ifdef _OPENMP + #pragma omp barrier +#endif if((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step #ifdef _OPENMP From 2bb747b55fd7acf320852ef08db8275d3efb10d7 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 24 Mar 2020 13:46:28 +0100 Subject: [PATCH 3/4] Wvalet - hide radius when old algo --- rtgui/wavelet.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index e314ee018..63eb7743e 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -3134,6 +3134,12 @@ void Wavelet::showmaskToggled() void Wavelet::oldshToggled() { + if (oldsh->get_active()) { + radius->hide(); + } else { + radius->show(); + } + if (multiImage) { if (oldsh->get_inconsistent()) { oldsh->set_inconsistent(false); From cdf8d8ec7f3741af1299b9d524a97bb69858404c Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 25 Mar 2020 07:15:27 +0100 Subject: [PATCH 4/4] Wavelet - added offset to contrast levels --- rtdata/languages/default | 2 ++ rtengine/ipwavelet.cc | 21 +++++++++++---------- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 8 +++++++- rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 14 ++++++++++++++ rtgui/wavelet.h | 2 ++ 8 files changed, 42 insertions(+), 11 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 3229e1015..f8cf543d6 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -803,6 +803,7 @@ HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_MSG_WAVOLDSH;Old algorithm +HISTORY_MSG_WAVOFFSET;Offset HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2293,6 +2294,7 @@ TP_WAVELET_USH;None TP_WAVELET_USHARP;Clarity method TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\nWavelet : the source file is the file including wavelet threatment TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. +TP_WAVELET_WAVOFFSET;Offset TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation TP_WBALANCE_AUTOOLD;Auto RGB grey diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index a899f5a9a..9177db0cc 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1691,7 +1691,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } } - if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step + if ((cp.conres >= 0.f || cp.conresH >= 0.f) && cp.resena && !cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step LabImage *temp = nullptr; temp = new LabImage(W_L, H_L); #ifdef _OPENMP @@ -2894,13 +2894,14 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz const float skinprot = params->wavelet.skinprotect; const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); + const float offs = params->wavelet.offset; //to adjust increase contrast with local contrast //for each pixel and each level float beta; float mea[9]; - float rap = mean[level] - 2.f * cp.sigm * sigma[level]; + float rap = offs * mean[level] - 2.f * cp.sigm * sigma[level]; if (rap > 0.f) { mea[0] = rap; @@ -2908,7 +2909,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz mea[0] = mean[level] / 6.f; } - rap = mean[level] - cp.sigm * sigma[level]; + rap = offs * mean[level] - cp.sigm * sigma[level]; if (rap > 0.f) { mea[1] = rap; @@ -2916,13 +2917,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz mea[1] = mean[level] / 2.f; } - mea[2] = mean[level]; // 50% data - mea[3] = mean[level] + cp.sigm * sigma[level] / 2.f; - mea[4] = mean[level] + cp.sigm * sigma[level]; //66% - mea[5] = mean[level] + cp.sigm * 1.2f * sigma[level]; - mea[6] = mean[level] + cp.sigm * 1.5f * sigma[level]; // - mea[7] = mean[level] + cp.sigm * 2.f * sigma[level]; //95% - mea[8] = mean[level] + cp.sigm * 2.5f * sigma[level]; //99% + mea[2] = offs * mean[level]; // 50% data + mea[3] = offs * mean[level] + cp.sigm * sigma[level] / 2.f; + mea[4] = offs * mean[level] + cp.sigm * sigma[level]; //66% + mea[5] = offs * mean[level] + cp.sigm * 1.2f * sigma[level]; + mea[6] = offs * mean[level] + cp.sigm * 1.5f * sigma[level]; // + mea[7] = offs * mean[level] + cp.sigm * 2.f * sigma[level]; //95% + mea[8] = offs * mean[level] + cp.sigm * 2.5f * sigma[level]; //99% bool useChromAndHue = (skinprot != 0.f || cp.HSmet); float modchro; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 879423961..96d2302c8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2274,6 +2274,7 @@ WaveletParams::WaveletParams() : Dirmethod("all"), HSmethod("with"), sigma(1.0), + offset(1.0), rescon(0), resconH(0), reschro(0), @@ -2382,6 +2383,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && Dirmethod == other.Dirmethod && HSmethod == other.HSmethod && sigma == other.sigma + && offset == other.offset && rescon == other.rescon && resconH == other.resconH && reschro == other.reschro @@ -3567,6 +3569,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.oldsh, "Wavelet", "Oldsh", wavelet.oldsh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.tmr, "Wavelet", "TMr", wavelet.tmr, keyFile); saveToKeyfile(!pedited || pedited->wavelet.sigma, "Wavelet", "Sigma", wavelet.sigma, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.offset, "Wavelet", "Offset", wavelet.offset, keyFile); saveToKeyfile(!pedited || pedited->wavelet.rescon, "Wavelet", "ResidualcontShadow", wavelet.rescon, keyFile); saveToKeyfile(!pedited || pedited->wavelet.resconH, "Wavelet", "ResidualcontHighlight", wavelet.resconH, keyFile); saveToKeyfile(!pedited || pedited->wavelet.thr, "Wavelet", "ThresholdResidShadow", wavelet.thr, keyFile); @@ -4687,6 +4690,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "HSMethod", pedited, wavelet.HSmethod, pedited->wavelet.HSmethod); assignFromKeyfile(keyFile, "Wavelet", "DirMethod", pedited, wavelet.Dirmethod, pedited->wavelet.Dirmethod); assignFromKeyfile(keyFile, "Wavelet", "Sigma", pedited, wavelet.sigma, pedited->wavelet.sigma); + assignFromKeyfile(keyFile, "Wavelet", "Offset", pedited, wavelet.offset, pedited->wavelet.offset); assignFromKeyfile(keyFile, "Wavelet", "ResidualcontShadow", pedited, wavelet.rescon, pedited->wavelet.rescon); assignFromKeyfile(keyFile, "Wavelet", "ResidualcontHighlight", pedited, wavelet.resconH, pedited->wavelet.resconH); assignFromKeyfile(keyFile, "Wavelet", "Residualchroma", pedited, wavelet.reschro, pedited->wavelet.reschro); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2eb18781d..feee0391a 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1243,6 +1243,7 @@ struct WaveletParams { Glib::ustring Dirmethod; Glib::ustring HSmethod; double sigma; + double offset; int rescon; int resconH; int reschro; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 66a302f55..d80d98361 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -510,7 +510,8 @@ void ParamsEdited::set(bool v) wavelet.HSmethod = v; wavelet.Dirmethod = v; wavelet.sigma = v; - wavelet.rescon = v; + wavelet.sigma = v; + wavelet.offset = v; wavelet.resconH = v; wavelet.reschro = v; wavelet.tmrs = v; @@ -1107,6 +1108,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.HSmethod = wavelet.HSmethod && p.wavelet.HSmethod == other.wavelet.HSmethod; wavelet.Dirmethod = wavelet.Dirmethod && p.wavelet.Dirmethod == other.wavelet.Dirmethod; wavelet.sigma = wavelet.sigma && p.wavelet.sigma == other.wavelet.sigma; + wavelet.offset = wavelet.offset && p.wavelet.offset == other.wavelet.offset; wavelet.rescon = wavelet.rescon && p.wavelet.rescon == other.wavelet.rescon; wavelet.resconH = wavelet.resconH && p.wavelet.resconH == other.wavelet.resconH; wavelet.reschro = wavelet.reschro && p.wavelet.reschro == other.wavelet.reschro; @@ -3168,6 +3170,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.sigma = mods.wavelet.sigma; } + if (wavelet.offset) { + toEdit.wavelet.offset = mods.wavelet.offset; + } + if (wavelet.resconH) { toEdit.wavelet.resconH = dontforceSet && options.baBehav[ADDSET_WA_RESCONH] ? toEdit.wavelet.resconH + mods.wavelet.resconH : mods.wavelet.resconH; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 9e50031fb..8cd8e25f0 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -526,6 +526,7 @@ struct WaveletParamsEdited { bool daubcoeffmethod; bool Dirmethod; bool sigma; + bool offset; bool rescon; bool resconH; bool reschro; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 63eb7743e..956c52738 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -82,6 +82,7 @@ Wavelet::Wavelet() : oldsh(Gtk::manage(new Gtk::CheckButton(M("TP_WAVELET_OLDSH")))), neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.2, 2.5, 0.01, 1.))), + offset(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVOFFSET"), 0.33, 1.66, 0.01, 1., Gtk::manage(new RTImage("circle-black-small.png")), Gtk::manage(new RTImage("circle-white-small.png"))))), rescon(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCON"), -100, 100, 1, 0))), resconH(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCONH"), -100, 100, 1, 0))), reschro(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0))), @@ -177,6 +178,7 @@ Wavelet::Wavelet() : EvWavradius = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVRADIUS"); EvWavsigma = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSIGMA"); EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); + EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); @@ -331,6 +333,8 @@ Wavelet::Wavelet() : sigma->setAdjusterListener(this); levBox->pack_start(*sigma, Gtk::PACK_SHRINK); + offset->setAdjusterListener(this); + levBox->pack_start(*offset, Gtk::PACK_SHRINK); levBox->pack_start(*sup); sup->setAdjusterListener(this); @@ -1241,6 +1245,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) lastoldsh = pp->wavelet.oldsh; lasttmr = pp->wavelet.tmr; sigma->setValue(pp->wavelet.sigma); + offset->setValue(pp->wavelet.offset); rescon->setValue(pp->wavelet.rescon); resconH->setValue(pp->wavelet.resconH); reschro->setValue(pp->wavelet.reschro); @@ -1394,6 +1399,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) edgthresh->setEditedState(pedited->wavelet.edgthresh ? Edited : UnEdited); rescon->setEditedState(pedited->wavelet.rescon ? Edited : UnEdited); sigma->setEditedState(pedited->wavelet.sigma ? Edited : UnEdited); + offset->setEditedState(pedited->wavelet.offset ? Edited : UnEdited); resconH->setEditedState(pedited->wavelet.resconH ? Edited : UnEdited); reschro->setEditedState(pedited->wavelet.reschro ? Edited : UnEdited); tmrs->setEditedState(pedited->wavelet.tmrs ? Edited : UnEdited); @@ -1577,6 +1583,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.oldsh = oldsh->get_active(); pp->wavelet.tmr = tmr->get_active(); pp->wavelet.sigma = sigma->getValue(); + pp->wavelet.offset = offset->getValue(); pp->wavelet.rescon = rescon->getValue(); pp->wavelet.resconH = resconH->getValue(); pp->wavelet.reschro = reschro->getValue(); @@ -1689,6 +1696,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.Dirmethod = Dirmethod->get_active_text() != M("GENERAL_UNCHANGED"); pedited->wavelet.edgthresh = edgthresh->getEditedState(); pedited->wavelet.sigma = sigma->getEditedState(); + pedited->wavelet.offset = offset->getEditedState(); pedited->wavelet.rescon = rescon->getEditedState(); pedited->wavelet.resconH = resconH->getEditedState(); pedited->wavelet.reschro = reschro->getEditedState(); @@ -1924,6 +1932,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit balance->setDefault(defParams->wavelet.balance); iter->setDefault(defParams->wavelet.iter); sigma->setDefault(defParams->wavelet.sigma); + offset->setDefault(defParams->wavelet.offset); rescon->setDefault(defParams->wavelet.rescon); resconH->setDefault(defParams->wavelet.resconH); reschro->setDefault(defParams->wavelet.reschro); @@ -1986,6 +1995,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited); sigma->setDefault(defParams->wavelet.sigma); + offset->setDefault(defParams->wavelet.offset); rescon->setDefault(defParams->wavelet.rescon); resconH->setDefault(defParams->wavelet.resconH); reschro->setDefault(defParams->wavelet.reschro); @@ -2037,6 +2047,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit } } else { sigma->setDefaultEditedState(Irrelevant); + offset->setDefaultEditedState(Irrelevant); rescon->setDefaultEditedState(Irrelevant); resconH->setDefaultEditedState(Irrelevant); reschro->setDefaultEditedState(Irrelevant); @@ -2565,6 +2576,7 @@ void Wavelet::setBatchMode(bool batchMode) curveEditorRES->setBatchMode(batchMode); curveEditorGAM->setBatchMode(batchMode); sigma->showEditedCB(); + offset->showEditedCB(); rescon->showEditedCB(); resconH->showEditedCB(); reschro->showEditedCB(); @@ -2648,6 +2660,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavrescon, rescon->getTextValue()); } else if (a == sigma) { listener->panelChanged(EvWavsigma, sigma->getTextValue()); + } else if (a == offset) { + listener->panelChanged(EvWavoffset, offset->getTextValue()); } else if (a == resconH) { listener->panelChanged(EvWavresconH, resconH->getTextValue()); } else if (a == reschro) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 7aede083f..94b88fd5c 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -80,6 +80,7 @@ private: rtengine::ProcEvent EvWavradius; rtengine::ProcEvent EvWavsigma; rtengine::ProcEvent EvWavoldsh; + rtengine::ProcEvent EvWavoffset; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -174,6 +175,7 @@ private: Adjuster* correction[9]; Adjuster* correctionch[9]; Adjuster* const sigma; + Adjuster* const offset; Adjuster* const rescon; Adjuster* const resconH; Adjuster* const reschro;