From bb09c54892bc1d45feac3b3bcd7d6ee08b470aaa Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 20 Oct 2019 10:19:02 +0200 Subject: [PATCH] Improve mask Retinex with deltaE image --- rtdata/languages/default | 1 + rtengine/improcfun.h | 9 +++-- rtengine/iplocallab.cc | 33 ++++++++++++++--- rtengine/ipretinex.cc | 76 +++++++++++++++++++++++++++++++--------- 4 files changed, 97 insertions(+), 22 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 79b3eed4a..6a01bb648 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2128,6 +2128,7 @@ TP_LOCALLAB_SLOMASKCOL;Slope mask TP_LOCALLAB_SHAMASKCOL;Shadows mask TP_LOCALLAB_LAPMASKCOL;Laplacian threshold mask TP_LOCALLAB_SCOPEMASK;Scope Mask DeltaE Image +TP_LOCALLAB_SCOPEMASK_TOOLTIP;Enabled if Mask DeltaE Image is enabled.\nLow values avoid retouching selected area TP_LOCALLAB_MASFRAME;Mask TP_LOCALLAB_MASFRAME_TOOLTIP;For all masks.\nTake into account deltaE image to avoid retouching the selection area when sliders gamma mask, slope mask, chroma mask and contrast curves and levels contrasts curves are used TP_LOCALLAB_WAMASKCOL;Mask Wavelet level diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 08eb85945..5e5c96e5d 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -215,7 +215,9 @@ public: const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, bool retiMasktmap, bool retiMask, float rad, float lap, bool pde, float gamm, float slop, float chro, float blend, LUTf & lmaskretilocalcurve, bool & localmaskretiutili, - LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, bool multiThread); + LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, bool multiThread, + bool delt, const float hueref, const float chromaref, const float lumaref, + float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope); void filmGrain(Imagefloat *rgb, int isogr, int strengr, int scalegr, int bfw, int bfh); @@ -224,7 +226,10 @@ public: const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, LUTf & lmaskretilocalcurve, bool & localmaskretiutili, - LabImage * transformed, bool retiMasktmap, bool retiMask); + LabImage * transformed, bool retiMasktmap, bool retiMask, + bool delt, const float hueref, const float chromaref, const float lumaref, + float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope); + void calc_ref(int sp, LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &chromarefblur, double &lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, float &avg); void copy_ref(LabImage* spotbuffer, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 16a96b3df..1181ec8fa 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -9545,11 +9545,20 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bool fftw = lp.ftwreti; //fftw = false; //for Retinex Mask are incorporated in MSR + bool delt = params->locallab.spots.at(sp).deltae; + int sco = params->locallab.spots.at(sp).scopemask; + const int limscope2 = 80; + const float mindE2 = 2.f + MINSCOPE * sco * lp.thr; + const float maxdE2 = 5.f + MAXSCOPE * sco * (1 + 0.1f * lp.thr); + const float mindElim2 = 2.f + MINSCOPE * limscope2 * lp.thr; + const float maxdElim2 = 5.f + MAXSCOPE * limscope2 * (1 + 0.1f * lp.thr); ImProcFunctions::MSRLocal(sp, fftw, 1, reducDE, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, lmaskretilocalcurve, localmaskretiutili, - transformed, lp.enaretiMasktmap, lp.enaretiMask); + transformed, lp.enaretiMasktmap, lp.enaretiMask, + delt, hueref, chromaref, lumaref, + maxdE2, mindE2, maxdElim2, mindElim2, lp.iterat, limscope2, sco); #ifdef _OPENMP #pragma omp parallel for #endif @@ -9680,7 +9689,10 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, lmaskretilocalcurve, localmaskretiutili, - transformed, lp.enaretiMasktmap, lp.enaretiMask); + transformed, lp.enaretiMasktmap, lp.enaretiMask, + false, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 50); + } if (!lp.invret && call == 1) { @@ -10055,12 +10067,22 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o // float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; bool fftw = lp.ftwreti; //for Retinex Mask are incorporated in MSR + bool delt = params->locallab.spots.at(sp).deltae; + int sco = params->locallab.spots.at(sp).scopemask; + + const int limscope2 = 80; + const float mindE2 = 2.f + MINSCOPE * sco * lp.thr; + const float maxdE2 = 5.f + MAXSCOPE * sco * (1 + 0.1f * lp.thr); + const float mindElim2 = 2.f + MINSCOPE * limscope2 * lp.thr; + const float maxdElim2 = 5.f + MAXSCOPE * limscope2 * (1 + 0.1f * lp.thr); ImProcFunctions::MSRLocal(sp, fftw, 1, reducDE, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, bfwr, bfhr, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, lmaskretilocalcurve, localmaskretiutili, - transformed, lp.enaretiMasktmap, lp.enaretiMask); + transformed, lp.enaretiMasktmap, lp.enaretiMask, + delt, hueref, chromaref, lumaref, + maxdE2, mindE2, maxdElim2, mindElim2, lp.iterat, limscope2, sco); #ifdef _OPENMP #pragma omp parallel for @@ -10205,7 +10227,10 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, lmaskretilocalcurve, localmaskretiutili, - transformed, lp.enaretiMasktmap, lp.enaretiMask); + transformed, lp.enaretiMasktmap, lp.enaretiMask, + false, 1.f, 1.f, 1.f, + 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 50); + } if (!lp.invret && call == 2) { diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index 39528e04f..2d521ab10 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -851,10 +851,12 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e void ImProcFunctions::maskforretinex(int sp, int before, float ** luminance, float ** out, int W_L, int H_L, int skip, - const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, - int llretiMask, bool retiMasktmap, bool retiMask, float rad, float lap, bool pde, float gamm, float slop, float chro, float blend, - LUTf & lmaskretilocalcurve, bool & localmaskretiutili, - LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, bool multiThread) + const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, + int llretiMask, bool retiMasktmap, bool retiMask, float rad, float lap, bool pde, float gamm, float slop, float chro, float blend, + LUTf & lmaskretilocalcurve, bool & localmaskretiutili, + LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, bool multiThread, + bool delt, const float hueref, const float chromaref, const float lumaref, + float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope) { array2D loctemp(W_L, H_L); array2D ble(W_L, H_L); @@ -863,6 +865,9 @@ void ImProcFunctions::maskforretinex(int sp, int before, float ** luminance, flo bufmaskblurreti.reset(new LabImage(W_L, H_L)); std::unique_ptr bufmaskorigreti; bufmaskorigreti.reset(new LabImage(W_L, H_L)); + std::unique_ptr bufprov; + bufprov.reset(new LabImage(W_L, H_L)); + #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) #endif @@ -931,6 +936,9 @@ void ImProcFunctions::maskforretinex(int sp, int before, float ** luminance, flo bufmaskblurreti->b[ir][jr] = kmaskCH; ble[ir][jr] = bufmaskblurreti->L[ir][jr] / 32768.f; guid[ir][jr] = bufreti->L[ir][jr] / 32768.f; + bufprov->L[ir][jr] = bufmaskblurreti->L[ir][jr]; + bufprov->a[ir][jr] = bufmaskblurreti->a[ir][jr]; + bufprov->b[ir][jr] = bufmaskblurreti->b[ir][jr]; } } @@ -955,17 +963,48 @@ void ImProcFunctions::maskforretinex(int sp, int before, float ** luminance, flo bufmaskblurreti->L[ir][jr] = lutTonemaskreti[L_]; } - if (lmaskretilocalcurve && localmaskretiutili) { + if (lmaskretilocalcurve && localmaskretiutili) { #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic,16) + #pragma omp parallel for schedule(dynamic,16) #endif - for (int ir = 0; ir < H_L; ir++) - for (int jr = 0; jr < W_L; jr++) { - bufmaskblurreti->L[ir][jr] = 0.5f * lmaskretilocalcurve[2.f * bufmaskblurreti->L[ir][jr]]; - } + for (int ir = 0; ir < H_L; ir++) + for (int jr = 0; jr < W_L; jr++) { + bufmaskblurreti->L[ir][jr] = 0.5f * lmaskretilocalcurve[2.f * bufmaskblurreti->L[ir][jr]]; + } + } + + + if (delt) { + float *rdE[H_L] ALIGNED16; + float *rdEBuffer = new float[H_L * W_L]; + + for (int i = 0; i < H_L; i++) { + rdE[i] = &rdEBuffer[i * W_L]; } + deltaEforMask(rdE, W_L, H_L, bufreti, hueref, chromaref, lumaref, maxdE, mindE, maxdElim, mindElim, iterat, limscope, scope); + // printf("rde1=%f rde2=%f\n", rdE[1][1], rdE[100][100]); + std::unique_ptr delta(new LabImage(W_L, H_L)); +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int ir = 0; ir < H_L; ir++) + for (int jr = 0; jr < W_L; jr++) { + delta->L[ir][jr] = bufmaskblurreti->L[ir][jr] - bufprov->L[ir][jr]; + delta->a[ir][jr] = bufmaskblurreti->a[ir][jr] - bufprov->a[ir][jr]; + delta->b[ir][jr] = bufmaskblurreti->b[ir][jr] - bufprov->b[ir][jr]; + + bufmaskblurreti->L[ir][jr] = bufprov->L[ir][jr] + rdE[ir][jr] * delta->L[ir][jr]; + bufmaskblurreti->a[ir][jr] = bufprov->a[ir][jr] + rdE[ir][jr] * delta->a[ir][jr]; + bufmaskblurreti->b[ir][jr] = bufprov->b[ir][jr] + rdE[ir][jr] * delta->b[ir][jr]; + } + + delete [] rdEBuffer; + + } + if (lap > 0.f) { float *datain = new float[H_L * W_L]; @@ -1096,11 +1135,13 @@ void ImProcFunctions::maskforretinex(int sp, int before, float ** luminance, flo void ImProcFunctions::MSRLocal(int sp, bool fftw, int lum, float** reducDE, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, - const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, - const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, - const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, - LUTf & lmaskretilocalcurve, bool & localmaskretiutili, - LabImage * transformed, bool retiMasktmap, bool retiMask) + const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, + const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, + const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, + LUTf & lmaskretilocalcurve, bool & localmaskretiutili, + LabImage * transformed, bool retiMasktmap, bool retiMask, + bool delt, const float hueref, const float chromaref, const float lumaref, + float maxdE, float mindE, float maxdElim, float mindElim, float iterat, float limscope, int scope) { BENCHFUN @@ -1636,7 +1677,10 @@ void ImProcFunctions::MSRLocal(int sp, bool fftw, int lum, float** reducDE, LabI locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, retiMasktmap, retiMask, rad, lap, pde, gamm, slop, chro, blend, lmaskretilocalcurve, localmaskretiutili, - bufreti, bufmask, buforig, buforigmas, multiThread); + bufreti, bufmask, buforig, buforigmas, multiThread, + delt, hueref, chromaref, lumaref, + maxdE, mindE, maxdElim, mindElim, iterat, limscope, scope + ); } //mask does not interfered with datas displayed