diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 50e7a4177..4a3edb017 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -47,7 +47,7 @@ #include "cplx_wavelet_dec.h" #include "ciecam02.h" -#define BENCHMARK +//#define BENCHMARK #include "StopWatch.h" #include "guidedfilter.h" @@ -2300,7 +2300,7 @@ void ImProcFunctions::ciecamloc_02float(int sp, LabImage* lab) void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, float epsilmax, float epsilmin, float thres, int sk, bool multiThread, int flag) { - if (rad > 0.f) { + if (rad != 0.f) { array2D ble(bfw, bfh); array2D guid(bfw, bfh); if (flag == 0) { @@ -2315,9 +2315,10 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco } } - const float aepsil = (epsilmax - epsilmin) / 90.f; - const float bepsil = epsilmax - 100.f * aepsil; - const float epsil = aepsil * 0.1f * rad + bepsil; + const float aepsil = (epsilmax - epsilmin) / 1000.f; + const float bepsil = epsilmin; //epsilmax - 100.f * aepsil; + // const float epsil = aepsil * 0.1f * rad + bepsil; + const float epsil = aepsil * rad + bepsil; const float blur = 10.f / sk * (thres + 0.8f * rad); rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); @@ -2361,6 +2362,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco } } + void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &buflight, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread) { float minlig = buflight[0][0]; @@ -14504,6 +14506,10 @@ void ImProcFunctions::Lab_Local( if (lp.blurma >= 0.25f && lp.fftma && call == 2) { optfft(N_fftwsize, bfh, bfw, bfh, bfw, lp, original->H, original->W, xstart, ystart, xend, yend, cx, cy); } + array2D blechro(bfw, bfh); + array2D ble(bfw, bfh); + array2D hue(bfw, bfh); + array2D guid(bfw, bfh); std::unique_ptr bufcolorigsav; std::unique_ptr bufcolorig; @@ -14599,17 +14605,48 @@ void ImProcFunctions::Lab_Local( bufcolfin->L[y][x] = bufcolorig->L[y][x]; bufcolfin->a[y][x] = bufcolorig->a[y][x]; bufcolfin->b[y][x] = bufcolorig->b[y][x]; + hue[y][x] = xatan2f(bufcolfin->b[y][x], bufcolfin->a[y][x]); + const float chromah = std::sqrt(SQR(bufcolfin->b[y][x]) + SQR(bufcolfin->a[y][x])); + ble[y][x] = bufcolfin->L[y][x] / 32768.f; + blechro[y][x] = chromah / 32768.f; + guid[y][x] = bufcolorigsav->L[y][x] / 32768.f; } } - //perhaps we can put here a softproc to reduce artifacts between bufcolorigsav and bufcolfin, just a slider... ?? but is it necessary with this type of change ?? - if (softr > 0.f) { - softproc(bufcolorigsav.get(), bufcolfin.get(), softr, bfh, bfw, 0.0001, 0.00001, 0.1f, sk, multiThread, 1); - } + if (softr != 0.f) {//soft for L a b because we change color... + float rad = softr; + const float tmpblur = rad < 0.f ? -1.f / rad : 1.f + rad; + const int r1 = rtengine::max(4 / sk * tmpblur + 0.5, 1); + const int r2 = rtengine::max(25 / sk * tmpblur + 0.5, 1); - float meansob = 0.f; - transit_shapedetect2(call, 20, bufcolorigsav.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, nullptr, lp, origsav, transformed, cx, cy, sk); - delete origsav; - origsav = NULL; + constexpr float epsilmax = 0.0008f; + constexpr float epsilmin = 0.00001f; + + constexpr float aepsil = (epsilmax - epsilmin) / 1000.f; + constexpr float bepsil = epsilmin; + const float epsil = rad < 0.f ? 0.001f : aepsil * rad + bepsil; + + rtengine::guidedFilter(guid, blechro, blechro, r1, epsil, multiThread); + rtengine::guidedFilter(guid, ble, ble, r2, 0.2f * epsil, multiThread); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int y = 0; y < bfh; y++) { + for (int x = 0; x < bfw; x++) { + float2 sincosval = xsincosf(hue[y][x]); + bufcolfin->L[y][x] = 32768.f * ble[y][x]; + bufcolfin->a[y][x] = 32768.f * blechro[y][x] * sincosval.y; + bufcolfin->b[y][x] = 32768.f * blechro[y][x] * sincosval.x; + } + } + } + + + + float meansob = 0.f; + transit_shapedetect2(call, 20, bufcolorigsav.get(), bufcolfin.get(), originalmaskcol.get(), hueref, chromaref, lumaref, sobelref, meansob, nullptr, lp, origsav, transformed, cx, cy, sk); + delete origsav; + origsav = NULL; if (params->locallab.spots.at(sp).recurs) { original->CopyFrom(transformed, multiThread); diff --git a/rtgui/locallabtools2.cc b/rtgui/locallabtools2.cc index b27eb3aeb..bc859cd70 100644 --- a/rtgui/locallabtools2.cc +++ b/rtgui/locallabtools2.cc @@ -4732,7 +4732,7 @@ LocallabMask::LocallabMask(): // Comon mask specific widgets sensimask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSI"), 0, 100, 1, 60))), blendmask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BLENDMASKCOL"), -100, 100, 1, 0))), - softradiusmask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), 0.0, 1000.0, 0.5, 0.))), + softradiusmask(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SOFTRADIUSCOL"), -10.0, 1000.0, 0.5, 0.))), showmask_Method(Gtk::manage(new MyComboBoxText())), enamask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ENABLE_MASK")))), @@ -4773,6 +4773,7 @@ LocallabMask::LocallabMask(): sensimask->setAdjusterListener(this); blendmask->setAdjusterListener(this); + softradiusmask->setLogScale(10, -10); softradiusmask->setAdjusterListener(this); showmask_Method->append(M("TP_LOCALLAB_SHOWMNONE")); showmask_Method->append(M("TP_LOCALLAB_SHOWMODIFMASK"));