From 473505ab39d4abb0c9a8c2dfdc5b6f832bbe735d Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 9 Apr 2019 17:53:24 +0200 Subject: [PATCH] Fixed huge bug in Blur-Noise --- rtengine/improcfun.h | 4 +- rtengine/iplocallab.cc | 216 +++++++++++++++-------------------------- rtgui/locallab.cc | 6 +- 3 files changed, 84 insertions(+), 142 deletions(-) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index bb2a4168b..14f7109f0 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -305,9 +305,9 @@ public: bool &LHutili, bool &HHutili, LUTf & cclocalcurve, bool & localcutili, bool & localexutili, LUTf & exlocalcurve, LUTf & hltonecurveloc, LUTf & shtonecurveloc, LUTf & tonecurveloc, LUTf & lightCurveloc, double & huerefblur, double &chromarefblur, double & lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int llColorMask, int llExpMask, int llSHMask); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); - void InverseBlurNoise_Local(const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); + void InverseBlurNoise_Local(const struct local_params& lp, const float hueref, const float chromaref, const float lumaref, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int sk); void InverseReti_Local(const struct local_params& lp, const float hueref, const float chromaref, const float lumaref, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy, int chro, int sk); - void BlurNoise_Local(int call, LabImage* tmp1, LabImage* tmp2, float ** buflight, float ** bufchro, const float hueref, const float chromaref, const float lumaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); + void BlurNoise_Local(LabImage* tmp1, const float hueref, const float chromaref, const float lumaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); static void strcurv_data(std::string retistr, int *s_datc, int &siz); void blendstruc(int bfw, int bfh, LabImage* bufcolorig, float radius, float stru, array2D & blend2, int sk, bool multiThread); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 076517f4e..1491e0fbe 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -1410,7 +1410,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, in } -void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2, float ** buflight, float ** bufchro, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::BlurNoise_Local(LabImage * tmp1, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { //local BLUR BENCHFUN @@ -1460,16 +1460,6 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing if (isZone0) { // outside selection and outside transition zone => no effect, keep original values - if (lp.blurmet == 2) { - for (int x = 0; x < transformed->W; x++) { - transformed->L[y][x] = tmp2->L[y][x]; - if (!lp.actsp) { - transformed->a[y][x] = tmp2->a[y][x]; - transformed->b[y][x] = tmp2->b[y][x]; - } - } - } - continue; } @@ -1485,14 +1475,6 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values - if (lp.blurmet == 2) { - transformed->L[y][x] = tmp2->L[y][x]; - if (!lp.actsp) { - transformed->a[y][x] = tmp2->a[y][x]; - transformed->b[y][x] = tmp2->b[y][x]; - } - } - continue; } @@ -1507,50 +1489,28 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 const float ar = 1.f / (mindE - maxdE); const float br = - ar * maxdE; reducdE = pow(ar * dE + br, lp.iterat); - } else /*if (dE <= mindE) */ { + } else { reducdE = 1.f; } - const float realstrdE = reducdE * buflight[loy - begy][lox - begx]; - const float realstrchdE = (1.f + (reducdE * bufchro[loy - begy][lox - begx]) / 100.f); - switch (zone) { case 1: { // inside transition zone float difL, difa, difb; - - if (call <= 3) { difL = tmp1->L[loy - begy][lox - begx] - original->L[y][x]; difa = tmp1->a[loy - begy][lox - begx] - original->a[y][x]; difb = tmp1->b[loy - begy][lox - begx] - original->b[y][x]; - } else { - difL = tmp1->L[y][x] - original->L[y][x]; - difa = tmp1->a[y][x] - original->a[y][x]; - difb = tmp1->b[y][x] - original->b[y][x]; + difL *= localFactor * reducdE; - - } - - difL *= localFactor * (100.f + realstrdE) / 100.f; - - if (lp.blurmet == 0) { transformed->L[y][x] = CLIP(original->L[y][x] + difL); - } else if (lp.blurmet == 2) { - transformed->L[y][x] = CLIP(tmp2->L[y][x] - difL); - } if (!lp.actsp) { - difa *= localFactor * realstrchdE; - difb *= localFactor * realstrchdE; + difa *= localFactor * reducdE; + difb *= localFactor * reducdE; - if (lp.blurmet == 0) { - transformed->a[y][x] = CLIPC(original->a[y][x] + difa); - transformed->b[y][x] = CLIPC(original->b[y][x] + difb); - } else if (lp.blurmet == 2) { - transformed->a[y][x] = CLIPC(tmp2->a[y][x] - difa); - transformed->b[y][x] = CLIPC(tmp2->b[y][x] - difb); - } + transformed->a[y][x] = CLIPC(original->a[y][x] + difa); + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } break; @@ -1563,25 +1523,16 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 difa = tmp1->a[loy - begy][lox - begx] - original->a[y][x]; difb = tmp1->b[loy - begy][lox - begx] - original->b[y][x]; - difL *= (100.f + realstrdE) / 100.f; + difL *= reducdE;//(100.f + realstrdE) / 100.f; - if (lp.blurmet == 0) { - transformed->L[y][x] = CLIP(original->L[y][x] + difL); - } else if (lp.blurmet == 2) { - transformed->L[y][x] = CLIP(tmp2->L[y][x] - difL); - } + transformed->L[y][x] = CLIP(original->L[y][x] + difL); if (!lp.actsp) { - difa *= realstrchdE; - difb *= realstrchdE; + difa *= reducdE; + difb *= reducdE; - if (lp.blurmet == 0) { - transformed->a[y][x] = CLIPC(original->a[y][x] + difa); ; - transformed->b[y][x] = CLIPC(original->b[y][x] + difb); - } else if (lp.blurmet == 2) { - transformed->a[y][x] = CLIPC(tmp2->a[y][x] - difa); - transformed->b[y][x] = CLIPC(tmp2->b[y][x] - difb); - } + transformed->a[y][x] = CLIPC(original->a[y][x] + difa); ; + transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } } } @@ -1590,6 +1541,8 @@ void ImProcFunctions::BlurNoise_Local(int call, LabImage * tmp1, LabImage * tmp2 } } + + void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const float hueref, const float chromaref, const float lumaref, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int chro, int sk) { // BENCHFUN @@ -1732,13 +1685,41 @@ void ImProcFunctions::InverseReti_Local(const struct local_params & lp, const fl -void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy) +void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, const float hueref, const float chromaref, const float lumaref, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk) { // BENCHFUN //inverse local blur and noise float ach = (float)lp.trans / 100.f; + int GW = transformed->W; + int GH = transformed->H; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); - #pragma omp parallel for schedule(dynamic,16) if (multiThread) + //balance deltaE + float kL = lp.balance; + float kab = 1.f; + balancedeltaE(kL, kab); + + LabImage *origblur = new LabImage(GW, GH); + + float radius = 3.f / sk; +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(original->L, origblur->L, GW, GH, radius); + gaussianBlur(original->a, origblur->a, GW, GH, radius); + gaussianBlur(original->b, origblur->b, GW, GH, radius); + + } +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif for (int y = 0; y < transformed->H; y++) { int loy = cy + y; @@ -1755,10 +1736,38 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab calcTransitionrect(lox, loy, ach, lp, zone, localFactor); } + float rL = origblur->L[y][x] / 327.68f; + float reducdE = 0.f; + float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL)); + float mindE = 2.f + MINSCOPE * lp.sensbn * lp.thr; + float maxdE = 5.f + MAXSCOPE * lp.sensbn * (1 + 0.1f * lp.thr); + + float ar = 1.f / (mindE - maxdE); + + float br = - ar * maxdE; + + if (dE > maxdE) { + reducdE = 0.f; + } + + if (dE > mindE && dE <= maxdE) { + reducdE = ar * dE + br; + } + + if (dE <= mindE) { + reducdE = 1.f; + } + + reducdE = pow(reducdE, lp.iterat); + + if (lp.sensbn > 99) { + reducdE = 1.f; + } switch (zone) { case 0: { // outside selection and outside transition zone => full effect, no transition - transformed->L[y][x] = CLIP(tmp1->L[y][x]); + float difL = tmp1->L[y][x] - original->L[y][x]; + transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE); if (!lp.actsp) { transformed->a[y][x] = CLIPC(tmp1->a[y][x]); @@ -1778,7 +1787,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab difa *= factorx; difb *= factorx; - transformed->L[y][x] = CLIP(original->L[y][x] + difL); + transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE); if (!lp.actsp) { @@ -1802,6 +1811,7 @@ void ImProcFunctions::InverseBlurNoise_Local(const struct local_params & lp, Lab } } } +} static void calclight(float lum, float koef, float &lumnew, const LUTf &lightCurveloc) //replace L-curve that does not work in local or bad @@ -4081,15 +4091,12 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o if (((radius >= 1.5 * GAUSS_SKIP && lp.rad > 1.) || lp.stren > 0.1) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image std::unique_ptr tmp1; - std::unique_ptr tmp2; std::unique_ptr bufgb; // LabImage *deltasobelL = nullptr; int GW = transformed->W; int GH = transformed->H; int bfh = int (lp.ly + lp.lyT) + del; //bfw bfh real size of square zone int bfw = int (lp.lx + lp.lxL) + del; - JaggedArray buflight(bfw, bfh); - JaggedArray bufchro(bfw, bfh); if (call <= 3 && lp.blurmet != 1) { bufgb.reset(new LabImage(bfw, bfh, true)); @@ -4118,19 +4125,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } tmp1.reset(new LabImage(bfw, bfh)); - if (lp.blurmet == 2) { - tmp2.reset(new LabImage(transformed->W, transformed->H)); -#ifdef _OPENMP - #pragma omp parallel -#endif - { - gaussianBlur(original->L, tmp2->L, GW, GH, radius); - gaussianBlur(original->a, tmp2->a, GW, GH, radius); - gaussianBlur(original->b, tmp2->b, GW, GH, radius); - } - } - - #ifdef _OPENMP #pragma omp parallel @@ -4165,62 +4159,10 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } - if (lp.blurmet != 1) { //blur and noise (center) - float minL = tmp1->L[0][0] - bufgb->L[0][0]; - float maxL = minL; -#ifdef _OPENMP - #pragma omp parallel for reduction(max:maxL) reduction(min:minL) schedule(dynamic,16) -#endif - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - buflight[ir][jr] = tmp1->L[ir][jr] - bufgb->L[ir][jr]; - minL = rtengine::min(minL, buflight[ir][jr]); - maxL = rtengine::max(maxL, buflight[ir][jr]); - } - } - - const float coef = 0.01f * (max(fabs(minL), fabs(maxL))); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - buflight[ir][jr] /= coef; - } - } - - float minC = sqrt((SQR(tmp1->a[0][0]) + SQR(tmp1->b[0][0]))) - sqrt(SQR(bufgb->a[0][0]) + SQR(bufgb->b[0][0])); - float maxC = minC; -#ifdef _OPENMP - #pragma omp parallel for reduction(max:maxC) reduction(min:minC) schedule(dynamic,16) -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufchro[ir][jr] = sqrt((SQR(tmp1->a[ir][jr]) + SQR(tmp1->b[ir][jr]))) - sqrt(SQR(bufgb->a[ir][jr]) + SQR(bufgb->b[ir][jr])); - minC = rtengine::min(minC, bufchro[ir][jr]); - maxC = rtengine::max(maxC, bufchro[ir][jr]); - } - } - - const float coefC = 0.01f * (max(fabs(minC), fabs(maxC))); - -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int ir = 0; ir < bfh; ir++) { - for (int jr = 0; jr < bfw; jr++) { - bufchro[ir][jr] /= coefC; - } - } - - BlurNoise_Local(call, tmp1.get(), tmp2.get(), buflight, bufchro, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); + if (lp.blurmet == 0) { //blur and noise (center) + BlurNoise_Local(tmp1.get(), hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } else { - - InverseBlurNoise_Local(lp, original, transformed, tmp1.get(), cx, cy); + InverseBlurNoise_Local(lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); } } diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 6bf03947b..8425cde3e 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -712,7 +712,7 @@ Locallab::Locallab(): blurMethod->append(M("TP_LOCALLAB_BLNORM")); blurMethod->append(M("TP_LOCALLAB_BLINV")); - blurMethod->append(M("TP_LOCALLAB_BLSYM")); +// blurMethod->append(M("TP_LOCALLAB_BLSYM")); blurMethod->set_active(0); if(showtooltip) blurMethod->set_tooltip_markup(M("TP_LOCALLAB_BLMETHOD_TOOLTIP")); blurMethodConn = blurMethod->signal_changed().connect(sigc::mem_fun(*this, &Locallab::blurMethodChanged)); @@ -2481,7 +2481,7 @@ void Locallab::blurMethodChanged() } else if (blurMethod->get_active_row_number() == 0 || blurMethod->get_active_row_number() == 2) { sensibn->show(); } else { - sensibn->hide(); + sensibn->show(); } if (blurMethod->get_active_row_number() == 2) { @@ -4928,7 +4928,7 @@ void Locallab::updateSpecificGUIState() } else if (blurMethod->get_active_row_number() == 0 || blurMethod->get_active_row_number() == 2) { sensibn->show(); } else { - sensibn->hide(); + sensibn->show(); } if (blurMethod->get_active_row_number() == 2) {