From 0fa2ca79c2c347bd92d47d7174fd824c4f00a8de Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 30 Mar 2020 08:54:26 +0200 Subject: [PATCH 1/3] Improvment contrast to prevent texture and noise --- rtdata/languages/default | 3 ++ rtengine/ipwavelet.cc | 67 ++++++++++++++++++++++++++++------------ rtengine/procparams.cc | 4 +++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 ++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 15 +++++++++ rtgui/wavelet.h | 2 ++ 8 files changed, 80 insertions(+), 19 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index d4fb356e0..4a419e736 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -806,6 +806,7 @@ HISTORY_MSG_THRESWAV;Balance threshold HISTORY_MSG_BLUWAV;Maximum blur HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOFFSET;Offset +HISTORY_MSG_WAVLOWTHR;Threshold low contrast HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_WAVBL;Blur levels HISTORY_MSG_BLURWAV;Blur luminance @@ -2242,6 +2243,7 @@ TP_WAVELET_LEVZERO;Level 1 TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength TP_WAVELET_LIPST;Enhanced algoritm TP_WAVELET_LOWLIGHT;Shadow luminance range +TP_WAVELET_LOWTHR_TOOLTIP;Prevents amplification of fine textures and noise TP_WAVELET_MEDGREINF;First level TP_WAVELET_MEDI;Reduce artifacts in blue sky TP_WAVELET_MEDILEV;Edge detection @@ -2312,6 +2314,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_WAVLOWTHR;Low contrast threshold TP_WAVELET_WAVOFFSET;Offset TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\n High values will amplify the contrast enhancement of the highlights, while low values will amplify the contrast enhancement of the shadows. Along with a low Max. effect value will help you selecting the contrasts that will be enhanced TP_WBALANCE_AUTO;Auto diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 8c15f51c5..d5b642aaa 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -3002,39 +3002,66 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz const float skinprotneg = -skinprot; const float factorHard = (1.f - skinprotneg / 100.f); const float offs = params->wavelet.offset; + const float lowthr = params->wavelet.lowthr; //to adjust increase contrast with local contrast //for each pixel and each level float beta; - float mea[9]; - float rap = offs * mean[level] - 2.f * cp.sigm * sigma[level]; + float mea[10]; + float rap = 0.f; + float sig = 1.f; + if(cp.sigm < 1.f) { + sig = cp.sigm; + } + if(cp.sigm <= 1.f) { + rap = offs * mean[level] - sig * sigma[level]; + } + if (rap > 0.f) { mea[0] = rap; } else { mea[0] = mean[level] / 6.f; } - rap = offs * mean[level] - cp.sigm * sigma[level]; + rap = 0.f; + if(cp.sigm <= 1.f) { + rap = offs * mean[level] - 0.5f * sig * sigma[level]; + } if (rap > 0.f) { mea[1] = rap; } else { - mea[1] = mean[level] / 2.f; + mea[1] = mean[level] / 4.f; + } + + rap = 0.f; + if(cp.sigm <= 1.f) { + rap = offs * mean[level] - 0.2f * sig * sigma[level]; } - 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% + if (rap > 0.f) { + mea[2] = rap; + } else { + mea[2] = mean[level] / 2.f; + } + + mea[3] = offs * mean[level]; // 50% data + mea[4] = offs * mean[level] + cp.sigm * sigma[level] / 2.f; + mea[5] = offs * mean[level] + cp.sigm * sigma[level]; //66% + mea[6] = offs * mean[level] + cp.sigm * 1.2f * sigma[level]; + mea[7] = offs * mean[level] + cp.sigm * 1.5f * sigma[level]; // + mea[8] = offs * mean[level] + cp.sigm * 2.f * sigma[level]; //95% + mea[9] = offs * mean[level] + cp.sigm * 2.5f * sigma[level]; //99% bool useChromAndHue = (skinprot != 0.f || cp.HSmet); float modchro; + float red0 = 0.005f * (110.f - lowthr); + float red1 = 0.008f * (110.f - lowthr); + float red2 = 0.011f * (110.f - lowthr); + for (int i = 0; i < W_L * H_L; i++) { float kLlev = 1.f; @@ -3046,22 +3073,24 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz //reduction amplification: max action between mean / 2 and mean + sigma // arbitrary coefficient, we can add a slider !! if (WavCL < mea[0]) { - beta = 0.6f; //preserve very low contrast (sky...) + beta = 0.4f * red0;//preserve very low contrast (sky...) } else if (WavCL < mea[1]) { - beta = 0.8f; + beta = 0.5f * red1; } else if (WavCL < mea[2]) { - beta = 1.f; //standard + beta = 0.7f * red2; } else if (WavCL < mea[3]) { - beta = 1.f; + beta = 1.f; //standard } else if (WavCL < mea[4]) { - beta = 0.8f; //+sigma + beta = 1.f; } else if (WavCL < mea[5]) { - beta = 0.6f; + beta = 0.8f; //+sigma } else if (WavCL < mea[6]) { - beta = 0.4f; + beta = 0.6f; } else if (WavCL < mea[7]) { - beta = 0.2f; // + 2 sigma + 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; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 20ae540f5..66f2a4c19 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2288,6 +2288,7 @@ WaveletParams::WaveletParams() : HSmethod("with"), sigma(1.0), offset(1.0), + lowthr(40.0), rescon(0), resconH(0), reschro(0), @@ -2403,6 +2404,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && HSmethod == other.HSmethod && sigma == other.sigma && offset == other.offset + && lowthr == other.lowthr && rescon == other.rescon && resconH == other.resconH && reschro == other.reschro @@ -3599,6 +3601,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo 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.lowthr, "Wavelet", "Lowthr", wavelet.lowthr, 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); @@ -4722,6 +4725,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) 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", "Lowthr", pedited, wavelet.lowthr, pedited->wavelet.lowthr); 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 8ca3e5c29..6dd5198ff 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1247,6 +1247,7 @@ struct WaveletParams { Glib::ustring HSmethod; double sigma; double offset; + double lowthr; int rescon; int resconH; int reschro; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index b3c2b64d7..0b06b9d92 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -512,6 +512,7 @@ void ParamsEdited::set(bool v) wavelet.sigma = v; wavelet.sigma = v; wavelet.offset = v; + wavelet.lowthr = v; wavelet.resconH = v; wavelet.reschro = v; wavelet.resblur = v; @@ -1115,6 +1116,7 @@ void ParamsEdited::initFrom(const std::vector& 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.lowthr = wavelet.lowthr && p.wavelet.lowthr == other.wavelet.lowthr; 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; @@ -3202,6 +3204,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.offset = mods.wavelet.offset; } + if (wavelet.lowthr) { + toEdit.wavelet.lowthr = mods.wavelet.lowthr; + } + if (wavelet.resblur) { toEdit.wavelet.resblur = mods.wavelet.resblur; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 43254b015..0b315583d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -527,6 +527,7 @@ struct WaveletParamsEdited { bool Dirmethod; bool sigma; bool offset; + bool lowthr; bool rescon; bool resconH; bool reschro; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 2e444ff3d..b23143c6c 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -84,6 +84,7 @@ Wavelet::Wavelet() : neutralchButton(Gtk::manage(new Gtk::Button(M("TP_WAVELET_NEUTRAL")))), sigma(Gtk::manage(new Adjuster(M("TP_WAVELET_SIGMA"), 0.05, 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"))))), + lowthr(Gtk::manage(new Adjuster(M("TP_WAVELET_WAVLOWTHR"), 20., 100., 0.5, 40.))), 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))), @@ -190,6 +191,7 @@ Wavelet::Wavelet() : EvWavchrwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_chrwav"); EvWavoldsh = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOLDSH"); EvWavoffset = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVOFFSET"); + EvWavlowthr = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVLOWTHR"); EvWavbluwav = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLUWAV"); EvWavblshape = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLSHAPE"); EvWavresblur = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_BLURWAV"); @@ -359,6 +361,9 @@ Wavelet::Wavelet() : levBox->pack_start(*offset, Gtk::PACK_SHRINK); sigma->set_tooltip_text(M("TP_WAVELET_SIGMA_TOOLTIP")); offset->set_tooltip_text(M("TP_WAVELET_OFFSET_TOOLTIP")); + lowthr->setAdjusterListener(this); + lowthr->set_tooltip_text(M("TP_WAVELET_LOWTHR_TOOLTIP")); + levBox->pack_start(*lowthr, Gtk::PACK_SHRINK); wavLabels->show(); levBox->pack_start(*wavLabels); @@ -1321,6 +1326,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) lasttmr = pp->wavelet.tmr; sigma->setValue(pp->wavelet.sigma); offset->setValue(pp->wavelet.offset); + lowthr->setValue(pp->wavelet.lowthr); rescon->setValue(pp->wavelet.rescon); resconH->setValue(pp->wavelet.resconH); reschro->setValue(pp->wavelet.reschro); @@ -1481,6 +1487,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) rescon->setEditedState(pedited->wavelet.rescon ? Edited : UnEdited); sigma->setEditedState(pedited->wavelet.sigma ? Edited : UnEdited); offset->setEditedState(pedited->wavelet.offset ? Edited : UnEdited); + lowthr->setEditedState(pedited->wavelet.lowthr ? Edited : UnEdited); resconH->setEditedState(pedited->wavelet.resconH ? Edited : UnEdited); reschro->setEditedState(pedited->wavelet.reschro ? Edited : UnEdited); resblur->setEditedState(pedited->wavelet.resblur ? Edited : UnEdited); @@ -1672,6 +1679,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.tmr = tmr->get_active(); pp->wavelet.sigma = sigma->getValue(); pp->wavelet.offset = offset->getValue(); + pp->wavelet.lowthr = lowthr->getValue(); pp->wavelet.rescon = rescon->getValue(); pp->wavelet.resconH = resconH->getValue(); pp->wavelet.reschro = reschro->getValue(); @@ -1791,6 +1799,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.edgthresh = edgthresh->getEditedState(); pedited->wavelet.sigma = sigma->getEditedState(); pedited->wavelet.offset = offset->getEditedState(); + pedited->wavelet.lowthr = lowthr->getEditedState(); pedited->wavelet.rescon = rescon->getEditedState(); pedited->wavelet.resconH = resconH->getEditedState(); pedited->wavelet.reschro = reschro->getEditedState(); @@ -2035,6 +2044,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit iter->setDefault(defParams->wavelet.iter); sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); + lowthr->setDefault(defParams->wavelet.lowthr); rescon->setDefault(defParams->wavelet.rescon); resconH->setDefault(defParams->wavelet.resconH); reschro->setDefault(defParams->wavelet.reschro); @@ -2102,6 +2112,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit sigma->setDefault(defParams->wavelet.sigma); offset->setDefault(defParams->wavelet.offset); + lowthr->setDefault(defParams->wavelet.lowthr); rescon->setDefault(defParams->wavelet.rescon); resconH->setDefault(defParams->wavelet.resconH); reschro->setDefault(defParams->wavelet.reschro); @@ -2158,6 +2169,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit } else { sigma->setDefaultEditedState(Irrelevant); offset->setDefaultEditedState(Irrelevant); + lowthr->setDefaultEditedState(Irrelevant); rescon->setDefaultEditedState(Irrelevant); resconH->setDefaultEditedState(Irrelevant); reschro->setDefaultEditedState(Irrelevant); @@ -2692,6 +2704,7 @@ void Wavelet::setBatchMode(bool batchMode) curveEditorGAM->setBatchMode(batchMode); sigma->showEditedCB(); offset->showEditedCB(); + lowthr->showEditedCB(); rescon->showEditedCB(); resconH->showEditedCB(); reschro->showEditedCB(); @@ -2781,6 +2794,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavsigma, sigma->getTextValue()); } else if (a == offset) { listener->panelChanged(EvWavoffset, offset->getTextValue()); + } else if (a == lowthr) { + listener->panelChanged(EvWavlowthr, lowthr->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 67a45b5ac..609d3226c 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -83,6 +83,7 @@ private: rtengine::ProcEvent EvWavchrwav; rtengine::ProcEvent EvWavoldsh; rtengine::ProcEvent EvWavoffset; + rtengine::ProcEvent EvWavlowthr; rtengine::ProcEvent EvWavbluwav; rtengine::ProcEvent EvWavblshape; rtengine::ProcEvent EvWavresblur; @@ -184,6 +185,7 @@ private: Adjuster* correctionch[9]; Adjuster* const sigma; Adjuster* const offset; + Adjuster* const lowthr; Adjuster* const rescon; Adjuster* const resconH; Adjuster* const reschro; From 5102c82c11a5f2d46972602857dc89bff78ca3e3 Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 31 Mar 2020 10:04:16 +0200 Subject: [PATCH 2/3] Improve blur with effect --- rtdata/languages/default | 4 +- rtengine/improcfun.h | 4 +- rtengine/ipwavelet.cc | 205 +++++++++++++++++++++++++++------------ rtgui/wavelet.cc | 2 +- 4 files changed, 150 insertions(+), 65 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 4a419e736..ec2e32d95 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -803,7 +803,7 @@ HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_MSG_THRESWAV;Balance threshold -HISTORY_MSG_BLUWAV;Maximum blur +HISTORY_MSG_BLUWAV;Effects HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOFFSET;Offset HISTORY_MSG_WAVLOWTHR;Threshold low contrast @@ -2146,7 +2146,7 @@ TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method TP_WAVELET_BLCURVE;Blur by levels TP_WAVELET_BLURFRAME;Blur -TP_WAVELET_BLUWAV;Maximum Blur +TP_WAVELET_BLUWAV;Effects TP_WAVELET_CBENAB;Toning and Color Balance TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted TP_WAVELET_CCURVE;Local contrast diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 424084b8c..affa33640 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -208,7 +208,7 @@ public: struct cont_params &cp, int skip, float *mean, float *sigma, float *MaxP, float *MaxN, const WavCurve & wavCLVCcurve, const WavOpacityCurveW & waOpacityCurveW, FlatCurve* ChCurve, bool Chutili); void WaveletcontAllLfinal(const wavelet_decomposition &WaveletCoeffs_L, const cont_params &cp, float *mean, float *sigma, float *MaxP, const WavOpacityCurveWL & waOpacityCurveWL); void WaveletcontAllAB(LabImage * lab, float **varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_a, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA, int skip); + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab); void WaveletAandBAllAB(const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, const cont_params &cp, FlatCurve* hhcurve, bool hhutili); void ContAllL(float **koeLi, float *maxkoeLi, bool lipschitz, int maxlvl, LabImage * lab, float **varhue, float **varchrom, float ** WavCoeffs_L, float * WavCoeffs_L0, int level, int dir, struct cont_params &cp, @@ -222,6 +222,8 @@ public: void Eval2(float ** WavCoeffs_L, int level, int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN); + void calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs); + void Aver(float * HH_Coeffs, int datalen, float &averagePlus, float &averageNeg, float &max, float &min); void Sigma(float * HH_Coeffs, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg); void calckoe(float ** WavCoeffs_LL, const cont_params& cp, float ** koeLi, int level, int dir, int W_L, int H_L, float edd, float *maxkoeLi, float **tmC = nullptr); diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index d5b642aaa..e7f6083e6 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -400,7 +400,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.oldsh = waparams.oldsh; cp.blurres = waparams.resblur; cp.blurcres = waparams.resblurc; - cp.bluwav = 0.01f * waparams.bluwav; + cp.bluwav = waparams.bluwav; //cp.hueres=waparams.reshue; cp.hueres = 2.f; cp.th = float(waparams.thr); @@ -643,6 +643,13 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float MaxP[10]; float MaxN[10]; + float meanab[10]; + float meanNab[10]; + float sigmaab[10]; + float sigmaNab[10]; + float MaxPab[10]; + float MaxNab[10]; + array2D varchro(tilewidth, tileheight); float** varhue = new float*[tileheight]; @@ -924,7 +931,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip); + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); adecomp->reconstruct(labco->data + datalen, cp.strength); } } @@ -941,7 +949,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); } } @@ -959,8 +968,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - WaveletcontAllAB(labco, varhue, varchro, *adecomp,wavblcurve, waOpacityCurveW, cp, true, skip); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip); + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp,wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); adecomp->reconstruct(labco->data + datalen, cp.strength); @@ -1227,6 +1238,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } + void ImProcFunctions::Aver(float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) { @@ -1333,6 +1345,56 @@ void ImProcFunctions::Evaluate2(const wavelet_decomposition &WaveletCoeffs_L, } } + +void ImProcFunctions::calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs) +{ + float rap = 0.f; + float sig = 1.f; + if(effect < 1.f) { + sig = effect; + } + + if(effect <= 1.f) { + rap = offs * mean[level] - sig * sigma[level]; + } + + if (rap > 0.f) { + mea[0] = rap; + } else { + mea[0] = mean[level] / 6.f; + } + + rap = 0.f; + if(effect <= 1.f) { + rap = offs * mean[level] - 0.5f * sig * sigma[level]; + } + + if (rap > 0.f) { + mea[1] = rap; + } else { + mea[1] = mean[level] / 4.f; + } + + rap = 0.f; + if(effect <= 1.f) { + rap = offs * mean[level] - 0.2f * sig * sigma[level]; + } + + if (rap > 0.f) { + mea[2] = rap; + } else { + mea[2] = mean[level] / 2.f; + } + + mea[3] = offs * mean[level]; // 50% data + mea[4] = offs * mean[level] + effect * sigma[level] / 2.f; + mea[5] = offs * mean[level] + effect * sigma[level]; //66% + mea[6] = offs * mean[level] + effect * 1.2f * sigma[level]; + mea[7] = offs * mean[level] + effect * 1.5f * sigma[level]; // + mea[8] = offs * mean[level] + effect * 2.f * sigma[level]; //95% + mea[9] = offs * mean[level] + effect * 2.5f * sigma[level]; //99% +} + void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level, int W_L, int H_L, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN) { @@ -1953,20 +2015,53 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); //blur level float klev = 1.f; - if(wavblcurve && wavcurvecomp && cp.blena && cp.bluwav > 0.f) { + if(wavblcurve && wavcurvecomp && cp.blena) { + float mea[10]; + float effect = cp.bluwav; + float beta = 0.f; + float offs = 1.f; + + calceffect(lvl, mean, sigma, mea, effect, offs); float * bef = new float[Wlvl_L * Hlvl_L]; float * aft = new float[Wlvl_L * Hlvl_L]; for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { - bef[co] = WavCoeffs_L[dir][co]; + bef[co] = WavCoeffs_L[dir][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; + } + + } klev = (wavblcurve[lvl * 55.5f]); float lvr = lvl; if(lvr == 0) { lvr = 1; } - klev *= cp.bluwav * lvr * 10.f / skip; + klev *= beta * lvr * 100.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { @@ -2053,7 +2148,7 @@ void ImProcFunctions::WaveletAandBAllAB(const wavelet_decomposition &WaveletCoef } void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, const wavelet_decomposition &WaveletCoeffs_ab, const Wavblcurve & wavblcurve, const WavOpacityCurveW & waOpacityCurveW, - struct cont_params &cp, const bool useChannelA, int skip) + struct cont_params &cp, const bool useChannelA, int skip, float *meanab, float *sigmaab) { int maxlvl = WaveletCoeffs_ab.maxlevel(); @@ -2219,20 +2314,54 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); - if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f && cp.bluwav > 0.f) { + if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + float mea[10]; + float effect = cp.bluwav; + float beta = 0.f; + float offs = 1.f; + + calceffect(lvl, meanab, sigmaab, mea, effect, offs); + float * bef = new float[Wlvl_ab * Hlvl_ab]; float * aft = new float[Wlvl_ab * Hlvl_ab]; float klev; for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { bef[co] = WavCoeffs_ab[dir][co]; + float WavCab = std::fabs(WavCoeffs_ab[dir][co]); + + if (WavCab < mea[0]) { + beta = 0.05f; + } else if (WavCab < mea[1]) { + beta = 0.2f; + } else if (WavCab < mea[2]) { + beta = 0.7f; + } else if (WavCab < mea[3]) { + beta = 1.f; //standard + } else if (WavCab < mea[4]) { + beta = 1.f; + } else if (WavCab < mea[5]) { + beta = 0.8f; //+sigma + } else if (WavCab < mea[6]) { + beta = 0.6f; + } else if (WavCab < mea[7]) { + beta = 0.4f; + } else if (WavCab < mea[8]) { + beta = 0.2f; // + 2 sigma + } else if (WavCab < mea[9]) { + beta = 0.1f; + } else { + beta = 0.0f; + } + + } klev = (wavblcurve[lvl * 55.5f]); float lvr = lvl; if(lvr == 0) { lvr = 1; } - - klev *= cp.bluwav * cp.chrwav * lvr * 20.f / skip; + + klev *= beta * cp.chrwav * lvr * 200.f / skip; boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); @@ -3003,57 +3132,11 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz const float factorHard = (1.f - skinprotneg / 100.f); const float offs = params->wavelet.offset; const float lowthr = params->wavelet.lowthr; - - //to adjust increase contrast with local contrast - - //for each pixel and each level - float beta; float mea[10]; - float rap = 0.f; - float sig = 1.f; - if(cp.sigm < 1.f) { - sig = cp.sigm; - } + float effect = cp.sigm; + float beta; - if(cp.sigm <= 1.f) { - rap = offs * mean[level] - sig * sigma[level]; - } - - if (rap > 0.f) { - mea[0] = rap; - } else { - mea[0] = mean[level] / 6.f; - } - - rap = 0.f; - if(cp.sigm <= 1.f) { - rap = offs * mean[level] - 0.5f * sig * sigma[level]; - } - - if (rap > 0.f) { - mea[1] = rap; - } else { - mea[1] = mean[level] / 4.f; - } - - rap = 0.f; - if(cp.sigm <= 1.f) { - rap = offs * mean[level] - 0.2f * sig * sigma[level]; - } - - if (rap > 0.f) { - mea[2] = rap; - } else { - mea[2] = mean[level] / 2.f; - } - - mea[3] = offs * mean[level]; // 50% data - mea[4] = offs * mean[level] + cp.sigm * sigma[level] / 2.f; - mea[5] = offs * mean[level] + cp.sigm * sigma[level]; //66% - mea[6] = offs * mean[level] + cp.sigm * 1.2f * sigma[level]; - mea[7] = offs * mean[level] + cp.sigm * 1.5f * sigma[level]; // - mea[8] = offs * mean[level] + cp.sigm * 2.f * sigma[level]; //95% - mea[9] = offs * mean[level] + cp.sigm * 2.5f * sigma[level]; //99% + calceffect(level, mean, sigma, mea, effect, offs); bool useChromAndHue = (skinprot != 0.f || cp.HSmet); float modchro; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index b23143c6c..afedf750c 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.0, 100.0, 0.5, 50.))), + bluwav(Gtk::manage(new Adjuster(M("TP_WAVELET_BLUWAV"), 0.05, 2.5, 0.01, 1.))), 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))), From b8749f708cfdc4bdb2b177a455b2025f0b3e241c Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 31 Mar 2020 14:24:17 +0200 Subject: [PATCH 3/3] Added effect to edge sharpness --- rtdata/languages/default | 3 +++ rtengine/ipwavelet.cc | 44 +++++++++++++++++++++++++++++++++++++++- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 19 +++++++++++++++-- rtgui/wavelet.h | 2 ++ 8 files changed, 77 insertions(+), 3 deletions(-) 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;