From d0e65ec93c3cf57afe0bfc2860a795fc13592fb4 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 06:59:17 +0200 Subject: [PATCH 01/12] Change history_msg --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index b545b2b7d..515e35b43 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -814,7 +814,7 @@ HISTORY_MSG_BLSHAPE;Blur by level HISTORY_MSG_WAVBL;Blur levels HISTORY_MSG_BLURWAV;Blur luminance HISTORY_MSG_BLURCWAV;Blur chroma -HISTORY_MSG_EDGEFFECT;Edge Effect +HISTORY_MSG_EDGEFFECT;Edge Damper HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOT;Snapshot From 2d52fbdcefdb886b60515962d26f013ef9adbe71 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 10:28:45 +0200 Subject: [PATCH 02/12] Improve wavelet levels with denoise chroma --- rtdata/languages/default | 2 +- rtengine/ipwavelet.cc | 641 +++++++++++++++++++++------------------ rtgui/wavelet.cc | 16 +- 3 files changed, 352 insertions(+), 307 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 515e35b43..4a181324d 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2307,7 +2307,7 @@ TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will b TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. TP_WAVELET_THRESWAV;Balance Threshold TP_WAVELET_THRH;Highlights threshold -TP_WAVELET_TILESBIG;Big tiles +TP_WAVELET_TILESBIG;Tiles TP_WAVELET_TILESFULL;Full image TP_WAVELET_TILESIZE;Tiling method TP_WAVELET_TILESLIT;Little tiles diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index e58ad3733..79302c452 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -399,8 +399,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.til = waparams.edgthresh; cp.eff = waparams.edgeffect; cp.balchrom = waparams.balchrom; - cp.chromfi = waparams.chromfi; - cp.chromco = waparams.chromco; + cp.chromfi = 0.1f * waparams.chromfi; + cp.chromco = 0.1f * waparams.chromco; cp.conres = waparams.rescon; cp.conresH = waparams.resconH; @@ -522,11 +522,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (params->wavelet.Tilesmethod == "big") { realtile = 22; } - +/* if (params->wavelet.Tilesmethod == "lit") { realtile = 12; } - +*/ int tilesize = 128 * realtile; int overlap = (int) tilesize * 0.125f; int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; @@ -667,6 +667,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const varhue[i] = new float[tilewidth]; } + + #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) #endif @@ -825,21 +827,28 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavL < 7) { + levwavL = 7; + } + } + if (levwavL < 4) { levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! } if (levwavL > 0) { const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + float madL[8][3]; if (!Ldecomp->memoryAllocationFailed) { - float madL[8][3]; + // float madL[8][3]; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1) #endif - for (int lvl = 0; lvl < 4; lvl++) { + for (int lvl = 0; lvl < levwavL; lvl++) { for (int dir = 1; dir < 4; dir++) { int Wlvl_L = Ldecomp->level_W(lvl); int Hlvl_L = Ldecomp->level_H(lvl); @@ -908,301 +917,336 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const WaveletcontAllLfinal(*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL); //Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + /* + Ldecomp->reconstruct(labco->data, cp.strength); + } + } + */ + + + float variC[7]; + float variCb[7]; + + float noisecfr = cp.chromfi; + float noiseccr = cp.chromco; + + if (cp.balchrom > 0.f) { + noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f); + noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f); + } + + float noisecfb = cp.chromfi; + float noiseccb = cp.chromco; + + if (cp.balchrom < 0.f) { + noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f); + noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f); + } + + + if (noisecfr < 0.f) { + noisecfr = 0.0001f; + } + + if (noiseccr < 0.f) { + noiseccr = 0.0001f; + } + + if (noisecfb < 0.f) { + noisecfb = 0.0001f; + } + + if (noiseccb < 0.f) { + noiseccb = 0.0001f; + } + + int edge = 2; + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); + + variC[3] = SQR(noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(noiseccr); + variC[6] = SQR(noiseccr); + + variCb[0] = SQR(noisecfb); + variCb[1] = SQR(noisecfb); + variCb[2] = SQR(noisecfb); + + variCb[3] = SQR(noisecfb); + variCb[4] = SQR(noisecfb); + variCb[5] = SQR(noiseccb); + variCb[6] = SQR(noiseccb); + + float k1 = 0.f; + float k2 = 0.f; + float k3 = 0.f; + + if (cp.chromfi < 0.2f) { + k1 = 0.f; + k2 = 0.f; + k3 = 0.f; + } else if (cp.chromfi < 0.3f) { + k1 = 0.1f; + k2 = 0.0f; + k3 = 0.f; + } else if (cp.chromfi < 0.5f) { + k1 = 0.2f; + k2 = 0.1f; + k3 = 0.f; + } else if (cp.chromfi < 0.8f) { + k1 = 0.3f; + k2 = 0.25f; + k3 = 0.f; + } else if (cp.chromfi < 1.f) { + k1 = 0.4f; + k2 = 0.25f; + k3 = 0.1f; + } else if (cp.chromfi < 2.f) { + k1 = 0.5f; + k2 = 0.3f; + k3 = 0.15f; + } else if (cp.chromfi < 3.f) { + k1 = 0.6f; + k2 = 0.45f; + k3 = 0.3f; + } else if (cp.chromfi < 4.f) { + k1 = 0.7f; + k2 = 0.5f; + k3 = 0.4f; + } else if (cp.chromfi < 5.f) { + k1 = 0.8f; + k2 = 0.6f; + k3 = 0.5f; + } else if (cp.chromfi < 6.f) { + k1 = 0.85f; + k2 = 0.7f; + k3 = 0.6f; + } else if (cp.chromfi < 8.f) { + k1 = 0.9f; + k2 = 0.8f; + k3 = 0.7f; + } else if (cp.chromfi < 10.f) { + k1 = 1.f; + k2 = 1.f; + k3 = 0.9f; + + } else { + k1 = 1.f; + k2 = 1.f; + k3 = 1.f; + } + + float minic = 0.0001f; + variC[0] = max(minic, variC[0]); + variC[1] = max(minic, k1 * variC[1]); + variC[2] = max(minic, k2 * variC[2]); + variC[3] = max(minic, k3 * variC[3]); + + variCb[0] = max(minic, variCb[0]); + variCb[1] = max(minic, k1 * variCb[1]); + variCb[2] = max(minic, k2 * variCb[2]); + variCb[3] = max(minic, k3 * variCb[3]); + + float k4 = 0.f; + float k5 = 0.f; + float k6 = 0.f; + + if (cp.chromco == 0.01f) { + k4 = 0.f; + k5 = 0.0f; + } else if (cp.chromco < 0.2f) { + k4 = 0.1f; + k5 = 0.0f; + } else if (cp.chromco < 0.5f) { + k4 = 0.15f; + k5 = 0.0f; + } else if (cp.chromco < 1.f) { + k4 = 0.15f; + k5 = 0.1f; + } else if (cp.chromco < 3.f) { + k4 = 0.3f; + k5 = 0.15f; + } else if (cp.chromco < 4.f) { + k4 = 0.6f; + k5 = 0.4f; + } else if (cp.chromco < 6.f) { + k4 = 0.8f; + k5 = 0.6f; + } else { + k4 = 1.f; + k5 = 1.f; + } + + variC[4] = max(0.0001f, k4 * variC[4]); + variC[5] = max(0.0001f, k5 * variC[5]); + variCb[4] = max(0.0001f, k4 * variCb[4]); + variCb[5] = max(0.0001f, k5 * variCb[5]); + + if (cp.chromco < 4.f) { + k6 = 0.f; + } else if (cp.chromco < 5.f) { + k6 = 0.4f; + } else if (cp.chromco < 6.f) { + k6 = 0.7f; + } else { + k6 = 1.f; + } + + variC[6] = max(0.0001f, k6 * variC[6]); + variCb[6] = max(0.0001f, k6 * variCb[6]); +/* + for (int y = 0; y < 7; y++) { + printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); + } +*/ + float nvch = 0.6f;//high value + float nvcl = 0.1f;//low value + + if (cp.chromco > 30.f) { + nvch = 0.8f; + nvcl = 0.4f; + } + + float seuil = 4000.f;//low + float seuil2 = 15000.f;//high + //ac and bc for transition + float ac = (nvch - nvcl) / (seuil - seuil2); + float bc = nvch - seuil * ac; + int GW = labco->W; + int GH = labco->H; + float* noisevarchrom = new float[GH * GW]; + //noisevarchrom in function chroma + int GW2 = (GW + 1) / 2; + float noisevarab_r = 100.f; + + for (int ir = 0; ir < GH; ir++) + for (int jr = 0; jr < GW; jr++) { + float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr])); + + if (cN < seuil) { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch; + } else if (cN < seuil2) { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc; + } else { + noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl; + } + } + + + //Flat curve for H=f(H) in residual image + FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H) + bool hhutili = false; + + if (!hhCurve || hhCurve->isIdentity()) { + if (hhCurve) { + delete hhCurve; + hhCurve = nullptr; + } + } else { + hhutili = true; + } + + + if (!hhutili) { //always a or b + int levwava = levwav; + + if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f)) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { + levwava--; + } + } + + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwava < 7) { + levwava = 7; + } + } + + if (levwava > 0) { + const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!adecomp->memoryAllocationFailed) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + adecomp->reconstruct(labco->data + datalen, cp.strength); + } + } + + int levwavb = levwav; + + if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f)) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { + levwavb--; + } + } + + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavb < 7) { + levwavb = 7; + } + } + + if (levwavb > 0) { + const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!bdecomp->memoryAllocationFailed) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); + } + } + } else {// a and b + int levwavab = levwav; + + if (cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels + while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { + levwavab--; + } + } + if (cp.chromfi > 0.f || cp.chromco > 0.f) { + if (levwavab < 7) { + levwavab = 7; + } + } + + if (levwavab > 0) { + const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); + + if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); + + adecomp->reconstruct(labco->data + datalen, cp.strength); + bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); + + } + } + } + + delete[] noisevarchrom; + + if (hhCurve) { + delete hhCurve; + } Ldecomp->reconstruct(labco->data, cp.strength); } } - - /* - float variC[7]; - float variCb[7]; - - float noisecfr = cp.chromfi; - float noiseccr = cp.chromco; - - if (cp.balchrom > 0.f) { - noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f); - noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f); - } - - float noisecfb = cp.chromfi; - float noiseccb = cp.chromco; - - if (cp.balchrom < 0.f) { - noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f); - noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f); - } - - - if (noisecfr < 0.f) { - noisecfr = 0.0001f; - } - - if (noiseccr < 0.f) { - noiseccr = 0.0001f; - } - - if (noisecfb < 0.f) { - noisecfb = 0.0001f; - } - - if (noiseccb < 0.f) { - noiseccb = 0.0001f; - } - - int edge = 2; - variC[0] = SQR(noisecfr); - variC[1] = SQR(noisecfr); - variC[2] = SQR(noisecfr); - - variC[3] = SQR(noisecfr); - variC[4] = SQR(noisecfr); - variC[5] = SQR(noiseccr); - variC[6] = SQR(noiseccr); - - variCb[0] = SQR(noisecfb); - variCb[1] = SQR(noisecfb); - variCb[2] = SQR(noisecfb); - - variCb[3] = SQR(noisecfb); - variCb[4] = SQR(noisecfb); - variCb[5] = SQR(noiseccb); - variCb[6] = SQR(noiseccb); - - float k1 = 0.f; - float k2 = 0.f; - float k3 = 0.f; - - if (cp.chromfi) { - k1 = 0.f; - k2 = 0.f; - k3 = 0.f; - } else if (cp.chromfi < 0.3f) { - k1 = 0.1f; - k2 = 0.0f; - k3 = 0.f; - } else if (cp.chromfi < 0.5f) { - k1 = 0.2f; - k2 = 0.1f; - k3 = 0.f; - } else if (cp.chromfi < 0.8f) { - k1 = 0.3f; - k2 = 0.25f; - k3 = 0.f; - } else if (cp.chromfi < 1.f) { - k1 = 0.4f; - k2 = 0.25f; - k3 = 0.1f; - } else if (cp.chromfi < 2.f) { - k1 = 0.5f; - k2 = 0.3f; - k3 = 0.15f; - } else if (cp.chromfi < 3.f) { - k1 = 0.6f; - k2 = 0.45f; - k3 = 0.3f; - } else if (cp.chromfi < 4.f) { - k1 = 0.7f; - k2 = 0.5f; - k3 = 0.4f; - } else if (cp.chromfi < 5.f) { - k1 = 0.8f; - k2 = 0.6f; - k3 = 0.5f; - } else if (cp.chromfi < 10.f) { - k1 = 0.85f; - k2 = 0.7f; - k3 = 0.6f; - } else if (cp.chromfi < 20.f) { - k1 = 0.9f; - k2 = 0.8f; - k3 = 0.7f; - } else if (cp.chromfi < 50.f) { - k1 = 1.f; - k2 = 1.f; - k3 = 0.9f; - - } else { - k1 = 1.f; - k2 = 1.f; - k3 = 1.f; - } - - float minic = 0.0001f; - variC[0] = max(minic, variC[0]); - variC[1] = max(minic, k1 * variC[1]); - variC[2] = max(minic, k2 * variC[2]); - variC[3] = max(minic, k3 * variC[3]); - - variCb[0] = max(minic, variCb[0]); - variCb[1] = max(minic, k1 * variCb[1]); - variCb[2] = max(minic, k2 * variCb[2]); - variCb[3] = max(minic, k3 * variCb[3]); - - float k4 = 0.f; - float k5 = 0.f; - float k6 = 0.f; - - if (cp.chromco == 0.01f) { - k4 = 0.f; - k5 = 0.0f; - } else if (cp.chromco < 0.2f) { - k4 = 0.1f; - k5 = 0.0f; - } else if (cp.chromco < 0.5f) { - k4 = 0.15f; - k5 = 0.0f; - } else if (cp.chromco < 1.f) { - k4 = 0.15f; - k5 = 0.1f; - } else if (cp.chromco < 3.f) { - k4 = 0.3f; - k5 = 0.15f; - } else if (cp.chromco < 4.f) { - k4 = 0.6f; - k5 = 0.4f; - } else if (cp.chromco < 6.f) { - k4 = 0.8f; - k5 = 0.6f; - } else { - k4 = 1.f; - k5 = 1.f; - } - - variC[4] = max(0.0001f, k4 * variC[4]); - variC[5] = max(0.0001f, k5 * variC[5]); - variCb[4] = max(0.0001f, k4 * variCb[4]); - variCb[5] = max(0.0001f, k5 * variCb[5]); - - if (cp.chromco < 4.f) { - k6 = 0.f; - } else if (cp.chromco < 5.f) { - k6 = 0.4f; - } else if (cp.chromco < 6.f) { - k6 = 0.7f; - } else { - k6 = 1.f; - } - - variC[6] = max(0.0001f, k6 * variC[6]); - variCb[6] = max(0.0001f, k6 * variCb[6]); - float nvch = 0.6f;//high value - float nvcl = 0.1f;//low value - - if (cp.chromco > 100.f) { - nvch = 0.8f; - nvcl = 0.4f; - } - - float seuil = 4000.f;//low - float seuil2 = 15000.f;//high - //ac and bc for transition - float ac = (nvch - nvcl) / (seuil - seuil2); - float bc = nvch - seuil * ac; - int GW = labco->W; - int GH = labco->H; - float* noisevarchrom = new float[GH * GW]; - //noisevarchrom in function chroma - int GW2 = (GW + 1) / 2; - float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0); - for (int ir = 0; ir < GH; ir++) - for (int jr = 0; jr < GW; jr++) { - float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr])); - - if (cN < seuil) { - noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch; - } else if (cN < seuil2) { - noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc; - } else { - noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl; - } - } - */ - - //Flat curve for H=f(H) in residual image - FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H) - bool hhutili = false; - - if (!hhCurve || hhCurve->isIdentity()) { - if (hhCurve) { - delete hhCurve; - hhCurve = nullptr; - } - } else { - hhutili = true; - } - - - if (!hhutili) { //always a or b - int levwava = levwav; - - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels - while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f)) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { - levwava--; - } - } - - if (levwava > 0) { - const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - - if (!adecomp->memoryAllocationFailed) { - Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); - adecomp->reconstruct(labco->data + datalen, cp.strength); - } - } - - int levwavb = levwav; - - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels - while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f)) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { - levwavb--; - } - } - - if (levwavb > 0) { - const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - - if (!bdecomp->memoryAllocationFailed) { - Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); - bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); - } - } - } else {// a and b - int levwavab = levwav; - - if (cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels - while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { - levwavab--; - } - } - - if (levwavab > 0) { - const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); - - if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); - Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); - WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); - - adecomp->reconstruct(labco->data + datalen, cp.strength); - bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); - - } - } - } - - // delete[] noisevarchrom; - - if (hhCurve) { - delete hhCurve; - } - if (numtiles > 1 || (numtiles == 1 /*&& cp.avoi*/)) { //in all case since I add contrast curve //calculate mask for feathering output tile overlaps float Vmask[height + overlap] ALIGNED16; @@ -2304,6 +2348,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * if (settings->verbose) { printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10); } + klev = (wavblcurve[lvl * 55.5f]); float lvr = lvl; @@ -2537,8 +2582,8 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float WavCoeffs_ab0[i] = aft[i]; } - delete[] bef; - delete[] aft; + delete[] bef; + delete[] aft; } diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index bc99d0d57..23e526474 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -131,8 +131,8 @@ Wavelet::Wavelet() : edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))), edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))), balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))), - chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0, 100, 1, 0))), - chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100, 1, 0))), + chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0.0, 150., 0.01, 0.))), + chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100., 0.01, 0.))), mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 40))), mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), @@ -246,7 +246,7 @@ Wavelet::Wavelet() : Tilesmethod->append(M("TP_WAVELET_TILESFULL")); Tilesmethod->append(M("TP_WAVELET_TILESBIG")); - Tilesmethod->append(M("TP_WAVELET_TILESLIT")); +// Tilesmethod->append(M("TP_WAVELET_TILESLIT")); Tilesmethodconn = Tilesmethod->signal_changed().connect(sigc::mem_fun(*this, &Wavelet::TilesmethodChanged)); Tilesmethod->set_tooltip_text(M("TP_WAVELET_TILES_TOOLTIP")); Gtk::HBox* const tilesizeHBox = Gtk::manage(new Gtk::HBox()); @@ -540,7 +540,7 @@ Wavelet::Wavelet() : chroBox->pack_start(*chromfi); chroBox->pack_start(*chromco); chroFrame->add(*chroBox); -// noiseBox->pack_start(*chroFrame); + noiseBox->pack_start(*chroFrame); //Clarity @@ -1257,8 +1257,8 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) Tilesmethod->set_active(0); } else if (pp->wavelet.Tilesmethod == "big") { Tilesmethod->set_active(1); - } else if (pp->wavelet.Tilesmethod == "lit") { - Tilesmethod->set_active(2); +// } else if (pp->wavelet.Tilesmethod == "lit") { +// Tilesmethod->set_active(2); } //daubcoeffmethod->set_active (4); @@ -2015,8 +2015,8 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.Tilesmethod = "full"; } else if (Tilesmethod->get_active_row_number() == 1) { pp->wavelet.Tilesmethod = "big"; - } else if (Tilesmethod->get_active_row_number() == 2) { - pp->wavelet.Tilesmethod = "lit"; +// } else if (Tilesmethod->get_active_row_number() == 2) { +// pp->wavelet.Tilesmethod = "lit"; } if (daubcoeffmethod->get_active_row_number() == 0) { From 05250a24973fcc607c491dd7b334a9882effce66 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 11:04:01 +0200 Subject: [PATCH 03/12] Change labels chroma --- rtdata/languages/default | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 4a181324d..ed9b06b04 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2143,7 +2143,7 @@ TP_WAVELET_BACKGROUND;Background TP_WAVELET_BACUR;Curve TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. -TP_WAVELET_BALCHRO;Chroma balance +TP_WAVELET_BALCHRO;Chrominance balance TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. TP_WAVELET_BALCHROM;Chroma balance TP_WAVELET_BANONE;None @@ -2163,8 +2163,8 @@ TP_WAVELET_CHR;Chroma-contrast link strength TP_WAVELET_CHRO;Saturated/pastel threshold TP_WAVELET_CHROFRAME;Denoise Chroma TP_WAVELET_CHROMAFRAME;Chroma -TP_WAVELET_CHROMCO;Chroma Coarse -TP_WAVELET_CHROMFI;Chroma Fine +TP_WAVELET_CHROMCO;Chrominance Coarse +TP_WAVELET_CHROMFI;Chrominance Fine TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength" TP_WAVELET_CHRWAV;Blur chroma From ca8399bc9008edd5fe9f970efe6ba64407179a6a Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 11:13:18 +0200 Subject: [PATCH 04/12] change labels --- rtdata/languages/default | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index ed9b06b04..83262a3fc 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2145,7 +2145,7 @@ TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. TP_WAVELET_BALCHRO;Chrominance balance TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. -TP_WAVELET_BALCHROM;Chroma balance +TP_WAVELET_BALCHROM;Chrominance balance TP_WAVELET_BANONE;None TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method @@ -2161,7 +2161,7 @@ TP_WAVELET_CH3;Link contrast levels TP_WAVELET_CHCU;Curve TP_WAVELET_CHR;Chroma-contrast link strength TP_WAVELET_CHRO;Saturated/pastel threshold -TP_WAVELET_CHROFRAME;Denoise Chroma +TP_WAVELET_CHROFRAME;Denoise Chrominance TP_WAVELET_CHROMAFRAME;Chroma TP_WAVELET_CHROMCO;Chrominance Coarse TP_WAVELET_CHROMFI;Chrominance Fine From f4a28b730a3f629eda8463324fb43e31646838a6 Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 14:53:55 +0200 Subject: [PATCH 05/12] Disabled denoise chrom when denoise and refine disabled --- rtengine/ipwavelet.cc | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 79302c452..43c5733db 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1168,8 +1168,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); - WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); adecomp->reconstruct(labco->data + datalen, cp.strength); @@ -1194,8 +1196,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); - WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); + } Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); @@ -1220,15 +1224,19 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); - WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); + } Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); - WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); + if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); + WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); + } adecomp->reconstruct(labco->data + datalen, cp.strength); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); From 1e3870d8f71912838aca84389fff34328c85a45f Mon Sep 17 00:00:00 2001 From: Desmis Date: Sun, 5 Apr 2020 15:53:05 +0200 Subject: [PATCH 06/12] Clean code improcfun.h --- rtengine/improcfun.h | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 3513efd92..d003df644 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -238,29 +238,22 @@ public: void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); -// bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); -// bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); + void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); - bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels); -// bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); -// bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, -// const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); + bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels); void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false); -// void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); -// void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, -// float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false); void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); From 31355ca70e2585d2b62268cc89f80697ea93aab9 Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 6 Apr 2020 09:37:37 +0200 Subject: [PATCH 07/12] Added equalizer denoise luminance --- rtdata/languages/default | 6 +++-- rtengine/FTblockDN.cc | 6 ++--- rtengine/ipwavelet.cc | 56 +++++++++++++++++++++++++++++++++++++--- rtengine/procparams.cc | 4 +++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 +++++ rtgui/paramsedited.h | 1 + rtgui/wavelet.cc | 12 +++++++++ rtgui/wavelet.h | 2 ++ 9 files changed, 85 insertions(+), 9 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 83262a3fc..c49205767 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -791,7 +791,8 @@ HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength HISTORY_MSG_TEMPOUT;CAM02 automatic temperature HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor HISTORY_MSG_TRANS_Method;Geometry - Method -HISTORY_MSG_WAVBALCHROM;Balance chroma +HISTORY_MSG_WAVBALCHROM;Equalizer chrominance +HISTORY_MSG_WAVBALLUM;Equalizer luminance HISTORY_MSG_WAVCHROMFI;Chroma fine HISTORY_MSG_WAVCHROMCO;Chroma coarse HISTORY_MSG_WAVCLARI;Clarity @@ -2145,7 +2146,8 @@ TP_WAVELET_BALANCE;Contrast balance d/v-h TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. TP_WAVELET_BALCHRO;Chrominance balance TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. -TP_WAVELET_BALCHROM;Chrominance balance +TP_WAVELET_BALCHROM;Denoise Equalizer Blue-Red +TP_WAVELET_BALLUM;Denoise Equalizer White-Black TP_WAVELET_BANONE;None TP_WAVELET_BASLI;Slider TP_WAVELET_BATYPE;Contrast balance method diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 34e7351b8..894c72ce2 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -2214,7 +2214,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); const float eps = 0.01f; - if (edge == 1 || edge == 3) { + if (edge == 1 || edge == 3 || edge == 4) { maxlvl = 4; //for refine denoise edge wavelet } @@ -2294,7 +2294,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W } } - if (edge == 2) { + if (edge == 2 || edge == 4) { for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) { nvl[i] = vari[lvl] * SQR(noisevarlum[i]); } @@ -2721,7 +2721,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f } } - if (edge == 2) { + if (edge == 2 || edge == 4) { for (int i = 0; i < W_L * H_L; ++i) { nvl[i] = vari[level] * SQR(noisevarlum[i]); } diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 43c5733db..a5dc1b7c6 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -138,6 +138,7 @@ struct cont_params { float edgampl; int neigh; bool lipp; + float ballum; float balchrom; float chromfi; float chromco; @@ -401,6 +402,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const cp.balchrom = waparams.balchrom; cp.chromfi = 0.1f * waparams.chromfi; cp.chromco = 0.1f * waparams.chromco; + cp.ballum = waparams.ballum; cp.conres = waparams.rescon; cp.conresH = waparams.resconH; @@ -884,16 +886,62 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const vari[1] = 8.f * SQR((cp.lev1n / 125.f) * (1.f + cp.lev1n / 25.f)); vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); + float kr3 = 1.f; + if (cp.lev3n < 10.f) { + kr3 = 0.f; + } else if (cp.lev3n < 30.f) { + kr3 = 0.5f; + } else if (cp.lev3n < 70.f) { + kr3 = 0.7f; + } else { + kr3 = 1.f; + } if ((cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f || cp.lev3n > 0.1f) && cp.noiseena) { - int edge = 1; + int edge = 4; vari[0] = rtengine::max(0.0001f, vari[0]); vari[1] = rtengine::max(0.0001f, vari[1]); vari[2] = rtengine::max(0.0001f, vari[2]); - vari[3] = rtengine::max(0.0001f, vari[3]); - float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + vari[3] = rtengine::max(0.0001f, kr3 * vari[3]); + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + int GWL = labco->W; + int GHL = labco->H; + float* noisevarlum = new float[GHL * GWL]; + int GW2L = (GWL + 1) / 2; - WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + float nvlh[13] = {1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 0.7f, 0.5f}; //high value + float nvll[13] = {0.1f, 0.15f, 0.2f, 0.25f, 0.3f, 0.35f, 0.4f, 0.45f, 0.7f, 0.8f, 1.f, 1.f, 1.f}; //low value + + float seuillow = 3000.f;//low + float seuilhigh = 18000.f;//high + int i = 10 - cp.ballum; + float ac = (nvlh[i] - nvll[i]) / (seuillow - seuilhigh); + float bc = nvlh[i] - seuillow * ac; + +#ifdef _OPENMP + #pragma omp parallel for + +#endif + + for (int ir = 0; ir < GHL; ir++) + for (int jr = 0; jr < GWL; jr++) { + float lN = labco->L[ir][jr]; + + if (lN < seuillow) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; + } + } + if (cp.lev3n < 0.5f) { + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } else { + WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + + WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); + } } //Flat curve for Contrast=f(H) in levels diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index b398cc729..b02f1970c 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2248,6 +2248,7 @@ WaveletParams::WaveletParams() : bluemed(0), greenhigh(0), bluehigh(0), + ballum(7.), balchrom(0.), chromfi(0.), chromco(0.), @@ -2361,6 +2362,7 @@ bool WaveletParams::operator ==(const WaveletParams& other) const && bluemed == other.bluemed && greenhigh == other.greenhigh && bluehigh == other.bluehigh + && ballum == other.ballum && balchrom == other.balchrom && chromfi == other.chromfi && chromco == other.chromco @@ -3526,6 +3528,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile); + saveToKeyfile(!pedited || pedited->wavelet.ballum, "Wavelet", "Ballum", wavelet.ballum, keyFile); saveToKeyfile(!pedited || pedited->wavelet.balchrom, "Wavelet", "Balchrom", wavelet.balchrom, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chromfi, "Wavelet", "Chromfine", wavelet.chromfi, keyFile); saveToKeyfile(!pedited || pedited->wavelet.chromco, "Wavelet", "Chromcoarse", wavelet.chromco, keyFile); @@ -4699,6 +4702,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh); assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed); assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow); + assignFromKeyfile(keyFile, "Wavelet", "Ballum", pedited, wavelet.ballum, pedited->wavelet.ballum); assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom); assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi); assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index a6147ccc5..4e2b0c275 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1205,6 +1205,7 @@ struct WaveletParams { int bluemed; int greenhigh; int bluehigh; + double ballum; double balchrom; double chromfi; double chromco; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 0685e1471..0faee0fd3 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -486,6 +486,7 @@ void ParamsEdited::set(bool v) wavelet.bluemed = v; wavelet.bluelow = v; wavelet.lipst = v; + wavelet.ballum = v; wavelet.balchrom = v; wavelet.chromfi = v; wavelet.chromco = v; @@ -1096,6 +1097,7 @@ void ParamsEdited::initFrom(const std::vector& wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow; wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh; + wavelet.ballum = wavelet.ballum && p.wavelet.ballum == other.wavelet.ballum; wavelet.balchrom = wavelet.balchrom && p.wavelet.balchrom == other.wavelet.balchrom; wavelet.chromfi = wavelet.chromfi && p.wavelet.chromfi == other.wavelet.chromfi; wavelet.chromco = wavelet.chromco && p.wavelet.chromco == other.wavelet.chromco; @@ -2935,6 +2937,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.wavelet.bluelow = mods.wavelet.bluelow; } + if (wavelet.ballum) { + toEdit.wavelet.ballum = mods.wavelet.ballum; + } + if (wavelet.balchrom) { toEdit.wavelet.balchrom = mods.wavelet.balchrom; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4465d15b4..d1be2c57e 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -586,6 +586,7 @@ struct WaveletParamsEdited { bool bluemed; bool greenhigh; bool bluehigh; + bool ballum; bool balchrom; bool chromfi; bool chromco; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 23e526474..652774af4 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -130,6 +130,7 @@ Wavelet::Wavelet() : edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))), edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))), edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))), + ballum(Gtk::manage(new Adjuster(M("TP_WAVELET_BALLUM"), -2., 10., 0.5, 7., Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))), balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))), chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0.0, 150., 0.01, 0.))), chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100., 0.01, 0.))), @@ -183,6 +184,7 @@ Wavelet::Wavelet() : auto m = ProcEventMapper::getInstance(); EvWavenaclari = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCLARI"); EvWavushamet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVUSHAMET"); + EvWavballum = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALLUM"); EvWavbalchrom = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALCHROM"); EvWavchromfi = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMFI"); EvWavchromco = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMCO"); @@ -524,7 +526,9 @@ Wavelet::Wavelet() : level3noise->setAdjusterListener(this); level3noise->setUpdatePolicy(RTUP_DYNAMIC); + ballum->setAdjusterListener(this); + noiseBox->pack_start(*ballum); noiseBox->pack_start(*level0noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level1noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0); @@ -1403,6 +1407,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) softrad->setValue(pp->wavelet.softrad); softradend->setValue(pp->wavelet.softradend); + ballum->setValue(pp->wavelet.ballum); balchrom->setValue(pp->wavelet.balchrom); chromfi->setValue(pp->wavelet.chromfi); chromco->setValue(pp->wavelet.chromco); @@ -1551,6 +1556,7 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited) softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + ballum->setEditedState(pedited->wavelet.ballum ? Edited : UnEdited); balchrom->setEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); chromfi->setEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); chromco->setEditedState(pedited->wavelet.chromco ? Edited : UnEdited); @@ -1774,6 +1780,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pp->wavelet.strength = (int) strength->getValue(); pp->wavelet.balance = (int) balance->getValue(); pp->wavelet.balchrom = balchrom->getValue(); + pp->wavelet.ballum = ballum->getValue(); pp->wavelet.chromfi = chromfi->getValue(); pp->wavelet.chromco = chromco->getValue(); @@ -1895,6 +1902,7 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited) pedited->wavelet.bluemed = bluemed->getEditedState(); pedited->wavelet.greenhigh = greenhigh->getEditedState(); pedited->wavelet.bluehigh = bluehigh->getEditedState(); + pedited->wavelet.ballum = ballum->getEditedState(); pedited->wavelet.balchrom = balchrom->getEditedState(); pedited->wavelet.chromfi = chromfi->getEditedState(); pedited->wavelet.chromco = chromco->getEditedState(); @@ -2129,6 +2137,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit level1noise->setDefault (defParams->wavelet.level1noise); level2noise->setDefault (defParams->wavelet.level2noise); level3noise->setDefault (defParams->wavelet.level3noise); + ballum->setDefault(defParams->wavelet.ballum); balchrom->setDefault(defParams->wavelet.balchrom); chromfi->setDefault(defParams->wavelet.chromfi); chromco->setDefault(defParams->wavelet.chromco); @@ -2155,6 +2164,7 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited); + ballum->setDefaultEditedState(pedited->wavelet.ballum ? Edited : UnEdited); balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited); chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited); chromco->setDefaultEditedState(pedited->wavelet.chromco ? Edited : UnEdited); @@ -2951,6 +2961,8 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval) listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); } else if (a == bluehigh) { listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue()); + } else if (a == ballum) { + listener->panelChanged(EvWavballum, ballum->getTextValue()); } else if (a == balchrom) { listener->panelChanged(EvWavbalchrom, balchrom->getTextValue()); } else if (a == chromfi) { diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h index 07d2432ac..d1b4bb7c3 100644 --- a/rtgui/wavelet.h +++ b/rtgui/wavelet.h @@ -70,6 +70,7 @@ public: private: rtengine::ProcEvent EvWavenaclari; rtengine::ProcEvent EvWavushamet; + rtengine::ProcEvent EvWavballum; rtengine::ProcEvent EvWavbalchrom; rtengine::ProcEvent EvWavchromfi; rtengine::ProcEvent EvWavchromco; @@ -244,6 +245,7 @@ private: Adjuster* const edgedetectthr2; Adjuster* const edgesensi; Adjuster* const edgeampli; + Adjuster* const ballum; Adjuster* const balchrom; Adjuster* const chromfi; Adjuster* const chromco; From 9f5e81b0262e50bf26dfdfc3524382d7b428557f Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 6 Apr 2020 09:42:46 +0200 Subject: [PATCH 08/12] Change tooltip offset --- rtdata/languages/default | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index c49205767..64af97689 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2328,7 +2328,7 @@ TP_WAVELET_USHARP_TOOLTIP;Origin : the source file is the file before Wavelet.\n TP_WAVELET_USH_TOOLTIP;If you select Sharp-mask, wavelet settings will be automatically positioned :\nBackground=black, Process=below, level=3...you can change level between 1 and 4.\n\nIf you select Clarity, wavelet settings will be automatically positioned :\nBackground=residual, Process=above, level=7..you can change level between 5 and 10 and wavelet levels. TP_WAVELET_WAVLOWTHR;Low contrast threshold TP_WAVELET_WAVOFFSET;Offset -TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\n High values will amplify the contrast enhancement of the highlights, while low values will amplify the contrast enhancement of the shadows. Along with a low Max. effect value will help you selecting the contrasts that will be enhanced +TP_WAVELET_OFFSET_TOOLTIP;Offset modifies the balance between shadows and highlights.\nHigh values here will amplify the contrast change of the highlights, whereas low values will amplify the contrast change of the shadows.\nAlong with a low Damper value you will able to select the contrasts that will be enhanced. TP_WBALANCE_AUTO;Auto TP_WBALANCE_AUTOITCGREEN;Auto iterate temperature correlation TP_WBALANCE_AUTOOLD;Auto RGB grey From ded866f5afc1e009a51adc74ba604ebcd5f9b9df Mon Sep 17 00:00:00 2001 From: Desmis Date: Mon, 6 Apr 2020 17:33:01 +0200 Subject: [PATCH 09/12] Optimize memory when denoise chroma is not used --- rtengine/ipwavelet.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index a5dc1b7c6..0d55791d6 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -838,7 +838,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwavL < 4) { levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! } - + bool usechrom = cp.chromfi > 0.f || cp.chromco > 0.f; + if (levwavL > 0) { const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); float madL[8][3]; @@ -970,7 +971,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } */ - + if(!usechrom) { + Ldecomp->reconstruct(labco->data, cp.strength); + } float variC[7]; float variCb[7]; @@ -1298,8 +1301,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (hhCurve) { delete hhCurve; } - - Ldecomp->reconstruct(labco->data, cp.strength); + + if(usechrom) { + Ldecomp->reconstruct(labco->data, cp.strength); + } } } From abba1bf360502b13bd541b68bf4630c0e2835cce Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 7 Apr 2020 10:16:08 +0200 Subject: [PATCH 10/12] Improve enabled blur level and wavelet decomp level --- rtengine/ipwavelet.cc | 105 ++++++++++++++++++++++++++++-------------- rtgui/wavelet.cc | 2 +- 2 files changed, 71 insertions(+), 36 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 0d55791d6..860530be2 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -524,11 +524,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (params->wavelet.Tilesmethod == "big") { realtile = 22; } -/* - if (params->wavelet.Tilesmethod == "lit") { - realtile = 12; - } -*/ + + /* + if (params->wavelet.Tilesmethod == "lit") { + realtile = 12; + } + */ int tilesize = 128 * realtile; int overlap = (int) tilesize * 0.125f; int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; @@ -823,7 +824,25 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const ref0 = true; } - if (cp.contrast == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels + bool wavcurvecomp = false;//not enable if 0.75 + + if (wavblcurve) { + for (int i = 0; i < 500; i++) { + if (wavblcurve[i] != 0.) { + wavcurvecomp = true; + } + } + } + + bool exblurL = cp.blena && wavcurvecomp; + + if(exblurL) { + if(cp.mul[0] == 0.f) { + cp.mul[0] = 0.01f;//to enable WaveletcontAllL if no contrast is nead + } + } + + if (!exblurL && cp.contrast == 0.f && cp.blurres == 0.f && !cp.tonemap && cp.conres == 0.f && cp.conresH == 0.f && cp.val == 0 && !ref0 && params->wavelet.CLmethod == "all") { // no processing of residual L or edge=> we probably can reduce the number of levels while (levwavL > 0 && cp.mul[levwavL - 1] == 0.f) { // cp.mul[level] == 0.f means no changes to level levwavL--; } @@ -838,8 +857,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (levwavL < 4) { levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! } + + // printf("wave L=%i\n", levwavL); bool usechrom = cp.chromfi > 0.f || cp.chromco > 0.f; - + if (levwavL > 0) { const std::unique_ptr Ldecomp(new wavelet_decomposition(labco->data, labco->W, labco->H, levwavL, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); float madL[8][3]; @@ -888,6 +909,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const vari[2] = 8.f * SQR((cp.lev2n / 125.f) * (1.f + cp.lev2n / 25.f)); vari[3] = 8.f * SQR((cp.lev3n / 125.f) * (1.f + cp.lev3n / 25.f)); float kr3 = 1.f; + if (cp.lev3n < 10.f) { kr3 = 0.f; } else if (cp.lev3n < 30.f) { @@ -904,7 +926,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const vari[1] = rtengine::max(0.0001f, vari[1]); vari[2] = rtengine::max(0.0001f, vari[2]); vari[3] = rtengine::max(0.0001f, kr3 * vari[3]); - // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL + // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL int GWL = labco->W; int GHL = labco->H; float* noisevarlum = new float[GHL * GWL]; @@ -920,22 +942,23 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const float bc = nvlh[i] - seuillow * ac; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for #endif - for (int ir = 0; ir < GHL; ir++) - for (int jr = 0; jr < GWL; jr++) { - float lN = labco->L[ir][jr]; + for (int ir = 0; ir < GHL; ir++) + for (int jr = 0; jr < GWL; jr++) { + float lN = labco->L[ir][jr]; + + if (lN < seuillow) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; + } else if (lN < seuilhigh) { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; + } else { + noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; + } + } - if (lN < seuillow) { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvlh[i]; - } else if (lN < seuilhigh) { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = ac * lN + bc; - } else { - noisevarlum[(ir >> 1)*GW2L + (jr >> 1)] = nvll[i]; - } - } if (cp.lev3n < 0.5f) { WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1); } else { @@ -965,13 +988,14 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } WaveletcontAllLfinal(*Ldecomp, cp, mean, sigma, MaxP, waOpacityCurveWL); + //Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); /* Ldecomp->reconstruct(labco->data, cp.strength); } } */ - if(!usechrom) { + if (!usechrom) { Ldecomp->reconstruct(labco->data, cp.strength); } @@ -1147,11 +1171,11 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const variC[6] = max(0.0001f, k6 * variC[6]); variCb[6] = max(0.0001f, k6 * variCb[6]); -/* - for (int y = 0; y < 7; y++) { - printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); - } -*/ + /* + for (int y = 0; y < 7; y++) { + printf("y=%i madL=%f varia=%f variab=%f\n", y, madL[y][1], variC[y], variCb[y]); + } + */ float nvch = 0.6f;//high value float nvcl = 0.1f;//low value @@ -1199,11 +1223,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const hhutili = true; } + bool exblurab = cp.chrwav > 0.f && exblurL; if (!hhutili) { //always a or b int levwava = levwav; - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels while (levwava > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwava - 1] == 0.f)) || (cp.CHmet != 2 && (levwava == 10 || (!cp.curv || cp.mulC[levwava - 1] == 0.f))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava - 1] == 0.f)) && ((levwava == 10 || (cp.CHSLmet == 1 && cp.mulC[levwava - 1] == 0.f)))) { levwava--; } @@ -1215,14 +1240,17 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } + // printf("wavea=%i\n", levwava); + if (levwava > 0) { const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed) { - if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); adecomp->reconstruct(labco->data + datalen, cp.strength); @@ -1231,7 +1259,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const int levwavb = levwav; - if (cp.chrores == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && params->wavelet.CLmethod == "all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels while (levwavb > 0 && !cp.diag && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavb - 1] == 0.f)) || (cp.CHmet != 2 && (levwavb == 10 || (!cp.curv || cp.mulC[levwavb - 1] == 0.f))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb - 1] == 0.f)) && ((levwavb == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavb - 1] == 0.f)))) { levwavb--; } @@ -1243,14 +1271,17 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } + // printf("waveb=%i\n", levwavb); + if (levwavb > 0) { const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!bdecomp->memoryAllocationFailed) { - if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); } + Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); bdecomp->reconstruct(labco->data + 2 * datalen, cp.strength); @@ -1259,11 +1290,12 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } else {// a and b int levwavab = levwav; - if (cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels + if (!exblurab && cp.chrores == 0.f && cp.blurcres == 0.f && !hhutili && params->wavelet.CLmethod == "all") { // no processing of residual ab => we probably can reduce the number of levels while (levwavab > 0 && (((cp.CHmet == 2 && (cp.chro == 0.f || cp.mul[levwavab - 1] == 0.f)) || (cp.CHmet != 2 && (levwavab == 10 || (!cp.curv || cp.mulC[levwavab - 1] == 0.f))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab - 1] == 0.f)) && ((levwavab == 10 || (cp.CHSLmet == 1 && cp.mulC[levwavab - 1] == 0.f)))) { levwavab--; } } + if (cp.chromfi > 0.f || cp.chromco > 0.f) { if (levwavab < 7) { levwavab = 7; @@ -1275,16 +1307,18 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavab, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { - if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, true, false, false, 1); } + Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, variCb, edge, noisevarab_r, true, false, false, 1); Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); - if(cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { + + if (cp.noiseena && (cp.chromfi > 0.f || cp.chromfi > 0.f)) { WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); } @@ -1301,8 +1335,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const if (hhCurve) { delete hhCurve; } - - if(usechrom) { + + if (usechrom) { Ldecomp->reconstruct(labco->data, cp.strength); } } @@ -2350,6 +2384,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float klev = 1.f; if (wavblcurve && wavcurvecomp && cp.blena) { + printf("Blur level L\n"); float mea[10]; float effect = cp.bluwav; float beta = 0.f; diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc index 652774af4..af159d480 100644 --- a/rtgui/wavelet.cc +++ b/rtgui/wavelet.cc @@ -138,7 +138,7 @@ Wavelet::Wavelet() : mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), softradend(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), - chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0., 0.))), + chrwav(Gtk::manage(new Adjuster(M("TP_WAVELET_CHRWAV"), 0., 100., 0.5, 0.))), Lmethod(Gtk::manage(new MyComboBoxText())), CHmethod(Gtk::manage(new MyComboBoxText())), CHSLmethod(Gtk::manage(new MyComboBoxText())), From cbac4e06913ecefbc096dd38c3ddb48a1359b4eb Mon Sep 17 00:00:00 2001 From: Desmis Date: Tue, 7 Apr 2020 10:52:08 +0200 Subject: [PATCH 11/12] Fixed segmentation fault with blur levels --- rtengine/ipwavelet.cc | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 860530be2..703894e2d 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -836,9 +836,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const bool exblurL = cp.blena && wavcurvecomp; - if(exblurL) { - if(cp.mul[0] == 0.f) { - cp.mul[0] = 0.01f;//to enable WaveletcontAllL if no contrast is nead + if (exblurL) { + if (cp.mul[0] == 0.f) { + cp.mul[0] = 0.01f;//to always enable WaveletcontAllL if no contrast is nead } } @@ -858,7 +858,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const levwavL = 4; //to allow edge => I always allocate 3 (4) levels..because if user select wavelet it is to do something !! } - // printf("wave L=%i\n", levwavL); + if (settings->verbose) { + printf("Level decomp L=%i\n", levwavL); + } + bool usechrom = cp.chromfi > 0.f || cp.chromco > 0.f; if (levwavL > 0) { @@ -1240,7 +1243,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - // printf("wavea=%i\n", levwava); + if (settings->verbose) { + printf("Leval decomp a=%i\n", levwava); + } if (levwava > 0) { const std::unique_ptr adecomp(new wavelet_decomposition(labco->data + datalen, labco->W, labco->H, levwava, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); @@ -1271,7 +1276,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - // printf("waveb=%i\n", levwavb); + if (settings->verbose) { + printf("Leval decomp b=%i\n", levwavb); + } + if (levwavb > 0) { const std::unique_ptr bdecomp(new wavelet_decomposition(labco->data + 2 * datalen, labco->W, labco->H, levwavb, 1, skip, rtengine::max(1, wavNestedLevels), DaubLen)); @@ -2384,7 +2392,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * float klev = 1.f; if (wavblcurve && wavcurvecomp && cp.blena) { - printf("Blur level L\n"); + // printf("Blur level L\n"); float mea[10]; float effect = cp.bluwav; float beta = 0.f; @@ -2446,13 +2454,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float * } klev = (wavblcurve[lvl * 55.5f]); - float lvr = lvl; - if (lvr == 0) { - lvr = 1; - } - - klev *= beta * lvr * 100.f / skip; + klev *= beta * 100.f / skip; boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); for (int co = 0; co < Hlvl_L * Wlvl_L; co++) { @@ -2707,6 +2710,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { + float mea[10]; float effect = cp.bluwav; float beta = 0.f; @@ -2750,13 +2754,8 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float } klev = (wavblcurve[lvl * 55.5f]); - float lvr = lvl; - if (lvr == 0) { - lvr = 1; - } - - klev *= beta * cp.chrwav * lvr * 200.f / skip; + klev *= beta * cp.chrwav * 100.f / skip; boxblur(bef, aft, klev, Wlvl_ab, Hlvl_ab, false); From 4c0013b461c060cb83ab2b2602a0644c70dd309a Mon Sep 17 00:00:00 2001 From: Desmis Date: Wed, 8 Apr 2020 07:42:17 +0200 Subject: [PATCH 12/12] Wavelet final - Change guidefilter parameters --- rtengine/ipwavelet.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc index 703894e2d..f415c9c8e 100644 --- a/rtengine/ipwavelet.cc +++ b/rtengine/ipwavelet.cc @@ -1576,10 +1576,10 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const } } - constexpr double epsilmax = 0.001; - constexpr double epsilmin = 0.0001; - constexpr double aepsil = (epsilmax - epsilmin) / 90.f; - constexpr double bepsil = epsilmax - 100.f * aepsil; + constexpr double epsilmax = 0.002; + constexpr double epsilmin = 0.0005; + constexpr double aepsil = 0.01f * (epsilmax - epsilmin); + constexpr double bepsil = epsilmin; const double epsil = aepsil * waparams.softradend + bepsil; const float blur = 10.f / scale * (0.001f + 0.8f * waparams.softradend);