diff --git a/rtdata/languages/default b/rtdata/languages/default index 62bd527a4..80e8db64f 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -845,7 +845,14 @@ HISTORY_MSG_588;Local - deNoise Equalizer blue-red HISTORY_MSG_589;Local - deNoise bilateral HISTORY_MSG_590;Local - deNoise Scope HISTORY_MSG_591;Local - Avoid color shift - +HISTORY_MSG_592;Local - Sh Contrast +HISTORY_MSG_593;Local - Local contrast +HISTORY_MSG_594;Local - Local contrast radius +HISTORY_MSG_595;Local - Local contrast amount +HISTORY_MSG_596;Local - Local contrast darkness +HISTORY_MSG_597;Local - Local contrast lightness +HISTORY_MSG_598;Local - Local contrast scope +HISTORY_MSG_599;Local - Retinex dehaze HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -1933,6 +1940,7 @@ TP_LOCALLAB_CURVENHSU;Combined HueChroma (experimental) TP_LOCALLAB_CURVENCONTRAST;Super+Contrast threshold (experimental) TP_LOCALLAB_CURVENSOB2;Combined HueChroma + Contrast threshold (experimental) TP_LOCALLAB_DENOIS;Denoise +TP_LOCALLAB_DEHAZ;Dehaze TP_LOCALLAB_LUM;Curves TP_LOCALLAB_CHROMACBDL;Chroma TP_LOCALLAB_CHROMACB_TOOLTIP;Acts as an amplifier-reducer action compare to sliders of luminance.\nUnder 100 reduce, above 100 amplifie @@ -1950,6 +1958,7 @@ TP_LOCALLAB_EXCLUTYPE_TOOLTIP;Normal spot use recursive data.\nExcluding spot re TP_LOCALLAB_EXNORM;Normal spot TP_LOCALLAB_EXECLU;Excluding spot TP_LOCALLAB_EXPOSE;Exposure +TP_LOCALLAB_LOC_CONTRAST;Local contrast TP_LOCALLAB_NOISELUMFINE;Luminance fine (Wav) TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav) TP_LOCALLAB_NOISELUMDETAIL;Luminance detail (DCT) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index b46fab57b..8d4d4ee7f 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -253,7 +253,7 @@ public: void Lanczos(const Imagefloat* src, Imagefloat* dst, float scale); void deconvsharpening(float** luminance, float** buffer, int W, int H, const SharpeningParams &sharpenParam); - void deconvsharpeningloc(float** luminance, float** buffer, int W, int H, float** loctemp, int damp, double radi, int ite, int amo); + void deconvsharpeningloc(float** luminance, float** buffer, int W, int H, float** loctemp, int damp, double radi, int ite, int amo, int contrast); void MLsharpen(LabImage* lab); // Manuel's clarity / sharpening void MLmicrocontrast(float** luminance, int W, int H); //Manuel's microcontrast @@ -319,7 +319,7 @@ public: void InverseColorLight_Local(const struct local_params& lp, LUTf & lightCurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, int sk); void cat02_Local(float moddE, float powdE, float **buflightcat, float **buf_a_cat, float ** buf_b_cat, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, const struct local_params & lp, LabImage * original, LabImage * transformed, const LabImage * const tmp1, int cx, int cy, int sk); - void Sharp_Local(int call, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); + void Sharp_Local(int call, float **loctemp, int senstype, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); void InverseSharp_Local(float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); @@ -397,8 +397,10 @@ public: void BadpixelsLab(LabImage * lab, double radius, int thresh, float chrom); void dehaze(Imagefloat *rgb); + void dehazeloc(Imagefloat *rgb, float deha, float depth); void ToneMapFattal02(Imagefloat *rgb); void localContrast(LabImage *lab); + void localContrastloc(LabImage *lab, int scale, int rad, int amo, int darkn, int lightn, float **loctemp); void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread); void shadowsHighlights(LabImage *lab); void softLight(LabImage *lab); diff --git a/rtengine/ipdehaze.cc b/rtengine/ipdehaze.cc index 97c1883c9..431fe924a 100644 --- a/rtengine/ipdehaze.cc +++ b/rtengine/ipdehaze.cc @@ -328,4 +328,122 @@ void ImProcFunctions::dehaze(Imagefloat *img) } +void ImProcFunctions::dehazeloc(Imagefloat *img, float deha, float depth) +{ + + img->normalizeFloatTo1(); + + const int W = img->getWidth(); + const int H = img->getHeight(); + float strength = deha;//LIM01(float(params->locallab.dehaze) / 100.f * 0.9f); + + if (options.rtSettings.verbose) { + std::cout << "dehaze: strength = " << strength << std::endl; + } + + array2D dark(W, H); + + int patchsize = max(int(5 / scale), 2); + int npatches = 0; + float ambient[3]; + array2D &t_tilde = dark; + float max_t = 0.f; + + { + array2D R(W, H); + array2D G(W, H); + array2D B(W, H); + extract_channels(img, R, G, B, patchsize, 1e-1, multiThread); + + patchsize = max(max(W, H) / 600, 2); + npatches = get_dark_channel(R, G, B, dark, patchsize, nullptr, false, multiThread); + DEBUG_DUMP(dark); + + max_t = estimate_ambient_light(R, G, B, dark, patchsize, npatches, ambient); + + if (options.rtSettings.verbose) { + std::cout << "dehaze: ambient light is " + << ambient[0] << ", " << ambient[1] << ", " << ambient[2] + << std::endl; + } + + get_dark_channel(R, G, B, dark, patchsize, ambient, true, multiThread); + } + + if (min(ambient[0], ambient[1], ambient[2]) < 0.01f) { + if (options.rtSettings.verbose) { + std::cout << "dehaze: no haze detected" << std::endl; + } + img->normalizeFloatTo65535(); + return; // probably no haze at all + } + + DEBUG_DUMP(t_tilde); + +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + dark[y][x] = 1.f - strength * dark[y][x]; + } + } + + const int radius = patchsize * 4; + const float epsilon = 1e-5; + array2D &t = t_tilde; + + { + array2D guideB(W, H, img->b.ptrs, ARRAY2D_BYREFERENCE); + guidedFilter(guideB, t_tilde, t, radius, epsilon, multiThread); + } + + DEBUG_DUMP(t); + + if (options.rtSettings.verbose) { + std::cout << "dehaze: max distance is " << max_t << std::endl; + } + + float dept = depth; + if (options.rtSettings.verbose) { + std::cout << "dehaze: depth = " << dept << std::endl; + } + + const float t0 = max(1e-3f, std::exp(dept * max_t)); + const float teps = 1e-3f; +#ifdef _OPENMP + #pragma omp parallel for if (multiThread) +#endif + for (int y = 0; y < H; ++y) { + for (int x = 0; x < W; ++x) { + // ensure that the transmission is such that to avoid clipping... + float rgb[3] = { img->r(y, x), img->g(y, x), img->b(y, x) }; + // ... t >= tl to avoid negative values + float tl = 1.f - min(rgb[0]/ambient[0], rgb[1]/ambient[1], rgb[2]/ambient[2]); + // ... t >= tu to avoid values > 1 + float tu = t0 - teps; + for (int c = 0; c < 3; ++c) { + if (ambient[c] < 1) { + tu = max(tu, (rgb[c] - ambient[c])/(1.f - ambient[c])); + } + } + float mt = max(t[y][x], t0, tl + teps, tu + teps); + if (params->dehaze.showDepthMap) { + img->r(y, x) = img->g(y, x) = img->b(y, x) = 1.f - mt; + } else { + float r = (rgb[0] - ambient[0]) / mt + ambient[0]; + float g = (rgb[1] - ambient[1]) / mt + ambient[1]; + float b = (rgb[2] - ambient[2]) / mt + ambient[2]; + + img->r(y, x) = r; + img->g(y, x) = g; + img->b(y, x) = b; + } + } + } + + img->normalizeFloatTo65535(); +} + + } // namespace rtengine diff --git a/rtengine/iplocalcontrast.cc b/rtengine/iplocalcontrast.cc index aa1eeff7d..9f8df7add 100644 --- a/rtengine/iplocalcontrast.cc +++ b/rtengine/iplocalcontrast.cc @@ -30,7 +30,8 @@ #include "gauss.h" #include "array2D.h" -namespace rtengine { +namespace rtengine +{ void ImProcFunctions::localContrast(LabImage *lab) { @@ -54,6 +55,7 @@ void ImProcFunctions::localContrast(LabImage *lab) #ifdef _OPENMP #pragma omp parallel for if(multiThread) #endif + for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { float bufval = (lab->L[y][x] - buf[y][x]) * a; @@ -67,4 +69,39 @@ void ImProcFunctions::localContrast(LabImage *lab) } } +void ImProcFunctions::localContrastloc(LabImage *lab, int scale, int rad, int amo, int darkn, int lightn, float **loctemp) +{ + + const int width = lab->W; + const int height = lab->H; + const float a = (float)(amo) / 100.f; + const float dark = (float)(darkn) / 100.f; + const float light = (float)(lightn) / 100.f; + array2D buf(width, height); + const float sigma = (float)(rad) / scale; + +#ifdef _OPENMP + #pragma omp parallel if(multiThread) +#endif + gaussianBlur(lab->L, buf, width, height, sigma); + +#ifdef _OPENMP + #pragma omp parallel for if(multiThread) +#endif + + for (int y = 0; y < height; ++y) { + for (int x = 0; x < width; ++x) { + float bufval = (lab->L[y][x] - buf[y][x]) * a; + + if (dark != 1 || light != 1) { + bufval *= (bufval > 0.f) ? light : dark; + } + + // lab->L[y][x] = std::max(0.0001f, lab->L[y][x] + bufval); + loctemp[y][x] = std::max(0.0001f, lab->L[y][x] + bufval); + + } + } +} + } // namespace rtengine diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 3e2a00d4a..f109677ea 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -155,13 +155,15 @@ struct local_params { int cir; float thr; int prox; - int chro, cont, sens, sensh, senscb, sensbn, senstm, sensex, sensexclu, sensden; + int chro, cont, sens, sensh, senscb, sensbn, senstm, sensex, sensexclu, sensden, senslc; float ligh; int shamo, shdamp, shiter, senssha, sensv; + float lcamount; double shrad; double rad; double stren; int trans; + int dehaze; bool inv; bool curvact; bool invrad; @@ -193,6 +195,7 @@ struct local_params { bool tonemapena; bool retiena; bool sharpena; + bool lcena; bool cbdlena; bool denoiena; bool expvib; @@ -422,15 +425,18 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall int local_sensibn = locallab.sensibn.at(sp); int local_sensitm = locallab.sensitm.at(sp); int local_sensiexclu = locallab.sensiexclu.at(sp); + int local_sensilc = locallab.sensilc.at(sp); int local_struc = locallab.struc.at(sp); int local_warm = locallab.warm.at(sp); int local_sensih = locallab.sensih.at(sp); + int local_dehaze = locallab.dehaz.at(sp); int local_sensicb = locallab.sensicb.at(sp); int local_contrast = locallab.contrast.at(sp); float local_lightness = (float) locallab.lightness.at(sp); int local_transit = locallab.transit.at(sp); double radius = (double) locallab.radius.at(sp); double sharradius = ((double) locallab.sharradius.at(sp)) / 100. ; + double lcamount = ((double) locallab.lcamount.at(sp)) / 100. ; int local_sensisha = locallab.sensisha.at(sp); int local_sharamount = locallab.sharamount.at(sp); int local_shardamping = locallab.shardamping.at(sp); @@ -460,6 +466,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.chro = local_chroma; lp.sens = local_sensi; lp.sensh = local_sensih; + lp.dehaze = local_dehaze; lp.senscb = local_sensicb; lp.cont = local_contrast; lp.ligh = local_lightness; @@ -473,6 +480,8 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.stren = strength; lp.sensbn = local_sensibn; lp.sensexclu = local_sensiexclu; + lp.senslc = local_sensilc; + lp.lcamount = lcamount; lp.inv = inverse; lp.curvact = curvacti; lp.invrad = inverserad; @@ -516,6 +525,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall lp.tonemapena = locallab.exptonemap.at(sp); lp.retiena = locallab.expreti.at(sp); lp.sharpena = locallab.expsharp.at(sp); + lp.lcena = locallab.expcontrast.at(sp); lp.cbdlena = locallab.expcbdl.at(sp); lp.denoiena = locallab.expdenoi.at(sp); lp.expvib = locallab.expvibrance.at(sp); @@ -5400,7 +5410,7 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueplus, c } -void ImProcFunctions::Sharp_Local(int call, float **loctemp, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) +void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk) { BENCHFUN const float ach = (float)lp.trans / 100.f; @@ -5410,15 +5420,22 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, const float hueplus const float bpl = - apl * hueplus; const float amo = 1.f / delhu; const float bmo = - amo * huemoins; + float varsens = 0.f; + if (senstype == 0) { + varsens = lp.senssha; + + } else if (senstype == 0) { + varsens = lp.senslc; + } const float pb = 4.f; const float pa = (1.f - pb) / 40.f; - const float ahu = 1.f / (2.8f * lp.senssha - 280.f); - const float bhu = 1.f - ahu * 2.8f * lp.senssha; + const float ahu = 1.f / (2.8f * varsens - 280.f); + const float bhu = 1.f - ahu * 2.8f * varsens; - const bool detectHue = lp.senssha < 20.f && lp.qualmet >= 1; + const bool detectHue = varsens < 20.f && lp.qualmet >= 1; int GW = transformed->W; int GH = transformed->H; @@ -5521,20 +5538,20 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, const float hueplus float deltachro = fabs(rchro - chromaref); //kch to modulate action with chroma - if (deltachro < 160.f * SQR(lp.senssha / 100.f)) { + if (deltachro < 160.f * SQR(varsens / 100.f)) { kch = 1.f; } else { - float ck = 160.f * SQR(lp.senssha / 100.f); + float ck = 160.f * SQR(varsens / 100.f); float ak = 1.f / (ck - 160.f); float bk = -160.f * ak; kch = ak * deltachro + bk; - if (lp.senssha < 40.f) { - kch = pow_F(kch, pa * lp.senssha + pb); //increase under 40 + if (varsens < 40.f) { + kch = pow_F(kch, pa * varsens + pb); //increase under 40 } } - if (lp.senssha >= 99.f) { + if (varsens >= 99.f) { kch = 1.f; } @@ -5596,7 +5613,7 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, const float hueplus float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 - if (deltaE < 2.8f * lp.senssha) { + if (deltaE < 2.8f * varsens) { fach = khu; } else { fach = khu * (ahu * deltaE + bhu); @@ -8602,6 +8619,8 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L float dhuesha = ared * lp.senssha + bred; //delta hue sharp + float dhuelc = ared * lp.senslc + bred; //delta hue local contrast + float dhuecb = ared * lp.senscb + bred; //delta hue cbdl float dhueexclu = ared * lp.sensexclu + bred; //delta hue exclude @@ -9801,7 +9820,7 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L bool execdenoi = false ; bool execcolor = (lp.chro != 0.f || lp.ligh != 0.f || lp.cont != 0.f); // only if one slider ore more is engaged bool execbdl = (lp.mulloc[0] != 1.f || lp.mulloc[1] != 1.f || lp.mulloc[2] != 1.f || lp.mulloc[3] != 1.f || lp.mulloc[4] != 1.f) ;//only if user want cbdl - execdenoi = noiscfactiv && ((lp.colorena && execcolor) || (lp.tonemapena && lp.strengt != 0.f) || (lp.cbdlena && execbdl) || (lp.sharpena && lp.shrad > 0.42) || (lp.retiena && lp.str > 0.f) || (lp.exposena && lp.expcomp != 0.f) || (lp.expvib && lp.past != 0.f)); + execdenoi = noiscfactiv && ((lp.colorena && execcolor) || (lp.tonemapena && lp.strengt != 0.f) || (lp.cbdlena && execbdl) || (lp.lcena && lp.lcamount > 0.f) || (lp.sharpena && lp.shrad > 0.42) || (lp.retiena && lp.str > 0.f) || (lp.exposena && lp.expcomp != 0.f) || (lp.expvib && lp.past != 0.f)); if (((lp.noiself > 0.f || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f) && lp.denoiena) || execdenoi) { // sk == 1 ?? StopWatch Stop1("locallab Denoise called"); @@ -11964,6 +11983,64 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L //end cbdl +//local contrast + if (lp.lcamount > 0.f && call < 3 && lp.lcena) { //interior ellipse for sharpening, call = 1 and 2 only with Dcrop and simpleprocess + int bfh = call == 2 ? int (lp.ly + lp.lyT) + del : original->H; //bfw bfh real size of square zone + int bfw = call == 2 ? int (lp.lx + lp.lxL) + del : original->W; + JaggedArray loctemp(bfw, bfh); + LabImage *bufloca = nullptr; + + if (call == 2) { //call from simpleprocess + bufloca = new LabImage(bfw, bfh); + + // JaggedArray hbuffer(bfw, bfh); + int begy = lp.yc - lp.lyT; + int begx = lp.xc - lp.lxL; + int yEn = lp.yc + lp.ly; + int xEn = lp.xc + lp.lx; + +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) +#endif + + for (int y = 0; y < transformed->H ; y++) //{ + for (int x = 0; x < transformed->W; x++) { + int lox = cx + x; + int loy = cy + y; + + if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) { + bufloca->L[loy - begy][lox - begx] = original->L[y][x];//fill square buffer with datas + } + } + + ImProcFunctions::localContrastloc(bufloca, sk, params->locallab.lcradius.at(sp), params->locallab.lcamount.at(sp), params->locallab.lcdarkness.at(sp), params->locallab.lightness.at(sp), loctemp); + + } else { //call from dcrop.cc + + ImProcFunctions::localContrastloc(original, sk, params->locallab.lcradius.at(sp), params->locallab.lcamount.at(sp), params->locallab.lcdarkness.at(sp), params->locallab.lightness.at(sp), loctemp); + + } + + float hueplus = hueref + dhuelc; + float huemoins = hueref - dhuelc; + + if (hueplus > rtengine::RT_PI) { + hueplus = hueref + dhuelc - 2.f * rtengine::RT_PI; + } + + if (huemoins < -rtengine::RT_PI) { + huemoins = hueref - dhuelc + 2.f * rtengine::RT_PI; + } + + //sharpen ellipse and transition + Sharp_Local(call, loctemp, 1, hueplus, huemoins, hueref, dhuesha, chromaref, lp, original, transformed, cx, cy, sk); + + delete bufloca; + + + } + + if (!lp.invshar && lp.shrad > 0.42 && call < 3 && lp.sharpena) { //interior ellipse for sharpening, call = 1 and 2 only with Dcrop and simpleprocess int bfh = call == 2 ? int (lp.ly + lp.lyT) + del : original->H; //bfw bfh real size of square zone int bfw = call == 2 ? int (lp.lx + lp.lxL) + del : original->W; @@ -11994,10 +12071,10 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L // } //sharpen only square area instaed of all image - ImProcFunctions::deconvsharpeningloc(bufsh, hbuffer, bfw, bfh, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp)); + ImProcFunctions::deconvsharpeningloc(bufsh, hbuffer, bfw, bfh, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp), params->locallab.sharcontrast.at(sp)); } else { //call from dcrop.cc - ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, bfw, bfh, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp)); + ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, bfw, bfh, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp), params->locallab.sharcontrast.at(sp)); } @@ -12013,14 +12090,14 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } //sharpen ellipse and transition - Sharp_Local(call, loctemp, hueplus, huemoins, hueref, dhuesha, chromaref, lp, original, transformed, cx, cy, sk); + Sharp_Local(call, loctemp, 0, hueplus, huemoins, hueref, dhuesha, chromaref, lp, original, transformed, cx, cy, sk); } else if (lp.invshar && lp.shrad > 0.42 && call < 3 && lp.sharpena) { int GW = original->W; int GH = original->H; JaggedArray loctemp(GW, GH); - ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, GW, GH, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp)); + ImProcFunctions::deconvsharpeningloc(original->L, shbuffer, GW, GH, loctemp, params->locallab.shardamping.at(sp), (double)params->locallab.sharradius.at(sp) / 100., params->locallab.shariter.at(sp), params->locallab.sharamount.at(sp), params->locallab.sharcontrast.at(sp)); float hueplus = hueref + dhuesha; float huemoins = hueref - dhuesha; @@ -12103,6 +12180,17 @@ void ImProcFunctions::Lab_Local(int call, int maxspot, int sp, LUTf & huerefs, L } } + //calc dehaze + Imagefloat *tmpImage = nullptr; + tmpImage = new Imagefloat(bfw, bfh); + lab2rgb(*bufreti, *tmpImage, params->icm.workingProfile); + float deha = LIM01(float(0.9f * params->locallab.dehaz.at(sp) + 0.3f*lp.str) / 100.f * 0.9f); + float depthcombi = 0.3f*params->locallab.neigh.at(sp) + 0.15f * (500.f - params->locallab.vart.at(sp)); + float depth = -LIM01(depthcombi / 100.f); + + dehazeloc(tmpImage, deha, depth); + + rgb2lab(*tmpImage, *bufreti, params->icm.workingProfile); } diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index cee216bdd..248d2c3be 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -211,7 +211,7 @@ BENCHFUN } // end parallel } -void ImProcFunctions::deconvsharpeningloc (float** luminance, float** tmp, int W, int H, float** loctemp, int damp, double radi, int ite, int amo) +void ImProcFunctions::deconvsharpeningloc (float** luminance, float** tmp, int W, int H, float** loctemp, int damp, double radi, int ite, int amo, int contrast) { // BENCHFUN @@ -233,6 +233,11 @@ void ImProcFunctions::deconvsharpeningloc (float** luminance, float** tmp, int W } } + // calculate contrast based blend factors to reduce sharpening in regions with low contrast + JaggedArray blend(W, H); + float contras = contrast / 100.f; + buildBlendMask(luminance, blend, W, H, contras, amo / 100.f); + float damping = (float) damp / 5.0; bool needdamp = damp > 0; double sigma = radi / scale; @@ -261,8 +266,8 @@ void ImProcFunctions::deconvsharpeningloc (float** luminance, float** tmp, int W gaussianBlur (tmp, tmpI, W, H, sigma, nullptr, GAUSS_MULT); } // end for - float p2 = (float) amo / 100.0; - float p1 = 1.0 - p2; + // float p2 = (float) amo / 100.0; + // float p1 = 1.0 - p2; #ifdef _OPENMP #pragma omp for @@ -270,7 +275,8 @@ void ImProcFunctions::deconvsharpeningloc (float** luminance, float** tmp, int W for (int i = 0; i < H; i++) for (int j = 0; j < W; j++) { - loctemp[i][j] = luminance[i][j] * p1 + max (tmpI[i][j], 0.0f) * p2; + // loctemp[i][j] = luminance[i][j] * p1 + max (tmpI[i][j], 0.0f) * p2; + loctemp[i][j] = intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]); } } // end parallel diff --git a/rtengine/procevents.h b/rtengine/procevents.h index eb616ba20..808daef05 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -618,6 +618,14 @@ enum ProcEventCode { Evlocallabbilateral = 588, Evlocallabsensiden = 589, Evlocallabavoid = 590, + Evlocallabsharcontrast = 591, + EvLocenacontrast = 592, + Evlocallablcradius = 593, + Evlocallablcamount = 594, + Evlocallablcdarkness = 595, + Evlocallablclightness = 596, + Evlocallabsensilc = 597, + Evlocallabdehaz = 598, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 8faef97be..ea1152e24 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2411,17 +2411,26 @@ LocallabParams::LocallabParams() : chrrt(), neigh(), vart(), + dehaz(), sensih(), localTgaincurve(), inversret(), // Sharpening expsharp(), + sharcontrast(), sharradius(), sharamount(), shardamping(), shariter(), sensisha(), inverssha(), + //local contrast + expcontrast(), + lcradius(), + lcamount(), + lcdarkness(), + lclightness(), + sensilc(), // Contrast by detail levels expcbdl(), mult(), @@ -2527,17 +2536,27 @@ bool LocallabParams::operator ==(const LocallabParams& other) const && chrrt == other.chrrt && neigh == other.neigh && vart == other.vart + && dehaz == other.dehaz && sensih == other.sensih && localTgaincurve == other.localTgaincurve && inversret == other.inversret // Sharpening && expsharp == other.expsharp + && sharcontrast == other.sharcontrast && sharradius == other.sharradius && sharamount == other.sharamount && shardamping == other.shardamping && shariter == other.shariter && sensisha == other.sensisha && inverssha == other.inverssha + //local contrast + && expcontrast == other.expcontrast + && lcradius == other.lcradius + && lcamount == other.lcamount + && lcdarkness == other.lcdarkness + && lclightness == other.lclightness + && sensilc == other.sensilc + // Constrast by detail levels && expcbdl == other.expcbdl && [this, &other]()->bool { @@ -3570,17 +3589,27 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.chrrt, "Locallab", "Chrrt_" + std::to_string(i), locallab.chrrt.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.neigh, "Locallab", "Neigh_" + std::to_string(i), locallab.neigh.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.vart, "Locallab", "Vart_" + std::to_string(i), locallab.vart.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.dehaz, "Locallab", "Dehaz_" + std::to_string(i), locallab.dehaz.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.sensih, "Locallab", "Sensih_" + std::to_string(i), locallab.sensih.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.localTgaincurve, "Locallab", "TgainCurve_" + std::to_string(i), locallab.localTgaincurve.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.inversret, "Locallab", "Inversret_" + std::to_string(i), locallab.inversret.at(i), keyFile); // Sharpening saveToKeyfile(!pedited || pedited->locallab.expsharp, "Locallab", "Expsharp_" + std::to_string(i), locallab.expsharp.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.sharcontrast, "Locallab", "Sharcontrast_" + std::to_string(i), locallab.sharcontrast.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.sharradius, "Locallab", "Sharradius_" + std::to_string(i), locallab.sharradius.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.sharamount, "Locallab", "Sharamount_" + std::to_string(i), locallab.sharamount.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.shardamping, "Locallab", "Shardamping_" + std::to_string(i), locallab.shardamping.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.shariter, "Locallab", "Shariter_" + std::to_string(i), locallab.shariter.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.sensisha, "Locallab", "Sensisha_" + std::to_string(i), locallab.sensisha.at(i), keyFile); saveToKeyfile(!pedited || pedited->locallab.inverssha, "Locallab", "Inverssha_" + std::to_string(i), locallab.inverssha.at(i), keyFile); + //local contrast + saveToKeyfile(!pedited || pedited->locallab.expcontrast, "Locallab", "Expcontrast_" + std::to_string(i), locallab.expcontrast.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.lcradius, "Locallab", "Lcradius_" + std::to_string(i), locallab.lcradius.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.lcradius, "Locallab", "Lcamount_" + std::to_string(i), locallab.lcamount.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.lcradius, "Locallab", "Lcdarkness_" + std::to_string(i), locallab.lcdarkness.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.lcradius, "Locallab", "Lclightness_" + std::to_string(i), locallab.lclightness.at(i), keyFile); + saveToKeyfile(!pedited || pedited->locallab.sensilc, "Locallab", "Sensilc_" + std::to_string(i), locallab.sensilc.at(i), keyFile); + // Contrast by detail levels saveToKeyfile(!pedited || pedited->locallab.expcbdl, "Locallab", "Expcbdl_" + std::to_string(i), locallab.expcbdl.at(i), keyFile); @@ -4748,17 +4777,26 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) locallab.chrrt.resize(locallab.nbspot); locallab.neigh.resize(locallab.nbspot); locallab.vart.resize(locallab.nbspot); + locallab.dehaz.resize(locallab.nbspot); locallab.sensih.resize(locallab.nbspot); locallab.localTgaincurve.resize(locallab.nbspot); locallab.inversret.resize(locallab.nbspot); // Sharpening locallab.expsharp.resize(locallab.nbspot); + locallab.sharcontrast.resize(locallab.nbspot); locallab.sharradius.resize(locallab.nbspot); locallab.sharamount.resize(locallab.nbspot); locallab.shardamping.resize(locallab.nbspot); locallab.shariter.resize(locallab.nbspot); locallab.sensisha.resize(locallab.nbspot); locallab.inverssha.resize(locallab.nbspot); + //local contrast + locallab.expcontrast.resize(locallab.nbspot); + locallab.lcradius.resize(locallab.nbspot); + locallab.lcamount.resize(locallab.nbspot); + locallab.lcdarkness.resize(locallab.nbspot); + locallab.lclightness.resize(locallab.nbspot); + locallab.sensilc.resize(locallab.nbspot); // Contrast by detail levels locallab.expcbdl.resize(locallab.nbspot); @@ -4873,17 +4911,27 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Chrrt_" + std::to_string(i), pedited, locallab.chrrt.at(i), pedited->locallab.chrrt); assignFromKeyfile(keyFile, "Locallab", "Neigh_" + std::to_string(i), pedited, locallab.neigh.at(i), pedited->locallab.neigh); assignFromKeyfile(keyFile, "Locallab", "Vart_" + std::to_string(i), pedited, locallab.vart.at(i), pedited->locallab.vart); + assignFromKeyfile(keyFile, "Locallab", "Dehaz_" + std::to_string(i), pedited, locallab.dehaz.at(i), pedited->locallab.dehaz); assignFromKeyfile(keyFile, "Locallab", "Sensih_" + std::to_string(i), pedited, locallab.sensih.at(i), pedited->locallab.sensih); assignFromKeyfile(keyFile, "Locallab", "TgainCurve_" + std::to_string(i), pedited, locallab.localTgaincurve.at(i), pedited->locallab.localTgaincurve); assignFromKeyfile(keyFile, "Locallab", "Inversret_" + std::to_string(i), pedited, locallab.inversret.at(i), pedited->locallab.inversret); // Sharpening assignFromKeyfile(keyFile, "Locallab", "Expsharp_" + std::to_string(i), pedited, locallab.expsharp.at(i), pedited->locallab.expsharp); + assignFromKeyfile(keyFile, "Locallab", "Sharcontrast_" + std::to_string(i), pedited, locallab.sharcontrast.at(i), pedited->locallab.sharcontrast); assignFromKeyfile(keyFile, "Locallab", "Sharradius_" + std::to_string(i), pedited, locallab.sharradius.at(i), pedited->locallab.sharradius); assignFromKeyfile(keyFile, "Locallab", "Sharamount_" + std::to_string(i), pedited, locallab.sharamount.at(i), pedited->locallab.sharamount); assignFromKeyfile(keyFile, "Locallab", "Shardamping_" + std::to_string(i), pedited, locallab.shardamping.at(i), pedited->locallab.shardamping); assignFromKeyfile(keyFile, "Locallab", "Shariter_" + std::to_string(i), pedited, locallab.shariter.at(i), pedited->locallab.shariter); assignFromKeyfile(keyFile, "Locallab", "Sensisha_" + std::to_string(i), pedited, locallab.sensisha.at(i), pedited->locallab.sensisha); assignFromKeyfile(keyFile, "Locallab", "Inverssha_" + std::to_string(i), pedited, locallab.inverssha.at(i), pedited->locallab.inverssha); + //local contrast + assignFromKeyfile(keyFile, "Locallab", "Expcontrast_" + std::to_string(i), pedited, locallab.expcontrast.at(i), pedited->locallab.expcontrast); + assignFromKeyfile(keyFile, "Locallab", "Lcradius_" + std::to_string(i), pedited, locallab.lcradius.at(i), pedited->locallab.lcradius); + assignFromKeyfile(keyFile, "Locallab", "Lcamount_" + std::to_string(i), pedited, locallab.lcamount.at(i), pedited->locallab.lcamount); + assignFromKeyfile(keyFile, "Locallab", "Lcdarkness_" + std::to_string(i), pedited, locallab.lcdarkness.at(i), pedited->locallab.lcdarkness); + assignFromKeyfile(keyFile, "Locallab", "Lclightness_" + std::to_string(i), pedited, locallab.lclightness.at(i), pedited->locallab.lclightness); + assignFromKeyfile(keyFile, "Locallab", "Sensilc_" + std::to_string(i), pedited, locallab.sensilc.at(i), pedited->locallab.sensilc); + // Contrast by detail levels assignFromKeyfile(keyFile, "Locallab", "Expcbdl_" + std::to_string(i), pedited, locallab.expcbdl.at(i), pedited->locallab.expcbdl); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 2ba032042..b3394e0a0 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -999,17 +999,26 @@ struct LocallabParams { std::vector chrrt; std::vector neigh; std::vector vart; + std::vector dehaz; std::vector sensih; std::vector> localTgaincurve; std::vector inversret; // Sharpening std::vector expsharp; + std::vector sharcontrast; std::vector sharradius; std::vector sharamount; std::vector shardamping; std::vector shariter; std::vector sensisha; std::vector inverssha; + //local contrast + std::vector expcontrast; + std::vector lcradius; + std::vector lcamount; + std::vector lcdarkness; + std::vector lclightness; + std::vector sensilc; // Contrast by detail levels std::vector expcbdl; std::vector mult[5]; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 9272ecce8..937b56f14 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -617,7 +617,15 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabadjblur LUMINANCECURVE, // Evlocallabbilateral LUMINANCECURVE, // Evlocallabsensiden - LUMINANCECURVE // Evlocallabavoid + LUMINANCECURVE, // Evlocallabavoid + LUMINANCECURVE, // Evlocallabsharcontrast + LUMINANCECURVE, //EvLocenacontrast + LUMINANCECURVE, //Evlocallablcradius + LUMINANCECURVE, //Evlocallablcamount + LUMINANCECURVE, //Evlocallablcdarkness + LUMINANCECURVE, //Evlocallablclightness + LUMINANCECURVE, //Evlocallabsensilc + LUMINANCECURVE //Evlocallabdehaz }; diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 34088dc4c..52d0052bb 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -52,6 +52,7 @@ Locallab::Locallab(): exptonemap(new MyExpander(true, M("TP_LOCALLAB_TM"))), expreti(new MyExpander(true, M("TP_LOCALLAB_RETI"))), expsharp(new MyExpander(true, M("TP_LOCALLAB_SHARP"))), + expcontrast(new MyExpander(true, M("TP_LOCALLAB_LOC_CONTRAST"))), expcbdl(new MyExpander(true, M("TP_LOCALLAB_CBDL"))), expdenoi(new MyExpander(true, M("TP_LOCALLAB_DENOIS"))), @@ -99,13 +100,22 @@ Locallab::Locallab(): chrrt(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHRRT"), 0, 100, 1, 0))), neigh(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NEIGH"), 14, 150, 1, 50))), vart(Gtk::manage(new Adjuster(M("TP_LOCALLAB_VART"), 50, 500, 1, 200))), + dehaz(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DEHAZ"), 0, 100, 1, 0))), sensih(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIH"), 0, 100, 1, 19))), // Sharpening + sharcontrast(Gtk::manage(new Adjuster(M("TP_SHARPENING_CONTRAST"), 0, 200, 1, 20))), sharradius(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARRADIUS"), 42, 500, 1, 4))), - sharamount(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARAMOUNT"), 0, 100, 1, 75))), + sharamount(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARAMOUNT"), 0, 100, 1, 100))), shardamping(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARDAMPING"), 0, 100, 1, 75))), shariter(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SHARITER"), 5, 100, 1, 30))), sensisha(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIS"), 0, 100, 1, 19))), + //local contrast + lcradius(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_RADIUS"), 20, 200, 1, 80))), + lcamount(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_AMOUNT"), 0, 100, 1, 0))), + lcdarkness(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_DARKNESS"), 0, 300, 1, 100))), + lclightness(Gtk::manage(new Adjuster(M("TP_LOCALCONTRAST_LIGHTNESS"), 0, 300, 1, 100))), + sensilc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIS"), 0, 100, 1, 19))), + // Contrast by detail levels chromacbdl(Gtk::manage(new Adjuster(M("TP_LOCALLAB_CHROMACBDL"), 0, 300, 1, 0))), threshold(Gtk::manage(new Adjuster(M("TP_DIRPYREQUALIZER_THRESHOLD"), 0, 100, 1, 20))), @@ -449,6 +459,7 @@ Locallab::Locallab(): neigh->setAdjusterListener(this); vart->setAdjusterListener(this); + dehaz->setAdjusterListener(this); chrrt->setAdjusterListener(this); @@ -472,6 +483,7 @@ Locallab::Locallab(): retiBox->pack_start(*chrrt); retiBox->pack_start(*neigh); retiBox->pack_start(*vart); + retiBox->pack_start(*dehaz); retiBox->pack_start(*sensih); retiBox->pack_start(*LocalcurveEditorgainT, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor retiBox->pack_start(*inversret); @@ -484,6 +496,8 @@ Locallab::Locallab(): expsharp->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expsharp)); enablesharpConn = expsharp->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expsharp)); + sharcontrast->setAdjusterListener(this); + sharradius->setAdjusterListener(this); sharamount->setAdjusterListener(this); @@ -498,6 +512,7 @@ Locallab::Locallab(): inversshaConn = inverssha->signal_toggled().connect(sigc::mem_fun(*this, &Locallab::inversshaChanged)); ToolParamBlock* const sharpBox = Gtk::manage(new ToolParamBlock()); + sharpBox->pack_start(*sharcontrast); sharpBox->pack_start(*sharradius); sharpBox->pack_start(*sharamount); sharpBox->pack_start(*shardamping); @@ -509,6 +524,26 @@ Locallab::Locallab(): panel->pack_start(*expsharp, false, false); + //local contrast + expcontrast->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expcontrast)); + enablecontrastConn = expcontrast->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expcontrast)); + lcradius->setAdjusterListener(this); + lcamount->setAdjusterListener(this); + lcdarkness->setAdjusterListener(this); + lclightness->setAdjusterListener(this); + sensilc->setAdjusterListener(this); + + ToolParamBlock* const contrastBox = Gtk::manage(new ToolParamBlock()); + contrastBox->pack_start(*lcradius); + contrastBox->pack_start(*lcamount); + contrastBox->pack_start(*lcdarkness); + contrastBox->pack_start(*lclightness); + contrastBox->pack_start(*sensilc); + expcontrast->add(*contrastBox); + + expcontrast->setLevel(2); + + panel->pack_start(*expcontrast, false, false); // Contrast by detail levels expcbdl->signal_button_release_event().connect_notify(sigc::bind(sigc::mem_fun(this, &Locallab::foldAllButMe), expcbdl)); enablecbdlConn = expcbdl->signal_enabled_toggled().connect(sigc::bind(sigc::mem_fun(this, &Locallab::enableToggled), expcbdl)); @@ -631,6 +666,7 @@ void Locallab::foldAllButMe(GdkEventButton* event, MyExpander *expander) exptonemap->set_expanded(exptonemap == expander); expreti->set_expanded(expreti == expander); expsharp->set_expanded(expsharp == expander); + expcontrast->set_expanded(expcontrast == expander); expcbdl->set_expanded(expcbdl == expander); expdenoi->set_expanded(expdenoi == expander); @@ -659,6 +695,8 @@ void Locallab::enableToggled(MyExpander *expander) event = EvLocenareti; } else if (expander == expsharp) { event = EvLocenasharp; + } else if (expander == expcontrast) { + event = EvLocenacontrast; } else if (expander == expcbdl) { event = EvLocenacbdl; } else if (expander == expdenoi) { @@ -688,6 +726,7 @@ void Locallab::writeOptions(std::vector &tpOpen) tpOpen.push_back(exptonemap->get_expanded()); tpOpen.push_back(expreti->get_expanded()); tpOpen.push_back(expsharp->get_expanded()); + tpOpen.push_back(expcontrast->get_expanded()); tpOpen.push_back(expcbdl->get_expanded()); tpOpen.push_back(expdenoi->get_expanded()); @@ -695,7 +734,7 @@ void Locallab::writeOptions(std::vector &tpOpen) void Locallab::updateToolState(std::vector &tpOpen) { - if (tpOpen.size() >= 10) { + if (tpOpen.size() >= 11) { expsettings->setExpanded(tpOpen.at(0)); expcolor->set_expanded(tpOpen.at(1)); expexpose->set_expanded(tpOpen.at(2)); @@ -704,8 +743,9 @@ void Locallab::updateToolState(std::vector &tpOpen) exptonemap->set_expanded(tpOpen.at(5)); expreti->set_expanded(tpOpen.at(6)); expsharp->set_expanded(tpOpen.at(7)); - expcbdl->set_expanded(tpOpen.at(8)); - expdenoi->set_expanded(tpOpen.at(9)); + expcontrast->set_expanded(tpOpen.at(8)); + expcbdl->set_expanded(tpOpen.at(9)); + expdenoi->set_expanded(tpOpen.at(10)); } } @@ -864,12 +904,14 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) chrrt->setEditedState(pedited->locallab.chrrt ? Edited : UnEdited); neigh->setEditedState(pedited->locallab.neigh ? Edited : UnEdited); vart->setEditedState(pedited->locallab.vart ? Edited : UnEdited); + dehaz->setEditedState(pedited->locallab.dehaz ? Edited : UnEdited); sensih->setEditedState(pedited->locallab.sensih ? Edited : UnEdited); cTgainshape->setUnChanged(!pedited->locallab.localTgaincurve); inversret->set_inconsistent(multiImage && !pedited->locallab.inversret); // Sharpening expsharp->set_inconsistent(!pedited->locallab.expsharp); + sharcontrast->setEditedState(pedited->locallab.sharcontrast ? Edited : UnEdited); sharradius->setEditedState(pedited->locallab.sharradius ? Edited : UnEdited); sharamount->setEditedState(pedited->locallab.sharamount ? Edited : UnEdited); shardamping->setEditedState(pedited->locallab.shardamping ? Edited : UnEdited); @@ -877,6 +919,14 @@ void Locallab::read(const ProcParams* pp, const ParamsEdited* pedited) sensisha->setEditedState(pedited->locallab.sensisha ? Edited : UnEdited); inverssha->set_inconsistent(multiImage && !pedited->locallab.inverssha); + // local contrast + expcontrast->set_inconsistent(!pedited->locallab.expcontrast); + lcradius->setEditedState(pedited->locallab.lcradius ? Edited : UnEdited); + lcamount->setEditedState(pedited->locallab.lcamount ? Edited : UnEdited); + lcdarkness->setEditedState(pedited->locallab.lcdarkness ? Edited : UnEdited); + lclightness->setEditedState(pedited->locallab.lclightness ? Edited : UnEdited); + sensilc->setEditedState(pedited->locallab.sensilc ? Edited : UnEdited); + // Contrast by detail levels expcbdl->set_inconsistent(!pedited->locallab.expcbdl); @@ -1110,17 +1160,26 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.chrrt.push_back(0); pp->locallab.neigh.push_back(50); pp->locallab.vart.push_back(200); + pp->locallab.dehaz.push_back(0); pp->locallab.sensih.push_back(19); pp->locallab.localTgaincurve.push_back({(double)FCT_MinMaxCPoints, 0.0, 0.12, 0.35, 0.35, 0.70, 0.50, 0.35, 0.35, 1.00, 0.12, 0.35, 0.35}); pp->locallab.inversret.push_back(0); // Sharpening pp->locallab.expsharp.push_back(0); + pp->locallab.sharcontrast.push_back(20); pp->locallab.sharradius.push_back(40); - pp->locallab.sharamount.push_back(75); + pp->locallab.sharamount.push_back(100); pp->locallab.shardamping.push_back(75); pp->locallab.shariter.push_back(30); pp->locallab.sensisha.push_back(19); pp->locallab.inverssha.push_back(0); + //local contrast + pp->locallab.expcontrast.push_back(0); + pp->locallab.lcradius.push_back(80); + pp->locallab.lcamount.push_back(0); + pp->locallab.lcdarkness.push_back(100); + pp->locallab.lclightness.push_back(100); + pp->locallab.sensilc.push_back(19); // Contrast by detail levels pp->locallab.expcbdl.push_back(0); @@ -1241,17 +1300,26 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.chrrt.erase(pp->locallab.chrrt.begin() + i); pp->locallab.neigh.erase(pp->locallab.neigh.begin() + i); pp->locallab.vart.erase(pp->locallab.vart.begin() + i); + pp->locallab.dehaz.erase(pp->locallab.dehaz.begin() + i); pp->locallab.sensih.erase(pp->locallab.sensih.begin() + i); pp->locallab.localTgaincurve.erase(pp->locallab.localTgaincurve.begin() + i); pp->locallab.inversret.erase(pp->locallab.inversret.begin() + i); // Sharpening pp->locallab.expsharp.erase(pp->locallab.expsharp.begin() + i); + pp->locallab.sharcontrast.erase(pp->locallab.sharcontrast.begin() + i); pp->locallab.sharradius.erase(pp->locallab.sharradius.begin() + i); pp->locallab.sharamount.erase(pp->locallab.sharamount.begin() + i); pp->locallab.shardamping.erase(pp->locallab.shardamping.begin() + i); pp->locallab.shariter.erase(pp->locallab.shariter.begin() + i); pp->locallab.sensisha.erase(pp->locallab.sensisha.begin() + i); pp->locallab.inverssha.erase(pp->locallab.inverssha.begin() + i); + //local contrast + pp->locallab.expcontrast.erase(pp->locallab.expcontrast.begin() + i); + pp->locallab.lcradius.erase(pp->locallab.lcradius.begin() + i); + pp->locallab.lcamount.erase(pp->locallab.lcamount.begin() + i); + pp->locallab.lcdarkness.erase(pp->locallab.lcdarkness.begin() + i); + pp->locallab.lclightness.erase(pp->locallab.lcradius.begin() + i); + pp->locallab.sensilc.erase(pp->locallab.sensilc.begin() + i); // Contrast by detail levels pp->locallab.expcbdl.erase(pp->locallab.expcbdl.begin() + i); @@ -1449,17 +1517,26 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.chrrt.at(pp->locallab.selspot) = chrrt->getIntValue(); pp->locallab.neigh.at(pp->locallab.selspot) = neigh->getIntValue(); pp->locallab.vart.at(pp->locallab.selspot) = vart->getIntValue(); + pp->locallab.dehaz.at(pp->locallab.selspot) = dehaz->getIntValue(); pp->locallab.sensih.at(pp->locallab.selspot) = sensih->getIntValue(); pp->locallab.localTgaincurve.at(pp->locallab.selspot) = cTgainshape->getCurve(); pp->locallab.inversret.at(pp->locallab.selspot) = inversret->get_active(); // Sharpening pp->locallab.expsharp.at(pp->locallab.selspot) = (int)expsharp->getEnabled(); + pp->locallab.sharcontrast.at(pp->locallab.selspot) = sharcontrast->getIntValue(); pp->locallab.sharradius.at(pp->locallab.selspot) = sharradius->getIntValue(); pp->locallab.sharamount.at(pp->locallab.selspot) = sharamount->getIntValue(); pp->locallab.shardamping.at(pp->locallab.selspot) = shardamping->getIntValue(); pp->locallab.shariter.at(pp->locallab.selspot) = shariter->getIntValue(); pp->locallab.sensisha.at(pp->locallab.selspot) = sensisha->getIntValue(); pp->locallab.inverssha.at(pp->locallab.selspot) = (int)inverssha->get_active(); + //local contrast + pp->locallab.expcontrast.at(pp->locallab.selspot) = (int)expcontrast->getEnabled(); + pp->locallab.lcradius.at(pp->locallab.selspot) = lcradius->getIntValue(); + pp->locallab.lcamount.at(pp->locallab.selspot) = lcamount->getIntValue(); + pp->locallab.lcdarkness.at(pp->locallab.selspot) = lcdarkness->getIntValue(); + pp->locallab.lclightness.at(pp->locallab.selspot) = lclightness->getIntValue(); + pp->locallab.sensilc.at(pp->locallab.selspot) = sensilc->getIntValue(); // Contrast by detail levels pp->locallab.expcbdl.at(pp->locallab.selspot) = (int)expcbdl->getEnabled(); @@ -1572,17 +1649,26 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.chrrt = chrrt->getEditedState(); pedited->locallab.neigh = neigh->getEditedState(); pedited->locallab.vart = vart->getEditedState(); + pedited->locallab.dehaz = dehaz->getEditedState(); pedited->locallab.sensih = sensih->getEditedState(); pedited->locallab.localTgaincurve = !cTgainshape->isUnChanged(); pedited->locallab.inversret = !inversret->get_inconsistent(); // Sharpening pedited->locallab.expsharp = !expsharp->get_inconsistent(); + pedited->locallab.sharcontrast = sharcontrast->getEditedState(); pedited->locallab.sharradius = sharradius->getEditedState(); pedited->locallab.sharamount = sharamount->getEditedState(); pedited->locallab.shardamping = shardamping->getEditedState(); pedited->locallab.shariter = shariter->getEditedState(); pedited->locallab.sensisha = sensisha->getEditedState(); pedited->locallab.inverssha = !inverssha->get_inconsistent(); + //local contrast + pedited->locallab.expcontrast = !expcontrast->get_inconsistent(); + pedited->locallab.lcradius = lcradius->getEditedState(); + pedited->locallab.lcamount = lcamount->getEditedState(); + pedited->locallab.lcdarkness = lcdarkness->getEditedState(); + pedited->locallab.lclightness = lclightness->getEditedState(); + pedited->locallab.sensilc = sensilc->getEditedState(); // Contrast by detail levels pedited->locallab.expcbdl = !expcbdl->get_inconsistent(); @@ -1986,8 +2072,10 @@ void Locallab::inversretChanged() // Update Retinex GUI according to inversret button state (to be compliant with updateSpecificGUIState function) if (inversret->get_active()) { sensih->hide(); + dehaz->hide(); } else { sensih->show(); + dehaz->show(); } if (getEnabled() && expreti->getEnabled()) { @@ -2443,6 +2531,12 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } + if (a == dehaz) { + if (listener) { + listener->panelChanged(Evlocallabdehaz, dehaz->getTextValue()); + } + } + if (a == sensih) { if (listener) { listener->panelChanged(Evlocallabsensih, sensih->getTextValue()); @@ -2452,6 +2546,12 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) // Sharpening if (getEnabled() && expsharp->getEnabled()) { + if (a == sharcontrast) { + if (listener) { + listener->panelChanged(Evlocallabsharcontrast, sharcontrast->getTextValue()); + } + } + if (a == sharradius) { if (listener) { listener->panelChanged(Evlocallabsharradius, sharradius->getTextValue()); @@ -2483,6 +2583,39 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) } } + //local contrast + if (getEnabled() && expcontrast->getEnabled()) { + if (a == lcradius) { + if (listener) { + listener->panelChanged(Evlocallablcradius, lcradius->getTextValue()); + } + } + + if (a == lcamount) { + if (listener) { + listener->panelChanged(Evlocallablcamount, lcamount->getTextValue()); + } + } + + if (a == lcdarkness) { + if (listener) { + listener->panelChanged(Evlocallablcdarkness, lcdarkness->getTextValue()); + } + } + + if (a == lclightness) { + if (listener) { + listener->panelChanged(Evlocallablclightness, lclightness->getTextValue()); + } + } + + if (a == sensilc) { + if (listener) { + listener->panelChanged(Evlocallabsensilc, sensilc->getTextValue()); + } + } + } + // Contrast by detail levels if (getEnabled() && expcbdl->getEnabled()) { if (a == multiplier[0] || a == multiplier[1] || a == multiplier[2] || a == multiplier[3] || a == multiplier[4]) { @@ -2719,10 +2852,16 @@ void Locallab::setBatchMode(bool batchMode) sensiden->showEditedCB(); noisechroc->showEditedCB(); noiselumf->showEditedCB(); + sharcontrast->showEditedCB(); sharradius->showEditedCB(); sharamount->showEditedCB(); shardamping->showEditedCB(); shariter->showEditedCB(); + lcradius->showEditedCB(); + lcamount->showEditedCB(); + lcdarkness->showEditedCB(); + lclightness->showEditedCB(); + sensilc->showEditedCB(); sensisha->showEditedCB(); sensi->showEditedCB(); sensiex->showEditedCB(); @@ -2740,6 +2879,7 @@ void Locallab::setBatchMode(bool batchMode) str->showEditedCB(); neigh->showEditedCB(); vart->showEditedCB(); + dehaz->showEditedCB(); LocalcurveEditorgainT->setBatchMode(batchMode); llCurveEditorG->setBatchMode(batchMode); chrrt->showEditedCB(); @@ -2907,6 +3047,8 @@ void Locallab::enableListener() inversshaConn.block(false); // Contrast by detail levels enablecbdlConn.block(false); + //local contrast + enablecontrastConn.block(false); // Denoise enabledenoiConn.block(false); avoidConn.block(false); @@ -2944,6 +3086,8 @@ void Locallab::disableListener() inversshaConn.block(true); // Contrast by detail levels enablecbdlConn.block(true); + //local contrast + enablecontrastConn.block(true); // Denoise enabledenoiConn.block(true); avoidConn.block(true); @@ -3045,12 +3189,14 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, int chrrt->setValue(pp->locallab.chrrt.at(index)); neigh->setValue(pp->locallab.neigh.at(index)); vart->setValue(pp->locallab.vart.at(index)); + dehaz->setValue(pp->locallab.dehaz.at(index)); sensih->setValue(pp->locallab.sensih.at(index)); cTgainshape->setCurve(pp->locallab.localTgaincurve.at(index)); inversret->set_active((bool)pp->locallab.inversret.at(index)); // Sharpening expsharp->setEnabled((bool)pp->locallab.expsharp.at(index)); + sharcontrast->setValue(pp->locallab.sharcontrast.at(index)); sharradius->setValue(pp->locallab.sharradius.at(index)); sharamount->setValue(pp->locallab.sharamount.at(index)); shardamping->setValue(pp->locallab.shardamping.at(index)); @@ -3058,6 +3204,13 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, int sensisha->setValue(pp->locallab.sensisha.at(index)); inverssha->set_active((bool)pp->locallab.inverssha.at(index)); + //local contrast + expcontrast->setEnabled((bool)pp->locallab.expcontrast.at(index)); + lcradius->setValue(pp->locallab.lcradius.at(index)); + lcamount->setValue(pp->locallab.lcamount.at(index)); + lcdarkness->setValue(pp->locallab.lcdarkness.at(index)); + lclightness->setValue(pp->locallab.lclightness.at(index)); + sensilc->setValue(pp->locallab.sensilc.at(index)); // Contrast by detail levels expcbdl->setEnabled((bool)pp->locallab.expcbdl.at(index)); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index fb13027b0..18e278444 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -51,9 +51,10 @@ private: MyExpander* const exptonemap; MyExpander* const expreti; MyExpander* const expsharp; + MyExpander* const expcontrast; MyExpander* const expcbdl; MyExpander* const expdenoi; - sigc::connection enablecolorConn, enableexposeConn, enablevibranceConn, enableblurConn, enabletonemapConn, enableretiConn, enablesharpConn, enablecbdlConn, enabledenoiConn; + sigc::connection enablecolorConn, enableexposeConn, enablevibranceConn, enableblurConn, enabletonemapConn, enableretiConn, enablesharpConn, enablecontrastConn, enablecbdlConn, enabledenoiConn; // Curve widgets // Color & Light @@ -106,13 +107,21 @@ private: Adjuster* const chrrt; Adjuster* const neigh; Adjuster* const vart; + Adjuster* const dehaz; Adjuster* const sensih; // Sharpening + Adjuster* const sharcontrast; Adjuster* const sharradius; Adjuster* const sharamount; Adjuster* const shardamping; Adjuster* const shariter; Adjuster* const sensisha; + //local contrast + Adjuster* const lcradius; + Adjuster* const lcamount; + Adjuster* const lcdarkness; + Adjuster* const lclightness; + Adjuster* const sensilc; // Contrast by detail levels Adjuster* multiplier[5]; Adjuster* const chromacbdl; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 9da842519..1f6158e62 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -407,17 +407,26 @@ void ParamsEdited::set(bool v) locallab.chrrt = v; locallab.neigh = v; locallab.vart = v; + locallab.dehaz = v; locallab.sensih = v; locallab.localTgaincurve = v; locallab.inversret = v; // Sharpening locallab.expsharp = v; + locallab.sharcontrast = v; locallab.sharradius = v; locallab.sharamount = v; locallab.shardamping = v; locallab.shariter = v; locallab.sensisha = v; locallab.inverssha = v; + //local contrast + locallab.expcontrast = v; + locallab.lcradius = v; + locallab.lcamount = v; + locallab.lcdarkness = v; + locallab.lclightness = v; + locallab.sensilc = v; // Contrast by detail levels locallab.expcbdl = v; @@ -1090,17 +1099,26 @@ void ParamsEdited::initFrom(const std::vector& locallab.chrrt = locallab.chrrt && p.locallab.chrrt == other.locallab.chrrt; locallab.neigh = locallab.neigh && p.locallab.neigh == other.locallab.neigh; locallab.vart = locallab.vart && p.locallab.vart == other.locallab.vart; + locallab.dehaz = locallab.dehaz && p.locallab.dehaz == other.locallab.dehaz; locallab.sensih = locallab.sensih && p.locallab.sensih == other.locallab.sensih; locallab.localTgaincurve = locallab.localTgaincurve && p.locallab.localTgaincurve == other.locallab.localTgaincurve; locallab.inversret = locallab.inversret && p.locallab.inversret == other.locallab.inversret; // Sharpening locallab.expsharp = locallab.expsharp && p.locallab.expsharp == other.locallab.expsharp; + locallab.sharcontrast = locallab.sharcontrast && p.locallab.sharcontrast == other.locallab.sharcontrast; locallab.sharradius = locallab.sharradius && p.locallab.sharradius == other.locallab.sharradius; locallab.sharamount = locallab.sharamount && p.locallab.sharamount == other.locallab.sharamount; locallab.shardamping = locallab.shardamping && p.locallab.shardamping == other.locallab.shardamping; locallab.shariter = locallab.shariter && p.locallab.shariter == other.locallab.shariter; locallab.sensisha = locallab.sensisha && p.locallab.sensisha == other.locallab.sensisha; locallab.inverssha = locallab.inverssha && p.locallab.inverssha == other.locallab.inverssha; + //local contrast + locallab.expcontrast = locallab.expcontrast && p.locallab.expcontrast == other.locallab.expcontrast; + locallab.lcradius = locallab.lcradius && p.locallab.lcradius == other.locallab.lcradius; + locallab.lcamount = locallab.lcamount && p.locallab.lcamount == other.locallab.lcamount; + locallab.lcdarkness = locallab.lcdarkness && p.locallab.lcdarkness == other.locallab.lcdarkness; + locallab.lclightness = locallab.lclightness && p.locallab.lclightness == other.locallab.lclightness; + locallab.sensilc = locallab.sensilc && p.locallab.sensilc == other.locallab.sensilc; // Contrast by detail levels locallab.expcbdl = locallab.expcbdl && p.locallab.expcbdl == other.locallab.expcbdl; @@ -2792,6 +2810,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.vart = mods.locallab.vart; } + if (locallab.dehaz) { + toEdit.locallab.dehaz = mods.locallab.dehaz; + } + if (locallab.sensih) { toEdit.locallab.sensih = mods.locallab.sensih; } @@ -2809,6 +2831,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.expsharp = mods.locallab.expsharp; } + if (locallab.sharcontrast) { + toEdit.locallab.sharcontrast = mods.locallab.sharcontrast; + } + if (locallab.sharradius) { toEdit.locallab.sharradius = mods.locallab.sharradius; } @@ -2832,7 +2858,30 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng if (locallab.inverssha) { toEdit.locallab.inverssha = mods.locallab.inverssha; } + //local contrast + if (locallab.expcontrast) { + toEdit.locallab.expcontrast = mods.locallab.expcontrast; + } + if (locallab.lcradius) { + toEdit.locallab.lcradius = mods.locallab.lcradius; + } + + if (locallab.lcamount) { + toEdit.locallab.lcamount = mods.locallab.lcamount; + } + + if (locallab.lcdarkness) { + toEdit.locallab.lcdarkness = mods.locallab.lcdarkness; + } + + if (locallab.lclightness) { + toEdit.locallab.lclightness = mods.locallab.lclightness; + } + + if (locallab.sensilc) { + toEdit.locallab.sensilc = mods.locallab.sensilc; + } // Contrast by detail levels if (locallab.expcbdl) { toEdit.locallab.expcbdl = mods.locallab.expcbdl; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index ccfe404c6..13f8ecf84 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -537,17 +537,26 @@ public: bool chrrt; bool neigh; bool vart; + bool dehaz; bool sensih; bool localTgaincurve; bool inversret; // Sharpening bool expsharp; + bool sharcontrast; bool sharradius; bool sharamount; bool shardamping; bool shariter; bool sensisha; bool inverssha; + //local contrast + bool expcontrast; + bool lcradius; + bool lcamount; + bool lcdarkness; + bool lclightness; + bool sensilc; // Contrast by detail levels bool expcbdl; bool mult[5];