From 5a0242718c68a7fe21c9ecdc7d5cf2505ac75169 Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 30 Jan 2019 13:55:04 +0100 Subject: [PATCH] Add forgotten inversecolorlight to deltaE --- rtengine/improcfun.h | 2 +- rtengine/iplocallab.cc | 327 ++++------------------------------------- rtgui/locallab.cc | 14 ++ 3 files changed, 41 insertions(+), 302 deletions(-) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 863749f37..74b8bb584 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -309,7 +309,7 @@ public: void fftw_denoise(int GW, int GH, int max_numblox_W, int min_numblox_W, float **tmp1, array2D *Lin, int numThreads, const struct local_params & lp, int chrom); void ColorLight_Local(float moddE, float powdE, int call, LabImage * bufcolorig, LabImage * originalmask, float **buflight, float **bufchro, float **bufchroslid, float ** bufhh, float ** buflightslid, bool &LHutili, bool &HHutili, const float hueplus, const float huemoins, const float hueref, const float dhue, const float chromaref, const float lumaref, float sobelref, float ** blend2, LUTf & lllocalcurve, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, LUTf & lightCurveloc, const local_params& lp, LabImage* original, LabImage* transformed, int cx, int cy, int sk); - 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 InverseColorLight_Local(const struct local_params& lp, LUTf & lightCurveloc, LabImage* original, LabImage* transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk); void Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, 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); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 48bfb8140..139b40468 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -4075,78 +4075,16 @@ void ImProcFunctions::transit_shapedetect(int senstype, LabImage * bufexporig, L } } -void ImProcFunctions::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 ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LUTf & lightCurveloc, LabImage * original, LabImage * transformed, int cx, int cy, const float hueref, const float chromaref, const float lumaref, int sk) { // BENCHFUN float ach = (float)lp.trans / 100.f; const float facc = (100.f + lp.chro) / 100.f; //chroma factor transition - //chroma - constexpr float amplchsens = 2.5f; - constexpr float achsens = (amplchsens - 1.f) / (100.f - 20.f); //20. default locallab.sensi - constexpr float bchsens = 1.f - 20.f * achsens; - const float multchro = lp.sens * achsens + bchsens; - - //luma - constexpr float ampllumsens = 2.f; - constexpr float alumsens = (ampllumsens - 1.f) / (100.f - 20.f); //20. default locallab.sensi - constexpr float blumsens = 1.f - 20.f * alumsens; - const float multlum = lp.sens * alumsens + blumsens; - - //skin - constexpr float amplchsensskin = 1.6f; - constexpr float achsensskin = (amplchsensskin - 1.f) / (100.f - 20.f); //20. default locallab.sensi - constexpr float bchsensskin = 1.f - 20.f * achsensskin; - const float multchroskin = lp.sens * achsensskin + bchsensskin; - - //transition = difficult to avoid artifact with scope on flat area (sky...) - constexpr float delhu = 0.05f; //between 0.05 and 0.2 ==> minima for scope - - const float aplus = (1.f - lp.chro) / delhu; - const float bplus = 1.f - aplus * hueplus; - const float amoins = (lp.chro - 1.f) / delhu; - const float bmoins = 1.f - amoins * huemoins; - - const float apl = (-1.f) / delhu; - const float bpl = - apl * hueplus; - const float amo = 1.f / delhu; - const float bmo = - amo * huemoins; - - const float pb = 4.f; - const float pa = (1.f - pb) / 40.f; - - const float ahu = 1.f / (2.8f * lp.sens - 280.f); - const float bhu = 1.f - ahu * 2.8f * lp.sens; - - //luma - constexpr float lumdelta = 11.f; //11 - float modlum = lumdelta * multlum; - - // constant and variables to prepare shape detection - if (lumaref + modlum >= 100.f) { - modlum = (100.f - lumaref) / 2.f; - } - - if (lumaref - modlum <= 0.f) { - modlum = (lumaref) / 2.f; - } - - float aa, bb, aaa, bbb, ccc; - float reducac = settings->reduchigh;//0.85f; - float reducac2 = settings->reduclow;//0.2f; - - float vinf = (lumaref + modlum) / 100.f; - float vi = (lumaref - modlum) / 100.f; - ImProcFunctions::secondeg_begin(reducac, vi, aa, bb); //parabolic - ImProcFunctions::secondeg_end(reducac, vinf, aaa, bbb, ccc); //parabolic - float vinf2 = (lumaref + modlum) / 100.f; - float vi2 = (lumaref - modlum) / 100.f; - float aaaa, bbbb, cccc, aO, bO; - ImProcFunctions::secondeg_end(reducac2, vinf2, aaaa, bbbb, cccc); //parabolic - ImProcFunctions::secondeg_begin(reducac2, vi2, aO, bO); //parabolic - int GW = transformed->W; int GH = transformed->H; + float refa = chromaref * cos(hueref); + float refb = chromaref * sin(hueref); LabImage *origblur = nullptr; @@ -4213,246 +4151,44 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU #ifdef __SSE2__ - float rhue = atan2Buffer[x]; - float rchro = sqrtBuffer[x]; +// float rhue = atan2Buffer[x]; +// float rchro = sqrtBuffer[x]; #else - float rhue = xatan2f(origblur->b[y][x], origblur->a[y][x]); +// float rhue = xatan2f(origblur->b[y][x], origblur->a[y][x]); - float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; +// float rchro = sqrt(SQR(origblur->b[y][x]) + SQR(origblur->a[y][x])) / 327.68f; #endif float rL = origblur->L[y][x] / 327.68f; - float rLL = origblur->L[y][x] / 327.68f; if (fabs(origblur->b[y][x]) < 0.01f) { origblur->b[y][x] = 0.01f; } + float dE = 0.f; + dE = sqrt(SQR(refa - origblur->a[y][x] / 327.68f) + SQR(refb - origblur->b[y][x] / 327.68f) + SQR(lumaref - rL)); - float realchro = 1.f; - //evaluate delta Hue and delta Chro - float deltachro = fabs(rchro - chromaref); + float reducdE = 0.f; + float mindE = 2.f + 0.05f * lp.sens;//between 2 and 7 + float maxdE = 5.f + 1.5f * lp.sens; // between 5 and 150, we can chnage this values - float deltahue = fabs(rhue - hueref); + float ar = 1.f / (mindE - maxdE); - if (deltahue > rtengine::RT_PI) { - deltahue = - (deltahue - 2.f * rtengine::RT_PI); + float br = - ar * maxdE; + + if (dE > maxdE) { + reducdE = 0.f; } - //pseudo deltaE - float deltaE = 20.f * deltahue + deltachro; //pseudo deltaE between 0 and 280 - float deltaL = fabs(lumaref - rL); //between 0 and 100 - - float kch = 1.f; - float khu = 0.f; - float fach = 1.f; - float falu = 1.f; - - //kch acts on luma - if (deltachro < 160.f * SQR(lp.sens / 100.f)) { - kch = 1.f; - } else { - float ck = 160.f * SQR(lp.sens / 100.f); - float ak = 1.f / (ck - 160.f); - float bk = -160.f * ak; - kch = ak * deltachro + bk; + if (dE > mindE && dE <= maxdE) { + reducdE = ar * dE + br; } - if (lp.sens < 40.f) { - kch = pow(kch, pa * lp.sens + pb); //increase under 40 + if (dE <= mindE) { + reducdE = 1.f; } - bool kzon = false; - - if ((hueref - dhue) > -rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { - if (rhue >= hueplus - delhu && rhue < hueplus) { - realchro = aplus * rhue + bplus; - khu = apl * rhue + bpl; - - } else if (rhue >= huemoins && rhue < huemoins + delhu) { - realchro = amoins * rhue + bmoins; - khu = amo * rhue + bmo; - - } else { - realchro = lp.chro; - khu = 1.f; - } - - kzon = true; - } else if ((hueref - dhue) <= -rtengine::RT_PI && (rhue > huemoins || rhue < hueplus)) { - if (rhue >= hueplus - delhu && rhue < hueplus) { - realchro = aplus * rhue + bplus; - khu = apl * rhue + bpl; - - } else if (rhue >= huemoins && rhue < huemoins + delhu) { - realchro = amoins * rhue + bmoins; - khu = amo * rhue + bmo; - - } else { - realchro = lp.chro; - khu = 1.f; - } - - kzon = true; - } - - if ((hueref - dhue) > -rtengine::RT_PI && rhue < hueplus && rhue > huemoins) { - if (rhue >= hueplus - delhu && rhue < hueplus) { - realchro = aplus * rhue + bplus; - khu = apl * rhue + bpl; - - } else if (rhue >= huemoins && rhue < huemoins + delhu) { - realchro = amoins * rhue + bmoins; - khu = amo * rhue + bmo; - - } else { - realchro = lp.chro; - khu = 1.f; - } - - kzon = true; - } else if ((hueref - dhue) <= -rtengine::RT_PI && (rhue > huemoins || rhue < hueplus)) { - if (rhue >= hueplus - delhu && rhue < hueplus) { - realchro = aplus * rhue + bplus; - khu = apl * rhue + bpl; - - } else if (rhue >= huemoins && rhue < huemoins + delhu) { - realchro = amoins * rhue + bmoins; - khu = amo * rhue + bmo; - - } else { - realchro = lp.chro; - khu = 1.f; - } - - kzon = true; - } - - if (lp.sens <= 20.f) { //to try... - //fach and kch acts on luma - if (deltaE < 2.8f * lp.sens) { - fach = khu; - } else { - fach = khu * (ahu * deltaE + bhu); - } - - float kcr = 10.f; - - if (rchro < kcr) { - fach *= (1.f / (kcr * kcr)) * rchro * rchro; - } - - //can be probably improved - if (lp.qualmet >= 1) { - } else { - fach = 1.f; - } - - //falu acts on chroma - if (deltaL < lp.sens) { - falu = 1.f; - } else { - falu = 1.f;// alum * deltaL + blum; - } - - } - - if (kzon) { - if (lp.sens < 60.f) { //arbitrary value - if (hueref < -1.1f && hueref > -2.8f) { // detect blue sky - if (chromaref > 0.f && chromaref < 35.f * multchro) { // detect blue sky - if ((rhue > -2.79f && rhue < -1.11f) && (rchro < 35.f * multchro)) { - realchro *= 0.9f; - } else { - realchro = 1.f; - - } - } - } else { - realchro = lp.chro; - - } - - if (lp.sens < 50.f && lp.chro > 0.f) { - if (hueref > -0.1f && hueref < 1.6f) { // detect skin - if (chromaref > 0.f && chromaref < 55.f * multchroskin) { // detect skin - if ((rhue > -0.09f && rhue < 1.59f) && (rchro < 55.f * multchroskin)) { - realchro *= 0.9f; - - } else { - realchro = 1.f; - - } - } - } else { - realchro = lp.chro; - - } - } - } - - } - - float kLinf = rLL / (100.f); - float kLsup = kLinf; - - float kdiff = 1.f; - - if (kzon) { ///rhue < hueplus && rhue > huemoins - - if ((rLL > (lumaref - modlum) && rLL < (lumaref + modlum))) { - kdiff = 1.f; - } else if (rLL > 0.f && rLL <= (lumaref - modlum)) { - kdiff = (aa * kLinf * kLinf + bb * kLinf); //parabolic - - if (kdiff < 0.01f) { - kdiff = 0.01f; - } - } else if (rLL <= 100.f && rLL >= (lumaref + modlum)) { - - kdiff = (aaa * kLsup * kLsup + bbb * kLsup + ccc); //parabolic - - if (kdiff < 0.01f) { - kdiff = 0.01f; - } - - } - - //end luma - } else { - float ktes = 1.f; - - if ((rLL > (lumaref - modlum) && rLL < (lumaref + modlum))) { - kdiff = ktes; - } else if (rLL > 0.f && rLL <= (lumaref - modlum)) { - - kdiff = (ktes * (aO * kLinf * kLinf + bO * kLinf)); //parabolic - - if (kdiff < 0.01f) { - kdiff = 0.01f; - } - - } else if (rLL <= 100.f && rLL >= (lumaref + modlum)) { - - kdiff = (ktes * (aaaa * kLsup * kLsup + bbbb * kLsup + cccc)); //parabolic - - if (kdiff < 0.01f) { - kdiff = 0.01f; - } - - } - - } - - float kcr = 100.f * lp.thr; - float falL = 1.f; - - if (rchro < kcr && chromaref > kcr) { // reduce artifacts in grey tones near hue spot and improve algorithm - falL *= pow(rchro / kcr, lp.iterat / 10.f); - } - - float th_r = 0.01f; if (rL > th_r) { //to avoid crash with very low gamut in rare cases ex : L=0.01 a=0.5 b=-0.9 @@ -4480,13 +4216,8 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU } float factorx = 1.f - localFactor; - float fli = 1.f; - float flisl = 1.f; - float flicur = 1.f; - float fac = flicur * (100.f + factorx * realchro * falu * falL) / 100.f; //chroma factor transition - float diflc = lightcont * fli * flisl - original->L[y][x]; - kdiff *= fach * kch; - diflc *= kdiff ; + float fac = (100.f + factorx * lp.chro * reducdE) / 100.f; //chroma factor transition + float diflc = (lightcont - original->L[y][x]) * reducdE; diflc *= factorx; //transition lightness transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); @@ -4531,15 +4262,9 @@ void ImProcFunctions::InverseColorLight_Local(const struct local_params & lp, LU lightcont = lumnew; } - float fli = 1.f; - float flisl = 1.f; - float flicur = 1.f; - float fac = flicur * (100.f + realchro * falu * falL) / 100.f; //chroma factor transition7 + float fac = (100.f + lp.chro * reducdE) / 100.f; //chroma factor transition + float diflc = (lightcont - original->L[y][x]) * reducdE; - float diflc = lightcont * fli * flisl - original->L[y][x]; - - kdiff *= fach * kch; - diflc *= kdiff ; transformed->L[y][x] = CLIP(1.f * (original->L[y][x] + diflc)); transformed->a[y][x] = CLIPC(original->a[y][x] * fac) ; @@ -8673,7 +8398,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o huemoins = hueref - dhue + 2.f * rtengine::RT_PI; } - InverseColorLight_Local(lp, lightCurveloc, original, transformed, cx, cy, hueplus, huemoins, hueref, dhue, chromaref, lumaref, sk); + InverseColorLight_Local(lp, lightCurveloc, original, transformed, cx, cy, hueref, chromaref, lumaref, sk); } // Gamut and Munsell control - very important do not desactivated to avoid crash diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 51c1f1345..0a34d8df4 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -2306,6 +2306,8 @@ void Locallab::inversChanged() qualitycurveMethod->show(); labqualcurv->show(); maskcolFrame->show(); + structcol->show(); + blurcolde->show(); showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } else if (invers->get_active()) { sensi->show(); @@ -2314,6 +2316,9 @@ void Locallab::inversChanged() qualitycurveMethod->hide(); labqualcurv->hide(); maskcolFrame->hide(); + structcol->hide(); + blurcolde->hide(); + } else { sensi->show(); llCurveEditorG->show(); @@ -2321,6 +2326,9 @@ void Locallab::inversChanged() qualitycurveMethod->show(); labqualcurv->show(); maskcolFrame->show(); + structcol->show(); + blurcolde->show(); + if (batchMode) { showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } @@ -3974,6 +3982,8 @@ void Locallab::updateSpecificGUIState() qualitycurveMethod->show(); labqualcurv->show(); maskcolFrame->show(); + structcol->show(); + blurcolde->show(); showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode } else if (invers->get_active()) { sensi->show(); @@ -3982,6 +3992,8 @@ void Locallab::updateSpecificGUIState() qualitycurveMethod->hide(); labqualcurv->hide(); maskcolFrame->hide(); + structcol->hide(); + blurcolde->hide(); } else { sensi->show(); llCurveEditorG->show(); @@ -3989,6 +4001,8 @@ void Locallab::updateSpecificGUIState() qualitycurveMethod->show(); labqualcurv->show(); maskcolFrame->show(); + structcol->show(); + blurcolde->show(); if (batchMode) { showmaskcolMethod->hide(); // Being able to change Color & Light mask visibility is useless in batch mode }