diff --git a/rtdata/languages/default b/rtdata/languages/default index ec2e32d95..ad98e3e71 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -811,6 +811,7 @@ HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_WAVBL;Blur levels HISTORY_MSG_BLURWAV;Blur luminance HISTORY_MSG_BLURCWAV;Blur chroma +HISTORY_MSG_EDGEFFECT;Edge Effect HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot @@ -2205,6 +2206,8 @@ TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +TP_WAVELET_EDEFFECT;Effect +TP_WAVELET_EDEFFECT_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\nMaximum value (2.5) disabled the tool TP_WAVELET_EDGESENSI;Edge sensitivity TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. TP_WAVELET_EDGTHRESH;Detail diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index e7f6083e6..53f685826 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -82,6 +82,7 @@ struct cont_params { float b_lpast, t_lpast, b_rpast, t_rpast; float b_lsat, t_lsat, b_rsat, t_rsat; int rad; + float eff; int val; int til; int numlevH, numlevS; @@ -392,6 +393,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.rad = waparams.edgrad; cp.val = waparams.edgval; cp.til = waparams.edgthresh; + cp.eff = waparams.edgeffect; cp.conres = waparams.rescon; cp.conresH = waparams.resconH; @@ -2721,7 +2723,47 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz constexpr float aedstr = (eddstrength - 1.f) / 90.f; constexpr float bedstr = 1.f - 10.f * aedstr; + float mea[10]; + float beta = 1.f; + if(cp.eff < 2.5f) { + float effect = cp.eff; + float offs = 1.f; + + calceffect(level, mean, sigma, mea, effect, offs); + for (int co = 0; co < H_L * W_L; co++) { + float WavCL = std::fabs(WavCoeffs_L[dir][co]); + + if (WavCL < mea[0]) { + beta = 0.05f; + } else if (WavCL < mea[1]) { + beta = 0.2f; + } else if (WavCL < mea[2]) { + beta = 0.7f; + } else if (WavCL < mea[3]) { + beta = 1.f; //standard + } else if (WavCL < mea[4]) { + beta = 1.f; + } else if (WavCL < mea[5]) { + beta = 0.8f; //+sigma + } else if (WavCL < mea[6]) { + beta = 0.6f; + } else if (WavCL < mea[7]) { + beta = 0.4f; + } else if (WavCL < mea[8]) { + beta = 0.2f; // + 2 sigma + } else if (WavCL < mea[9]) { + beta = 0.1f; + } else { + beta = 0.0f; + } + + } + } + + if (cp.val > 0 && cp.edgeena) { + + float * koe = nullptr; float maxkoe = 0.f; @@ -2810,7 +2852,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz float atten01234 = 0.80f; value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!! } - + value *= beta; float edge = 1.f; float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi float lev = float (level); diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 66f2a4c19..ae5b6b465 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2312,6 +2312,7 @@ WaveletParams::WaveletParams() : edgeampli(10), contrast(0), edgrad(15), + edgeffect(1.0), edgval(0), edgthresh(10), thr(30), @@ -2428,6 +2429,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && edgeampli == other.edgeampli && contrast == other.contrast && edgrad == other.edgrad + && edgeffect == other.edgeffect && edgval == other.edgval && edgthresh == other.edgthresh && thr == other.thr @@ -3593,6 +3595,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.bluwav, "Wavelet", "bluwav", wavelet.bluwav, keyFile); saveToKeyfile(!pedited || pedited->wavelet.hueskin, "Wavelet", "Hueskin", wavelet.hueskin.toVector(), keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgrad, "Wavelet", "Edgrad", wavelet.edgrad, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.edgeffect, "Wavelet", "Edgeffect", wavelet.edgeffect, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgval, "Wavelet", "Edgval", wavelet.edgval, keyFile); saveToKeyfile(!pedited || pedited->wavelet.edgthresh, "Wavelet", "ThrEdg", wavelet.edgthresh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.avoid, "Wavelet", "AvoidColorShift", wavelet.avoid, keyFile); @@ -4749,6 +4752,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "ChromaLink", pedited, wavelet.chro, pedited->wavelet.chro); assignFromKeyfile(keyFile, "Wavelet", "Contrast", pedited, wavelet.contrast, pedited->wavelet.contrast); assignFromKeyfile(keyFile, "Wavelet", "Edgrad", pedited, wavelet.edgrad, pedited->wavelet.edgrad); + assignFromKeyfile(keyFile, "Wavelet", "Edgeffect", pedited, wavelet.edgeffect, pedited->wavelet.edgeffect); assignFromKeyfile(keyFile, "Wavelet", "Edgval", pedited, wavelet.edgval, pedited->wavelet.edgval); assignFromKeyfile(keyFile, "Wavelet", "ThrEdg", pedited, wavelet.edgthresh, pedited->wavelet.edgthresh); assignFromKeyfile(keyFile, "Wavelet", "ThresholdResidShadow", pedited, wavelet.thr, pedited->wavelet.thr); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 6dd5198ff..7174dfb3c 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1271,6 +1271,7 @@ struct WaveletParams { int edgeampli; int contrast; int edgrad; + double edgeffect; int edgval; int edgthresh; int thr; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0b06b9d92..87c405d42 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -535,6 +535,7 @@ void ParamsEdited::set(bool v) wavelet.chro = v; wavelet.contrast = v; wavelet.edgrad = v; + wavelet.edgeffect = v; wavelet.edgval = v; wavelet.edgthresh = v; wavelet.thr = v; @@ -1140,6 +1141,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.chro = wavelet.chro && p.wavelet.chro == other.wavelet.chro; wavelet.contrast = wavelet.contrast && p.wavelet.contrast == other.wavelet.contrast; wavelet.edgrad = wavelet.edgrad && p.wavelet.edgrad == other.wavelet.edgrad; + wavelet.edgeffect = wavelet.edgeffect && p.wavelet.edgeffect == other.wavelet.edgeffect; wavelet.edgval = wavelet.edgval && p.wavelet.edgval == other.wavelet.edgval; wavelet.edgthresh = wavelet.edgthresh && p.wavelet.edgthresh == other.wavelet.edgthresh; wavelet.thr = wavelet.thr && p.wavelet.thr == other.wavelet.thr; @@ -3212,6 +3214,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.resblur = mods.wavelet.resblur; } + if (wavelet.edgeffect) { + toEdit.wavelet.edgeffect = mods.wavelet.edgeffect; + } + if (wavelet.resblurc) { toEdit.wavelet.resblurc = mods.wavelet.resblurc; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0b315583d..f117163dd 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -551,6 +551,7 @@ struct WaveletParamsEdited { bool chroma; bool contrast; bool edgrad; + bool edgeffect; bool edgval; bool edgthresh; bool thr; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index afedf750c..89e05346a 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -90,7 +90,7 @@ Wavelet::Wavelet() : reschro(Gtk::manage(new Adjuster(M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0))), resblur(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLUR"), 0, 100, 1, 0))), resblurc(Gtk::manage(new Adjuster(M("TP_WAVELET_RESBLURC"), 0, 100, 1, 0))), - bluwav(Gtk::manage(new Adjuster(M("TP_WAVELET_BLUWAV"), 0.05, 2.5, 0.01, 1.))), + bluwav(Gtk::manage(new Adjuster(M("TP_WAVELET_BLUWAV"), 0.05, 2.5, 0.5, 50.))), 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))), scale(Gtk::manage(new Adjuster(M("TP_WAVELET_TMSCALE"), 0.1, 10.0, 0.01, 1.0))), @@ -106,6 +106,7 @@ Wavelet::Wavelet() : radius(Gtk::manage(new Adjuster(M("TP_WAVELET_RADIUS"), 0, 100, 1, 40))), skinprotect(Gtk::manage(new Adjuster(M("TP_WAVELET_SKIN"), -100, 100, 1, 0.))), edgrad(Gtk::manage(new Adjuster(M("TP_WAVELET_EDRAD"), 0, 100, 1, 15))), + edgeffect(Gtk::manage(new Adjuster(M("TP_WAVELET_EDEFFECT"), 0.05, 2.5, 0.01, 1.))), edgval(Gtk::manage(new Adjuster(M("TP_WAVELET_EDVAL"), 0, 100, 1, 0))), edgthresh(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGTHRESH"), -50, 100, 1, 10))), strength(Gtk::manage(new Adjuster(M("TP_WAVELET_STRENGTH"), 0, 100, 1, 100))), @@ -196,7 +197,7 @@ Wavelet::Wavelet() : EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE"); EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV"); EvWavresblurc = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURCWAV"); - + EvWavedgeffect = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_EDGEFFECT"); expsettings->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expsettings)); expcontrast->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Wavelet::foldAllButMe), expcontrast)); @@ -546,10 +547,14 @@ Wavelet::Wavelet() : // Edge Sharpness ToolParamBlock* const edgBox = Gtk::manage(new ToolParamBlock()); + edgeffect->setAdjusterListener(this); + edgBox->pack_start(*edgeffect); + edgeffect->set_tooltip_markup(M("TP_WAVELET_EDEFFECT_TOOLTIP")); edgval->setAdjusterListener(this); edgBox->pack_start(*edgval); + edgrad->setAdjusterListener(this); edgBox->pack_start(*edgrad); edgrad->set_tooltip_markup(M("TP_WAVELET_EDRAD_TOOLTIP")); @@ -1343,6 +1348,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) chro->setValue(pp->wavelet.chro); contrast->setValue(pp->wavelet.contrast); edgrad->setValue(pp->wavelet.edgrad); + edgeffect->setValue(pp->wavelet.edgeffect); edgval->setValue(pp->wavelet.edgval); edgthresh->setValue(pp->wavelet.edgthresh); thr->setValue(pp->wavelet.thr); @@ -1530,6 +1536,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) lipst->set_inconsistent(!pedited->wavelet.lipst); contrast->setEditedState(pedited->wavelet.contrast ? Edited : UnEdited); edgrad->setEditedState(pedited->wavelet.edgrad ? Edited : UnEdited); + edgeffect->setEditedState(pedited->wavelet.edgeffect ? Edited : UnEdited); edgval->setEditedState(pedited->wavelet.edgval ? Edited : UnEdited); thr->setEditedState(pedited->wavelet.thr ? Edited : UnEdited); thrH->setEditedState(pedited->wavelet.thrH ? Edited : UnEdited); @@ -1702,6 +1709,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.lipst = lipst->get_active(); pp->wavelet.contrast = contrast->getValue(); pp->wavelet.edgrad = edgrad->getValue(); + pp->wavelet.edgeffect = edgeffect->getValue(); pp->wavelet.edgval = edgval->getValue(); pp->wavelet.edgthresh = edgthresh->getValue(); pp->wavelet.thr = thr->getValue(); @@ -1823,6 +1831,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.chro = chro->getEditedState(); pedited->wavelet.contrast = contrast->getEditedState(); pedited->wavelet.edgrad = edgrad->getEditedState(); + pedited->wavelet.edgeffect = edgeffect->getEditedState(); pedited->wavelet.edgval = edgval->getEditedState(); pedited->wavelet.thr = thr->getEditedState(); pedited->wavelet.thrH = thrH->getEditedState(); @@ -2068,6 +2077,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit chro->setDefault(defParams->wavelet.chro); contrast->setDefault(defParams->wavelet.contrast); edgrad->setDefault(defParams->wavelet.edgrad); + edgeffect->setDefault(defParams->wavelet.edgeffect); edgval->setDefault(defParams->wavelet.edgval); edgthresh->setDefault(defParams->wavelet.edgthresh); thr->setDefault(defParams->wavelet.thr); @@ -2136,6 +2146,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit chro->setDefaultEditedState(pedited->wavelet.chro ? Edited : UnEdited); contrast->setDefaultEditedState(pedited->wavelet.contrast ? Edited : UnEdited); edgrad->setDefaultEditedState(pedited->wavelet.edgrad ? Edited : UnEdited); + edgeffect->setDefaultEditedState(pedited->wavelet.edgeffect ? Edited : UnEdited); edgval->setDefaultEditedState(pedited->wavelet.edgval ? Edited : UnEdited); edgthresh->setDefault(defParams->wavelet.edgthresh); thr->setDefaultEditedState(pedited->wavelet.thr ? Edited : UnEdited); @@ -2193,6 +2204,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit chro->setDefaultEditedState(Irrelevant); contrast->setDefaultEditedState(Irrelevant); edgrad->setDefaultEditedState(Irrelevant); + edgeffect->setDefaultEditedState(Irrelevant); edgval->setDefaultEditedState(Irrelevant); edgthresh->setDefaultEditedState(Irrelevant); thr->setDefaultEditedState(Irrelevant); @@ -2728,6 +2740,7 @@ void Wavelet::setBatchMode(bool batchMode) chro->showEditedCB(); contrast->showEditedCB(); edgrad->showEditedCB(); + edgeffect->showEditedCB(); edgval->showEditedCB(); edgthresh->showEditedCB(); thr->showEditedCB(); @@ -2856,6 +2869,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavedgeampli, edgeampli->getTextValue()); } else if (a == edgrad) { listener->panelChanged(EvWavedgrad, edgrad->getTextValue()); + } else if (a == edgeffect) { + listener->panelChanged(EvWavedgeffect, edgeffect->getTextValue()); } else if (a == edgval) { listener->panelChanged(EvWavedgval, edgval->getTextValue()); } else if (a == thres) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 609d3226c..b73339973 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -88,6 +88,7 @@ private: rtengine::ProcEvent EvWavblshape; rtengine::ProcEvent EvWavresblur; rtengine::ProcEvent EvWavresblurc; + rtengine::ProcEvent EvWavedgeffect; void foldAllButMe(GdkEventButton* event, MyExpander *expander); @@ -207,6 +208,7 @@ private: Adjuster* const radius; Adjuster* const skinprotect; Adjuster* const edgrad; + Adjuster* const edgeffect; Adjuster* const edgval; Adjuster* const edgthresh; Adjuster* const strength;