From 94133f417fe1ee8ccb29c4d062c4f327e9079284 Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 5 Aug 2019 11:19:43 +0200 Subject: [PATCH] Mask for Blur normal --- rtdata/languages/default | 9 ++ rtengine/improcfun.h | 2 +- rtengine/iplocallab.cc | 192 ++++++++++++++++++++++++++++++++++++--- rtgui/locallab.cc | 14 ++- 4 files changed, 200 insertions(+), 17 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 458d17a3f..b6848212f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -960,6 +960,15 @@ HISTORY_MSG_716;Local - Local method HISTORY_MSG_717;Local - Local contrast HISTORY_MSG_718;Local - Local contrast levels HISTORY_MSG_719;Local - Local contrast residual +HISTORY_MSG_720;Local - Blur mask C +HISTORY_MSG_721;Local - Blur mask L +HISTORY_MSG_722;Local - Blur mask CL +HISTORY_MSG_723;Local - use Blur mask +HISTORY_MSG_725;Local - Blur mask Blend +HISTORY_MSG_726;Local - Blur mask radius +HISTORY_MSG_727;Local - Blur mask chroma +HISTORY_MSG_728;Local - Blur mask gamma +HISTORY_MSG_729;Local - Blur mask slope HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 7bfa42b9f..3e49c6867 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -323,7 +323,7 @@ public: 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, 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(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); + void BlurNoise_Local(LabImage* tmp1, LabImage * originalmask, 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 00afe897f..eb39056f4 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -224,6 +224,13 @@ struct local_params { float chromatm; float gammatm; float slomatm; + + float radmabl; + float blendmabl; + float chromabl; + float gammabl; + float slomabl; + float struexp; float blurexp; float blurcol; @@ -658,6 +665,12 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall float gammasktm = ((float) locallab.spots.at(sp).gammasktm); float slomasktm = ((float) locallab.spots.at(sp).slomasktm); + float blendmaskbl = ((float) locallab.spots.at(sp).blendmaskbl) / 100.f ; + float radmaskbl = ((float) locallab.spots.at(sp).radmaskbl); + float chromaskbl = ((float) locallab.spots.at(sp).chromaskbl); + float gammaskbl = ((float) locallab.spots.at(sp).gammaskbl); + float slomaskbl = ((float) locallab.spots.at(sp).slomaskbl); + lp.scalereti = scaleret; lp.cir = circr; lp.actsp = acti; @@ -704,6 +717,12 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.gammatm = gammasktm; lp.slomatm = slomasktm; + lp.blendmabl = blendmaskbl; + lp.radmabl = radmaskbl; + lp.chromabl = chromaskbl; + lp.gammabl = gammaskbl; + lp.slomabl = slomasktm; + lp.struexp = structexpo; lp.blurexp = blurexpo; lp.blurcol = blurcolor; @@ -1569,7 +1588,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, in } } -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) +void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, LabImage * originalmask, 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 @@ -1585,6 +1604,8 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, const float hueref, const const float refa = chromaref * cos(hueref) * 327.68f; const float refb = chromaref * sin(hueref) * 327.68f; const float refL = lumaref * 327.68f; + const bool blshow = ((lp.showmaskblmet == 1 || lp.showmaskblmet == 2)); + const bool previewbl = ((lp.showmaskblmet == 4)); //balance deltaE float kL = lp.balance; @@ -1592,10 +1613,26 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, const float hueref, const balancedeltaE(kL, kab); kab /= SQR(327.68f); kL /= SQR(327.68f); + const bool usemaskbl = (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 4); + const bool usemaskall = (usemaskbl); + const float radius = 3.f / sk; + std::unique_ptr origblurmask; std::unique_ptr origblur(new LabImage(GW, GH)); - const float radius = 3.f / sk; + if (usemaskall) { + origblurmask.reset(new LabImage(GW, GH)); + +#ifdef _OPENMP + #pragma omp parallel if (multiThread) +#endif + { + gaussianBlur(originalmask->L, origblurmask->L, GW, GH, radius); + gaussianBlur(originalmask->a, origblurmask->a, GW, GH, radius); + gaussianBlur(originalmask->b, origblurmask->b, GW, GH, radius); + } + } + #ifdef _OPENMP #pragma omp parallel #endif @@ -1609,6 +1646,7 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, const float hueref, const #pragma omp parallel if (multiThread) #endif { + const LabImage *maskptr = usemaskall ? origblurmask.get() : origblur.get(); const int limscope = 80; const float mindE = 4.f + MINSCOPE * lp.sensbn * lp.thr;//best usage ?? with blurnoise const float maxdE = 5.f + MAXSCOPE * lp.sensbn * (1 + 0.1f * lp.thr); @@ -1636,20 +1674,31 @@ void ImProcFunctions::BlurNoise_Local(LabImage *tmp1, const float hueref, const continue; } - const float dE = sqrt(kab * (SQR(refa - origblur->a[y][x]) + SQR(refb - origblur->b[y][x])) + kL * SQR(refL - origblur->L[y][x])); + // const float dE = sqrt(kab * (SQR(refa - origblur->a[y][x]) + SQR(refb - origblur->b[y][x])) + kL * SQR(refL - origblur->L[y][x])); + const float dE = sqrt(kab * (SQR(refa - maskptr->a[y][x]) + SQR(refb - maskptr->b[y][x])) + kL * SQR(refL - maskptr->L[y][x])); float reducdE; calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, lp.sensbn, reducdE); const float difL = (tmp1->L[y - ystart][x - xstart] - original->L[y][x]) * localFactor * reducdE; transformed->L[y][x] = CLIP(original->L[y][x] + difL); + const float difa = (tmp1->a[y - ystart][x - xstart] - original->a[y][x]) * localFactor * reducdE;; + const float difb = (tmp1->b[y - ystart][x - xstart] - original->b[y][x]) * localFactor * reducdE;; if (!lp.actsp) { - const float difa = (tmp1->a[y - ystart][x - xstart] - original->a[y][x]) * localFactor * reducdE;; - const float difb = (tmp1->b[y - ystart][x - xstart] - original->b[y][x]) * localFactor * reducdE;; transformed->a[y][x] = CLIPC(original->a[y][x] + difa); transformed->b[y][x] = CLIPC(original->b[y][x] + difb); } + + if (blshow) { + transformed->L[y][x] = CLIP(12000.f + difL); + transformed->a[y][x] = CLIPC(difa); + transformed->b[y][x] = CLIPC(difb); + } else if (previewbl) { + transformed->a[y][x] = 0.f; + transformed->b[y][x] = (difb); + } + } } } @@ -6299,7 +6348,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o //Blur and noise - 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 + if (((radius >= 1.5 * GAUSS_SKIP && lp.rad > 1.) || lp.stren > 0.1 || lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) && lp.blurena) { // radius < GAUSS_SKIP means no gauss, just copy of original image std::unique_ptr tmp1; const int ystart = std::max(static_cast(lp.yc - lp.lyT) - cy, 0); const int yend = std::min(static_cast(lp.yc + lp.ly) - cy, original->H); @@ -6312,6 +6361,131 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o int bfwmask = 0; int bfhmask = 0; + //here mask is used with plein image for normal and inverse + std::unique_ptr bufmaskorigbl; + std::unique_ptr bufmaskblurbl; + std::unique_ptr originalmaskbl; + std::unique_ptr bufgb(new LabImage(GW, GH)); + + if (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) { + bufmaskorigbl.reset(new LabImage(GW, GH)); + bufmaskblurbl.reset(new LabImage(GW, GH)); + originalmaskbl.reset(new LabImage(GW, GH)); + } + + array2D ble(GW, GH); + array2D guid(GW, GH); + float meanfab, fab; + mean_fab(0, 0, GW, GH, bufgb.get(), original, fab, meanfab, lp.chromabl); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < GH; y++) { + for (int x = 0; x < GW; x++) { + bufgb->L[y][x] = original->L[y][x]; + bufgb->a[y][x] = original->a[y][x]; + bufgb->b[y][x] = original->b[y][x]; + } + } + + if (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int ir = 0; ir < GH; ir++) { + for (int jr = 0; jr < GW; jr++) { + float kmaskLexp = 0; + float kmaskCH = 0; + + if (locllmasblCurve && llmasblutili) { + float ligh = bufgb->L[ir][jr] / 32768.f; + kmaskLexp = 32768.f * LIM01(1.f - locllmasblCurve[500.f * ligh]); + } + + if (lp.showmaskblmet != 4) { + if (locccmasblCurve && lcmasblutili) { + float chromask = 0.0001f + sqrt(SQR((bufgb->a[ir][jr]) / fab) + SQR((bufgb->b[ir][jr]) / fab)); + kmaskCH = LIM01(1.f - locccmasblCurve[500.f * chromask]); + } + } + + if (lochhmasblCurve && lhmasblutili) { + float huema = xatan2f(bufgb->b[ir][jr], bufgb->a[ir][jr]); + float h = Color::huelab_to_huehsv2(huema); + h += 1.f / 6.f; + + if (h > 1.f) { + h -= 1.f; + } + + float valHH = LIM01(1.f - lochhmasblCurve[500.f * h]); + + if (lp.showmaskblmet != 4) { + kmaskCH += valHH; + } + + kmaskLexp += 32768.f * valHH; + } + + bufmaskblurbl->L[ir][jr] = CLIPLOC(kmaskLexp); + bufmaskblurbl->a[ir][jr] = kmaskCH; + bufmaskblurbl->b[ir][jr] = kmaskCH; + ble[ir][jr] = bufmaskblurbl->L[ir][jr] / 32768.f; + guid[ir][jr] = bufgb->L[ir][jr] / 32768.f; + + } + } + + if (lp.radmabl > 0.f) { + guidedFilter(guid, ble, ble, lp.radmabl * 10.f / sk, 0.001, multiThread, 4); + } + + LUTf lutTonemaskbl(65536); + calcGammaLut(lp.gammabl, lp.slomabl, lutTonemaskbl); + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int ir = 0; ir < GH; ir++) + for (int jr = 0; jr < GW; jr++) { + float L_; + bufmaskblurbl->L[ir][jr] = LIM01(ble[ir][jr]) * 32768.f; + L_ = 2.f * bufmaskblurbl->L[ir][jr]; + bufmaskblurbl->L[ir][jr] = lutTonemaskbl[L_]; + } + + } + + float radiusb = 1.f / sk; + + if (lp.showmaskblmet == 2 || lp.enablMask || lp.showmaskblmet == 3 || lp.showmaskblmet == 4) { + + //printf("lp.showmasktmmet=%i\n",lp.showmasktmmet); +#ifdef _OPENMP + #pragma omp parallel +#endif + { + gaussianBlur(bufmaskblurbl->L, bufmaskorigbl->L, GW, GH, radiusb); + gaussianBlur(bufmaskblurbl->a, bufmaskorigbl->a, GW, GH, 1.f + (0.5f * lp.radmabl) / sk); + gaussianBlur(bufmaskblurbl->b, bufmaskorigbl->b, GW, GH, 1.f + (0.5f * lp.radmabl) / sk); + } + + if (lp.showmaskblmet == 0 || lp.showmaskblmet == 1 || lp.showmaskblmet == 2 || lp.showmaskblmet == 4 || lp.enablMask) { + blendmask(lp, 0, 0, cx, cy, GW, GH, bufgb.get(), original, bufmaskorigbl.get(), originalmaskbl.get(), lp.blendmabl); + + } else if (lp.showmaskblmet == 3) { + showmask(lp, 0, 0, cx, cy, GW, GH, bufgb.get(), transformed, bufmaskorigbl.get()); + return; + } + } + +//end mask + + if (call <= 3 && lp.blurmet == 0) { if (bfw > 0 && bfh > 0) { tmp1.reset(new LabImage(bfw, bfh)); @@ -6336,10 +6510,6 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bfhmask = GH; } -//here mask for normal and inverse - - -//end mask if (lp.blurmet == 0) { #ifdef _OPENMP @@ -6372,7 +6542,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o if (lp.blurmet == 0) { //blur and noise (center) if (tmp1.get()) { - BlurNoise_Local(tmp1.get(), hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); + BlurNoise_Local(tmp1.get(), originalmaskbl.get(), hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); } } else { InverseBlurNoise_Local(lp, hueref, chromaref, lumaref, original, transformed, tmp1.get(), cx, cy, sk); diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 8c78f0ff0..0d2c60cd8 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -1137,7 +1137,7 @@ Locallab::Locallab(): blurrBox->pack_start(*sensibn); blurrBox->pack_start(*blurMethod); blurrBox->pack_start(*activlum); -// blurrBox->pack_start(*expmaskbl); + blurrBox->pack_start(*expmaskbl); expblur->add(*blurrBox, false); expblur->setLevel(2); @@ -3764,7 +3764,11 @@ void Locallab::softMethodChanged() void Locallab::blurMethodChanged() { // printf("blurMethodChanged\n"); - + if (blurMethod->get_active_row_number() == 0) { + expmaskbl->show(); + } else if (blurMethod->get_active_row_number() == 1) { + expmaskbl->hide(); + } if (getEnabled() && expblur->getEnabled()) { if (listener) { @@ -4008,9 +4012,6 @@ Locallab::llMaskVisibility* Locallab::getMaskVisibility() maskStruct->softMask = showmasksoftMethod->get_active_row_number(); maskStruct->tmMask = showmasktmMethod->get_active_row_number(); maskStruct->blMask = showmaskblMethod->get_active_row_number(); -// printf("SHmask=%i \n", maskStruct->SHMask); -// printf("retimask=%i \n", maskStruct->retiMask); - return maskStruct; } @@ -6549,6 +6550,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con retinexMethod->show(); } + llshape->setCurve(pp->locallab.spots.at(index).llcurve); ccshape->setCurve(pp->locallab.spots.at(index).cccurve); LHshape->setCurve(pp->locallab.spots.at(index).LHcurve); @@ -6653,8 +6655,10 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con if (pp->locallab.spots.at(index).blurMethod == "norm") { blurMethod->set_active(0); + expmaskbl->show(); } else if (pp->locallab.spots.at(index).blurMethod == "inv") { blurMethod->set_active(1); + expmaskbl->hide(); } activlum->set_active(pp->locallab.spots.at(index).activlum);