diff --git a/.github/workflows/appimage.yml b/.github/workflows/appimage.yml index 9ad9a6cbd..6b286b68b 100644 --- a/.github/workflows/appimage.yml +++ b/.github/workflows/appimage.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' jobs: build: runs-on: ubuntu-20.04 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 4ab10212c..e01e4bd75 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -11,7 +11,7 @@ on: - dev workflow_dispatch: env: - publish_pre_dev_labels: '[]' + publish_pre_dev_labels: '["Beep6581:ladenoise_improv"]' jobs: build: runs-on: windows-2022 diff --git a/rtdata/languages/default b/rtdata/languages/default index 45471bb5c..4c99d113b 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -2839,13 +2839,15 @@ TP_LOCALLAB_DENOIMASK;Denoise chroma mask TP_LOCALLAB_DENOIMASK_TOOLTIP;For all tools, allows you to control the chromatic noise level of the mask.\nUseful for better control of chrominance and to avoid artifacts when using the LC(h) curve. TP_LOCALLAB_DENOIQUA_TOOLTIP;Conservative mode preserves low frequency detail. Aggressive mode removes low frequency detail.\nConservative and Aggressive modes use wavelets and DCT and can be used in conjunction with 'Non-local Means – Luminance'. TP_LOCALLAB_DENOITHR_TOOLTIP;Adjusts edge detection to help reduce noise in uniform, low-contrast areas. +TP_LOCALLAB_DENOIWAVCH;Wavelets: Chrominance +TP_LOCALLAB_DENOIWAVLUM;Wavelets: Luminance TP_LOCALLAB_DENOI_EXP;Denoise TP_LOCALLAB_DENOI_TOOLTIP;This module can be used for noise reduction either on its own (at the end of the processing pipeline) or in addition to the Noise Reduction module in the Detail tab (which works at the beginning of the pipeline).\n Scope allows you to differentiate the action based on color (ΔE).\nMinimum RT-spot size: 128x128. TP_LOCALLAB_DEPTH;Depth TP_LOCALLAB_DETAIL;Local contrast TP_LOCALLAB_DETAILFRA;Edge detection - DCT TP_LOCALLAB_DETAILSH;Details -TP_LOCALLAB_DETAILTHR;Luma-chro detail threshold +TP_LOCALLAB_DETAILTHR;Lum/chrom detail threshold TP_LOCALLAB_DIVGR;Gamma TP_LOCALLAB_DUPLSPOTNAME;Copy TP_LOCALLAB_EDGFRA;Edge sharpness @@ -3110,7 +3112,7 @@ TP_LOCALLAB_MASKLCTHRLOW;Dark area luminance threshold TP_LOCALLAB_MASKLCTHRLOW2;Dark area luma threshold TP_LOCALLAB_MASKLCTHRMID;Gray area luma denoise TP_LOCALLAB_MASKLCTHRMIDCH;Gray area chroma denoise -TP_LOCALLAB_MASKLC_TOOLTIP;This allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. +TP_LOCALLAB_MASKLC_TOOLTIP;Used by wavelet luminance.\nThis allows you to target the denoise based on the image luminance information contained in the L(L) or LC(H) mask (Mask and Modifications).\n The L(L) mask or the LC(H) mask must be enabled to use this function.\n 'Dark area luminance threshold'. If 'Reinforce denoise in dark and light areas' > 1 the denoise is progressively increased from 0% at the threshold setting to 100% at the maximum black value (determined by mask).\n 'Light area luminance threshold'. The denoise is progressively decreased from 100% at the threshold setting to 0% at the maximum white value (determined by mask).\n In the area between the two thresholds, the denoise settings are not affected by the mask. TP_LOCALLAB_MASKLNOISELOW;Reinforce dark/light areas TP_LOCALLAB_MASKLOWTHRESCB_TOOLTIP;Dark-tone limit below which the CBDL parameters (Luminance only) will be restored progressively to their original values prior to being modified by the CBDL settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Smooth radius', Gamma and Slope, 'Contrast curve'.\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. TP_LOCALLAB_MASKLOWTHRESC_TOOLTIP;Dark-tone limit below which the parameters will be restored progressively to their original values prior to being modified by the Color and Light settings.\n You can use certain tools in 'Mask and modifications' to change the gray levels: 'Structure mask', 'blur mask', 'Smooth radius', Gamma and Slope, 'Contrast curve', 'Local contrast' (wavelets).\n Use a 'lockable color picker' on the mask to see which areas will be affected. Make sure you set 'Background color mask' = 0 in Settings. @@ -3169,6 +3171,12 @@ TP_LOCALLAB_MERTHR;Difference TP_LOCALLAB_MERTWE;Exclusion TP_LOCALLAB_MERTWO;Subtract TP_LOCALLAB_METHOD_TOOLTIP;'Enhanced + chroma denoise' significantly increases processing times.\nBut reduce artifacts. +TP_LOCALLAB_LCLABELS;Residual noise levels +TP_LOCALLAB_LCLABELS_TOOLTIP;Displays the mean and high-end noise values for the area shown in the Preview Panel (at 100% zoom). The noise values are grouped by wavelet levels 0,1,2,3 and 4,5,6.\nThe displayed values are indicative only and are designed to assist with denoise adjustments. They should not be interpreted as absolute noise levels.\n\n 300: Very noisy\n 100-300: Noisy\n 50-100: Moderatly noisy\n < 50: Low noise\n\nThey allow you to see:\n*The impact of Noise Reduction in the main-menu Detail tab.\n*The influence of Non-local Means, Wavelets and DCT on the luminance noise.\n*The influence of Wavelets and DCT on the chroma noise.\n*The influence of Capture Sharpening and Demosaicing. +TP_LOCALLAB_LUMLABEL;Luma levels 0123: Mean=%1 High=%2 +TP_LOCALLAB_LUM46LABEL;Luma levels 456: Mean=%1 High=%2 +TP_LOCALLAB_CHROLABEL;Chroma levels 0123: Mean=%1 High=%2 +TP_LOCALLAB_CHRO46LABEL;Chroma levels 456: Mean=%1 High=%2 TP_LOCALLAB_MLABEL;Restored data Min=%1 Max=%2 TP_LOCALLAB_MLABEL_TOOLTIP;The values should be close to Min=0 Max=32768 (log mode) but other values are possible.You can adjust 'Clip restored data (gain)' and 'Offset' to normalize.\nRecovers image data without blending. TP_LOCALLAB_MODE_EXPERT;Advanced @@ -3185,7 +3193,7 @@ TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP;Use this slider to adapt the amount of denois TP_LOCALLAB_NLDENOISENLRAD_TOOLTIP;Higher values increase denoise at the expense of processing time. TP_LOCALLAB_NLDENOISE_TOOLTIP;'Detail recovery' acts on a Laplacian transform to target uniform areas rather than areas with detail. TP_LOCALLAB_NLDET;Detail recovery -TP_LOCALLAB_NLFRA;Non-local Means - Luminance +TP_LOCALLAB_NLFRA;Non-local Means: Luminance TP_LOCALLAB_NLFRAME_TOOLTIP;Non-local means denoising takes a mean of all pixels in the image, weighted by how similar they are to the target pixel.\nReduces loss of detail compared with local mean algorithms.\nOnly luminance noise is taken into account. Chrominance noise is best processed using wavelets and Fourier transforms (DCT).\nCan be used in conjunction with 'Luminance denoise by level' or on its own. TP_LOCALLAB_NLGAM;Gamma TP_LOCALLAB_NLLUM;Strength diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 400dea05b..7477c5d08 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -1203,7 +1203,7 @@ BENCHFUN if (!memoryAllocationFailed) { if (kall == 0) { - Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb); + Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb, 0, levwav); chresidtemp = chresid; chmaxresidtemp = chmaxresid; } @@ -1240,12 +1240,13 @@ BENCHFUN if (!memoryAllocationFailed) { if (kall == 0) { - Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb); + Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb, 0, levwav); chresid += chresidtemp; chmaxresid += chmaxresidtemp; chresid = sqrt(chresid / (6 * (levwav))); highresi = chresid + 0.66f * (sqrt(chmaxresid) - chresid); //evaluate sigma nresi = chresid; + printf("Nresi=%f Highresi=%f lev=%i\n", (double) nresi, (double) highresi, levwav); } bdecomp->reconstruct(labdn->b[0]); @@ -2158,16 +2159,18 @@ float ImProcFunctions::MadRgb(const float * DataList, const int datalen) -void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb) +void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb, int beg, int end) { float resid = 0.f; float maxresid = 0.f; - +// int maxlev = WaveletCoeffs_ab.maxlevel(); + // end = maxlev; #ifdef _OPENMP #pragma omp parallel for schedule(dynamic) collapse(2) reduction(+:resid) reduction(max:maxresid) num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #endif - for (int lvl = 0; lvl < WaveletCoeffs_ab.maxlevel(); ++lvl) { + // for (int lvl = 0; lvl < WaveletCoeffs_ab.maxlevel(); ++lvl) { + for (int lvl = beg; lvl < end; ++lvl) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator for (int dir = 1; dir < 4; ++dir) { const int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index a6a1f1f50..bce6f2291 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -600,7 +600,6 @@ void Crop::update(int todo) params.dirpyrDenoise.redchro = maxr; params.dirpyrDenoise.bluechro = maxb; parent->denoiseInfoStore.valid = true; - if (parent->adnListener) { parent->adnListener->chromaChanged(params.dirpyrDenoise.chroma, params.dirpyrDenoise.redchro, params.dirpyrDenoise.bluechro); } @@ -848,7 +847,7 @@ void Crop::update(int todo) if ((todo & (M_AUTOEXP | M_RGBCURVE)) && params.locallab.enabled && !params.locallab.spots.empty()) { - + //I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here. parent->ipf.rgb2lab(*baseCrop, *laboCrop, params.icm.workingProfile); @@ -945,16 +944,7 @@ void Crop::update(int todo) auto& locwavCurveden = parent->locwavCurveden; auto& lmasklocal_curve2 = parent->lmasklocal_curve; auto& loclmasCurve_wav = parent->loclmasCurve_wav; -// const int sizespot = (int)params.locallab.spots.size(); -/* float *huerefp = nullptr; - huerefp = new float[sizespot]; - float *chromarefp = nullptr; - chromarefp = new float[sizespot]; - float *lumarefp = nullptr; - lumarefp = new float[sizespot]; - float *fabrefp = nullptr; - fabrefp = new float[sizespot]; -*/ + for (int sp = 0; sp < (int)params.locallab.spots.size(); sp++) { locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); locRETtransCurve.Set(params.locallab.spots.at(sp).localTtranscurve); @@ -1048,6 +1038,7 @@ void Crop::update(int todo) if (black < 0. && params.locallab.spots.at(sp).expMethod == "pde" ) { black *= 1.5; } + std::vector localldenoiselc; double cont = params.locallab.spots.at(sp).contrast; double huere, chromare, lumare, huerefblu, chromarefblu, lumarefblu, sobelre; @@ -1063,6 +1054,7 @@ void Crop::update(int todo) float stdtme = parent->stdtms[sp]; float meanretie = parent->meanretis[sp]; float stdretie = parent->stdretis[sp]; + float fab = 1.f; float minCD; float maxCD; @@ -1073,7 +1065,14 @@ void Crop::update(int todo) float Tmin; float Tmax; int lastsav; - + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; /* huerefp[sp] = huere; chromarefp[sp] = chromare; lumarefp[sp] = lumare; @@ -1142,9 +1141,20 @@ void Crop::update(int todo) huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, parent->previewDeltaE, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallvibMask, parent->localllcMask, parent->locallsharMask, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask, parent->localllogMask, parent->locall_Mask, parent->locallcieMask, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab); - // fabrefp[sp] = fab; - + meantme, stdtme, meanretie, stdretie, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); + + LocallabListener::locallabDenoiseLC denoiselc; + denoiselc.highres = highresi; + denoiselc.nres = nresi; + denoiselc.highres46 = highresi46; + denoiselc.nres46 = nresi46; + denoiselc.Lhighres = Lhighresi; + denoiselc.Lnres = Lnresi; + denoiselc.Lhighres46 = Lhighresi46; + denoiselc.Lnres46 = Lnresi46; + localldenoiselc.push_back(denoiselc); + if (parent->previewDeltaE || parent->locallColorMask == 5 || parent->locallvibMask == 4 || parent->locallExpMask == 5 || parent->locallSHMask == 4 || parent->localllcMask == 4 || parent->localltmMask == 4 || parent->localllogMask == 4 || parent->locallsoftMask == 6 || parent->localllcMask == 4 || parent->locallcieMask == 4) { params.blackwhite.enabled = false; params.colorToning.enabled = false; @@ -1174,6 +1184,20 @@ void Crop::update(int todo) } */ + denoiselc.highres = highresi; + denoiselc.nres = nresi; + denoiselc.highres46 = highresi46; + denoiselc.nres46 = nresi46; + denoiselc.Lhighres = Lhighresi; + denoiselc.Lnres = Lnresi; + denoiselc.Lhighres46 = Lhighresi46; + denoiselc.Lnres46 = Lnresi46; + localldenoiselc.push_back(denoiselc); + + + if (parent->locallListener) { + parent->locallListener->denChanged(localldenoiselc, params.locallab.selspot); + } } else { parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop.get(), savenormtmCrop.get(), savenormretiCrop.get(), lastorigCrop.get(), fw, fh, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, @@ -1229,8 +1253,11 @@ void Crop::update(int todo) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve2, localcutili, rgblocalcurve2, localrgbutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab); + meantme, stdtme, meanretie, stdretie, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); } + + if (sp + 1u < params.locallab.spots.size()) { // do not copy for last spot as it is not needed anymore lastorigCrop->CopyFrom(labnCrop); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 664029a5e..2ab6383bf 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -1169,7 +1169,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float stdtm = stdtms[sp] = stdtme; float meanreti = meanretis[sp] = meanretie; float stdreti = stdretis[sp] = stdretie; - huerefp[sp] = huer; chromarefp[sp] = chromar; lumarefp[sp] = lumar; @@ -1203,6 +1202,15 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) float Tmax; int lastsav; + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv.get(), savenormtm.get(), savenormreti.get(), lastorigimp.get(), fw, fh, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, cllocalcurve, localclutili, @@ -1256,7 +1264,8 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantm, stdtm, meanreti, stdreti, fab); + meantm, stdtm, meanreti, stdreti, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); fabrefp[sp] = fab; @@ -1296,7 +1305,6 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) retiMinMax.Tmin = Tmin; retiMinMax.Tmax = Tmax; locallretiminmax.push_back(retiMinMax); - // Recalculate references after if (params->locallab.spots.at(sp).spotMethod == "exc") { ipf.calc_ref(sp, reserv.get(), reserv.get(), 0, 0, pW, pH, scale, huerefblu, chromarefblu, lumarefblu, huer, chromar, lumar, sobeler, avg, locwavCurveden, locwavdenutili); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 92cdd91c7..50c14ef9e 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -365,6 +365,7 @@ protected: std::vector stdtms; std::vector meanretis; std::vector stdretis; + bool lastspotdup; bool previewDeltaE; int locallColorMask; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 36c571291..8b05a7bb4 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -360,7 +360,8 @@ enum class BlurType { double& huerefblur, double &chromarefblur, double& lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, int &lastsav, bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab); + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, + float &highresi, float &nresi, float &highresi46, float &nresi46, float &Lhighresi, float &Lnresi, float &Lhighresi46, float &Lnresi46); void addGaNoise(LabImage *lab, LabImage *dst, const float mean, const float variance, const int sk); void BlurNoise_Localold(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage* const tmp1, int cx, int cy); @@ -399,7 +400,8 @@ enum class BlurType { void DeNoise_Local(int call, const struct local_params& lp, LabImage* originalmask, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk); void DeNoise_Local2(const struct local_params& lp, LabImage* originalmask, int levred, float hueref, float lumaref, float chromaref, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy, int sk); - void DeNoise(int call, float * slidL, float * slida, float * slidb, int aut, bool noiscfactiv, const struct local_params& lp, LabImage* originalmaskbl, LabImage * bufmaskblurbl, int levred, float huerefblur, float lumarefblur, float chromarefblur, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const LocwavCurve& locwavCurvehue, bool locwavhueutili); + void DeNoise(int call, int aut, bool noiscfactiv, const struct local_params& lp, LabImage* originalmaskbl, LabImage * bufmaskblurbl, int levred, float huerefblur, float lumarefblur, float chromarefblur, LabImage* original, LabImage* transformed, + int cx, int cy, int sk, const LocwavCurve& locwavCurvehue, bool locwavhueutili, float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46); void fftw_denoise(int sk, 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); @@ -462,7 +464,7 @@ enum class BlurType { void ShrinkAll_info(const float* const* WavCoeffs_a, const float* const* 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); - void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); + void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb, int beg, int end); void calcautodn_info(float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc); float Mad(const float * DataList, int datalen); float MadRgb(const float * DataList, int datalen); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index b9e82cc5d..adc762710 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -10872,7 +10872,8 @@ void ImProcFunctions::fftw_denoise(int sk, int GW, int GH, int max_numblox_W, in } -void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * slidb, int aut, bool noiscfactiv, const struct local_params & lp, LabImage * originalmaskbl, LabImage * bufmaskblurbl, int levred, float huerefblur, float lumarefblur, float chromarefblur, LabImage * original, LabImage * transformed, int cx, int cy, int sk, const LocwavCurve& locwavCurvehue, bool locwavhueutili) +void ImProcFunctions::DeNoise(int call, int aut, bool noiscfactiv, const struct local_params & lp, LabImage * originalmaskbl, LabImage * bufmaskblurbl, int levred, float huerefblur, float lumarefblur, float chromarefblur, LabImage * original, LabImage * transformed, + int cx, int cy, int sk, const LocwavCurve& locwavCurvehue, bool locwavhueutili, float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46) { BENCHFUN //local denoise @@ -10943,7 +10944,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - // if (call == 1 && GW >= mDEN && GH >= mDEN) { if (call == 1 && ((GW >= mDEN && GH >= mDEN && isnois) || lp.quamet == 2)) { @@ -10965,6 +10965,9 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl tmp1.a[ir][jr] = original->a[ir][jr]; tmp1.b[ir][jr] = original->b[ir][jr]; } + if(lp.nlstr > 0) { + NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); + } float gamma = lp.noisegam; rtengine::GammaValues g_a; //gamma parameters @@ -11003,14 +11006,13 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl if (!Ldecomp.memory_allocation_failed()) { #ifdef _OPENMP - #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) + // #pragma omp parallel for schedule(dynamic) collapse(2) if (multiThread) #endif for (int lvl = 0; lvl < levred; lvl++) { for (int dir = 1; dir < 4; dir++) { int Wlvl_L = Ldecomp.level_W(lvl); int Hlvl_L = Ldecomp.level_H(lvl); const float* const* WavCoeffs_L = Ldecomp.level_coeffs(lvl); - madL[lvl][dir - 1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); } } @@ -11019,67 +11021,36 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float mxsl = 0.f; // float mxsfl = 0.f; - if (aut == 0) { - if (levred == 7) { - edge = 2; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); + edge = 2; + vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); + vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); + vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[4] = 0.8f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); - vari[5] = 0.8f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); - vari[6] = 0.8f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); - } else if (levred == 4) { - edge = 3; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - vari[0] = SQR(slidL[0]); - vari[1] = SQR(slidL[1]); - vari[2] = SQR(slidL[2]); - vari[3] = SQR(slidL[3]); - vari[4] = SQR(slidL[4]); - vari[5] = SQR(slidL[5]); - vari[6] = SQR(slidL[6]); - float mxslid34 = rtengine::max(slidL[3], slidL[4]); - float mxslid56 = rtengine::max(slidL[5], slidL[6]); - mxsl = rtengine::max(mxslid34, mxslid56); - - } + vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); + vari[4] = 1.f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); + vari[5] = 1.5f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); + vari[6] = 2.5f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); { float kr3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noiselc < 30.f && aut == 0) || (mxsl < 30.f && aut == 1)) { + if (lp.noiselc < 30.f) { kr3 = 0.f; - } else if ((lp.noiselc < 50.f && aut == 0) || (mxsl < 50.f && aut == 1)) { + } else if (lp.noiselc < 50.f) { kr3 = 0.5f; - } else if ((lp.noiselc < 70.f && aut == 0) || (mxsl < 70.f && aut == 1)) { + } else if (lp.noiselc < 70.f) { kr3 = 0.7f; } else { kr3 = 1.f; } - } else if (aut == 2) { - kr3 = 1.f; - } vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); - - if (levred == 7) { - vari[4] = rtengine::max(0.000001f, vari[4]); - vari[5] = rtengine::max(0.000001f, vari[5]); - vari[6] = rtengine::max(0.000001f, vari[6]); - } + vari[4] = rtengine::max(0.000001f, vari[4]); + vari[5] = rtengine::max(0.000001f, vari[5]); + vari[6] = rtengine::max(0.000001f, vari[6]); float* noisevarlum = new float[GH * GW]; float* noisevarhue = new float[GH * GW]; @@ -11218,75 +11189,25 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { - float maxcfine = 0.f; float maxccoarse = 0.f; - if (aut == 0) { - if (levred == 7) { - edge = 2; - variC[0] = SQR(noisecfr); - variC[1] = SQR(noisecfr); - variC[2] = SQR(noisecfr); + edge = 2; + variC[0] = SQR(noisecfr); + variC[1] = SQR(noisecfr); + variC[2] = SQR(noisecfr); + variC[3] = SQR(1.2f * noisecfr); + variC[4] = SQR(noisecfr); + variC[5] = SQR(1.2f * noiseccr); + variC[6] = SQR(1.5f * noiseccr); - 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(1.2f * noiseccb); + variCb[6] = SQR(1.5f * noiseccb); - 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); - - } else if (levred == 4) { - edge = 3; - variC[0] = SQR(lp.noisecf / 10.f); - variC[1] = SQR(lp.noisecf / 10.f); - variC[2] = SQR(lp.noisecf / 10.f); - variC[3] = SQR(lp.noisecf / 10.f); - - variCb[0] = SQR(lp.noisecf / 10.f); - variCb[1] = SQR(lp.noisecf / 10.f); - variCb[2] = SQR(lp.noisecf / 10.f); - variCb[3] = SQR(lp.noisecf / 10.f); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - variC[0] = SQR(slida[0]); - variC[1] = SQR(slida[1]); - variC[2] = SQR(slida[2]); - variC[3] = SQR(slida[3]); - variC[4] = SQR(slida[4]); - variC[5] = SQR(slida[5]); - variC[6] = SQR(slida[6]); - float maxc01 = rtengine::max(slida[0], slida[1]); - float maxc23 = rtengine::max(slida[2], slida[3]); - float max03 = rtengine::max(maxc01, maxc23); - float maxrf = rtengine::max(max03, slida[4]); - float maxrc = rtengine::max(slida[5], slida[6]); - - variCb[0] = SQR(slidb[0]); - variCb[1] = SQR(slidb[1]); - variCb[2] = SQR(slidb[2]); - variCb[3] = SQR(slidb[3]); - variCb[4] = SQR(slidb[4]); - variCb[5] = SQR(slidb[5]); - variCb[6] = SQR(slidb[6]); - float maxb01 = rtengine::max(slidb[0], slidb[1]); - float maxb23 = rtengine::max(slidb[2], slidb[3]); - float maxb03 = rtengine::max(maxb01, maxb23); - float maxbf = rtengine::max(maxb03, slidb[4]); - maxcfine = rtengine::max(maxrf, maxbf); - - float maxbc = rtengine::max(slidb[5], slidb[6]); - maxccoarse = rtengine::max(maxrc, maxbc); - - } { float minic = 0.000001f; @@ -11299,52 +11220,51 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float k2 = 0.f; float k3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noisecf < 0.2f && aut == 0) || (maxcfine < 0.2f && aut == 1)) { + if (lp.noisecf < 0.2f) { k1 = 0.05f; k2 = 0.f; k3 = 0.f; - } else if ((lp.noisecf < 0.3f && aut == 0) || (maxcfine < 0.3f && aut == 1)) { + } else if (lp.noisecf < 0.3f) { k1 = 0.1f; k2 = 0.0f; k3 = 0.f; - } else if ((lp.noisecf < 0.5f && aut == 0) || (maxcfine < 0.5f && aut == 1)) { + } else if (lp.noisecf < 0.5f) { k1 = 0.2f; k2 = 0.1f; k3 = 0.f; - } else if ((lp.noisecf < 0.8f && aut == 0) || (maxcfine < 0.8f && aut == 1)) { + } else if (lp.noisecf < 0.8f) { k1 = 0.3f; k2 = 0.25f; k3 = 0.f; - } else if ((lp.noisecf < 1.f && aut == 0) || (maxcfine < 1.f && aut == 1)) { + } else if (lp.noisecf < 1.f) { k1 = 0.4f; k2 = 0.25f; k3 = 0.1f; - } else if ((lp.noisecf < 2.f && aut == 0) || (maxcfine < 2.f && aut == 1)) { + } else if (lp.noisecf < 2.f) { k1 = 0.5f; k2 = 0.3f; k3 = 0.15f; - } else if ((lp.noisecf < 3.f && aut == 0) || (maxcfine < 3.f && aut == 1)) { + } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; - } else if ((lp.noisecf < 4.f && aut == 0) || (maxcfine < 4.f && aut == 1)) { + } else if (lp.noisecf < 4.f) { k1 = 0.7f; k2 = 0.5f; k3 = 0.4f; - } else if ((lp.noisecf < 5.f && aut == 0) || (maxcfine < 5.f && aut == 1)) { + } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; - } else if ((lp.noisecf < 6.f && aut == 0) || (maxcfine < 10.f && aut == 1)) { + } else if (lp.noisecf < 6.f) { k1 = 0.85f; k2 = 0.7f; k3 = 0.6f; - } else if ((lp.noisecf < 8.f && aut == 0) || (maxcfine < 20.f && aut == 1)) { + } else if (lp.noisecf < 8.f) { k1 = 0.9f; k2 = 0.8f; k3 = 0.7f; - } else if ((lp.noisecf < 10.f && aut == 0) || (maxcfine < 50.f && aut == 1)) { + } else if (lp.noisecf < 10.f) { k1 = 1.f; k2 = 1.f; k3 = 0.9f; @@ -11352,14 +11272,8 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } else { k1 = 1.f; k2 = 1.f; - k3 = 1.f; + k3 = 1.5f; } - } else if (aut == 2) { - k1 = 1.f; - k2 = 1.f; - k3 = 1.f; - } - variC[0] = rtengine::max(minic, variC[0]); variC[1] = rtengine::max(minic, k1 * variC[1]); @@ -11371,27 +11285,26 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[2] = rtengine::max(minic, k2 * variCb[2]); variCb[3] = rtengine::max(minic, k3 * variCb[3]); - if (levred == 7) { float k4 = 0.f; float k5 = 0.f; float k6 = 0.f; - if ((lp.noisecc < 0.2f && aut == 0) || (maxccoarse < 0.2f && aut == 1)) { + if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.02f; - } else if ((lp.noisecc < 0.5f && aut == 0) || (maxccoarse < 0.5f && aut == 1)) { + } else if (lp.noisecc < 0.5f) { k4 = 0.15f; k5 = 0.05f; - } else if ((lp.noisecc < 1.f && aut == 0) || (maxccoarse < 1.f && aut == 1)) { + } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if ((lp.noisecc < 3.f && aut == 0) || (maxccoarse < 3.f && aut == 1)) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; k5 = 0.6f; } else { @@ -11404,11 +11317,11 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[4] = rtengine::max(0.000001f, k4 * variCb[4]); variCb[5] = rtengine::max(0.000001f, k5 * variCb[5]); - if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 4.f && aut == 1)) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if ((lp.noisecc < 5.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k6 = 0.7f; } else { k6 = 1.f; @@ -11417,7 +11330,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variC[6] = rtengine::max(0.00001f, k6 * variC[6]); variCb[6] = rtengine::max(0.00001f, k6 * variCb[6]); - } float* noisevarchrom = new float[GH * GW]; //noisevarchrom in function chroma @@ -11425,7 +11337,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float nvch = 0.6f;//high value float nvcl = 0.1f;//low value - if ((lp.noisecf > 100.f && aut == 0) || (maxcfine > 100.f && (aut == 1 || aut == 2))) { + if (lp.noisecf > 100.f) { nvch = 0.8f; nvcl = 0.4f; } @@ -11534,7 +11446,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - if(gamma > 1.f) { #ifdef _OPENMP # pragma omp parallel for schedule(dynamic,16) if (multiThread) @@ -11552,10 +11463,6 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } - if(lp.nlstr > 0) { - NLMeans(tmp1.L, lp.nlstr, lp.nldet, lp.nlpat, lp.nlrad, lp.nlgam, GW, GH, float (sk), multiThread); - } - if(lp.smasktyp != 0) { if(lp.enablMask && lp.recothrd != 1.f) { LabImage tmp3(GW, GH); @@ -11634,7 +11541,82 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl masklum.free(); masklumch.free(); } - DeNoise_Local(call, lp, originalmaskbl, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); + +// re read wavelet decomposition to calaculate noise residual + float chresid = 0.f; + float chresidtemp = 0.f; + float chmaxresid = 0.f; + float chmaxresidtemp = 0.f; + float chresid46 = 0.f; + float chresidtemp46 = 0.f; + float chmaxresid46 = 0.f; + float chmaxresidtemp46 = 0.f; + float Lresid = 0.f; + float Lmaxresid = 0.f; + float Lresid46 = 0.f; + float Lmaxresid46 = 0.f; + + +//calculate and display residual noise luma and chroma +// various coefficient from 1 to 5 - tries to take into account the difference between calculate Noise and percepted noise + wavelet_decomposition Ldecompinf(tmp1.L[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + wavelet_decomposition adecompinf(tmp1.a[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + wavelet_decomposition bdecompinf(tmp1.b[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, lp.daubLen); + + Noise_residualAB(adecompinf, chresid, chmaxresid, false, 0, 3); + chresidtemp = chresid; + chmaxresidtemp = chmaxresid; + Noise_residualAB(bdecompinf, chresid, chmaxresid, false, 0, 3); + chresid += chresidtemp; + chmaxresid += chmaxresidtemp; + int nbmaddir = 4; + chresid = sqrt(chresid / ( 3 * nbmaddir * 2)); + highresi = chresid + 0.5f * (sqrt(chmaxresid) - chresid); //evaluate sigma + nresi = chresid; + highresi /= 1.4f;//arbitrary coefficient + nresi /= 1.4f; + + // printf("nresi03=%f highresi=%f \n", (double) nresi, (double) highresi); + + + Noise_residualAB(adecompinf, chresid46, chmaxresid46, false, 4, 6); + nbmaddir = 3; + chresidtemp46 = chresid46; + chmaxresidtemp46 = chmaxresid46; + Noise_residualAB(bdecompinf, chresid46, chmaxresid46, false, 4, 6); + chresid46 += chresidtemp46; + chmaxresid46 += chmaxresidtemp46; + chresid46 = sqrt(chresid46 / ( 3 * nbmaddir * 2)); + highresi46 = chresid46 + 0.5f * (sqrt(chmaxresid46) - chresid46); //evaluate sigma + nresi46 = chresid46; + highresi46 /= 2.f;//arbitrary coefficient + nresi46 /= 2.f; + + // printf("nresi46=%f highresi=%f \n", (double) nresi46, (double) highresi46); + + + Noise_residualAB(Ldecompinf, Lresid, Lmaxresid, false, 0, 3); + nbmaddir = 4; + Lresid = sqrt(Lresid / (3 * nbmaddir)); + Lhighresi = Lresid + 0.5f * (sqrt(Lmaxresid) - Lresid); //evaluate sigma + Lnresi = Lresid; + Lnresi /= 2.f;//arbitrary coefficient + Lhighresi /= 2.f; + // printf("Lresi03=%f Lhighresi=%f levwavL=%i\n", (double) Lnresi, (double) Lhighresi, levwavL); + + Noise_residualAB(Ldecompinf, Lresid46, Lmaxresid46, false, 4, 6); + nbmaddir = 3; + Lresid46 = sqrt(Lresid46 / (3 * nbmaddir)); + Lhighresi46 = Lresid46 + 0.5f * (sqrt(Lmaxresid46) - Lresid46); //evaluate sigma + Lnresi46 = Lresid46; + Lhighresi46 /= 5.f;//arbitrary coefficient + Lnresi46 /= 5.f; + // printf("Lresi46=%f Lhighresi=%f levwavL=%i\n", (double) Lnresi46, (double) Lhighresi46, levwavL); + +// end calculate + + DeNoise_Local(call, lp, originalmaskbl, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); + } else { DeNoise_Local(call, lp, original, levred, huerefblur, lumarefblur, chromarefblur, original, transformed, tmp1, cx, cy, sk); } @@ -11731,69 +11713,40 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float vari[levred]; float mxsl = 0.f; - // float mxsfl = 0.f; - if (aut == 0) { - if (levred == 7) { + { edge = 2; vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); vari[2] = 0.8f * SQR((lp.noiself2 / 125.f) * (1.f + lp.noiself2 / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[4] = 0.8f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); - vari[5] = 0.8f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); - vari[6] = 0.8f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); - } else if (levred == 4) { - edge = 3; - vari[0] = 0.8f * SQR((lp.noiself0 / 125.f) * (1.f + lp.noiself0 / 25.f)); - vari[1] = 0.8f * SQR((lp.noiself / 125.f) * (1.f + lp.noiself / 25.f)); - vari[2] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - vari[3] = 0.8f * SQR((lp.noiselc / 125.f) * (1.f + lp.noiselc / 25.f)); - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - vari[0] = SQR(slidL[0]); - vari[1] = SQR(slidL[1]); - vari[2] = SQR(slidL[2]); - vari[3] = SQR(slidL[3]); - vari[4] = SQR(slidL[4]); - vari[5] = SQR(slidL[5]); - vari[6] = SQR(slidL[6]); - float mxslid34 = rtengine::max(slidL[3], slidL[4]); - float mxslid56 = rtengine::max(slidL[5], slidL[6]); - mxsl = rtengine::max(mxslid34, mxslid56); - - } + vari[4] = 1.f * SQR((lp.noiselc4 / 125.f) * (1.f + lp.noiselc4 / 25.f)); + vari[5] = 1.5f * SQR((lp.noiselc5 / 125.f) * (1.f + lp.noiselc5 / 25.f)); + vari[6] = 2.5f * SQR((lp.noiselc6 / 125.f) * (1.f + lp.noiselc6 / 25.f)); + } { float kr3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noiselc < 30.f && aut == 0) || (mxsl < 30.f && aut == 1)) { + { + if (lp.noiselc < 30.f) { kr3 = 0.f; - } else if ((lp.noiselc < 50.f && aut == 0) || (mxsl < 50.f && aut == 1)) { + } else if (lp.noiselc < 50.f) { kr3 = 0.5f; - } else if ((lp.noiselc < 70.f && aut == 0) || (mxsl < 70.f && aut == 1)) { + } else if (lp.noiselc < 70.f) { kr3 = 0.7f; } else { kr3 = 1.f; } - } else if (aut == 2) { - kr3 = 1.f; - } + } vari[0] = rtengine::max(0.000001f, vari[0]); vari[1] = rtengine::max(0.000001f, vari[1]); vari[2] = rtengine::max(0.000001f, vari[2]); vari[3] = rtengine::max(0.000001f, kr3 * vari[3]); - - if (levred == 7) { - vari[4] = rtengine::max(0.000001f, vari[4]); - vari[5] = rtengine::max(0.000001f, vari[5]); - vari[6] = rtengine::max(0.000001f, vari[6]); - } + vari[4] = rtengine::max(0.000001f, vari[4]); + vari[5] = rtengine::max(0.000001f, vari[5]); + vari[6] = rtengine::max(0.000001f, vari[6]); // float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL float* noisevarlum = new float[bfh * bfw]; @@ -11930,77 +11883,28 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl if (!adecomp.memory_allocation_failed() && !bdecomp.memory_allocation_failed()) { - float maxcfine = 0.f; float maxccoarse = 0.f; - if (aut == 0) { - if (levred == 7) { + { edge = 2; variC[0] = SQR(noisecfr); variC[1] = SQR(noisecfr); variC[2] = SQR(noisecfr); - - variC[3] = SQR(noisecfr); + variC[3] = SQR(1.2f * noisecfr); variC[4] = SQR(noisecfr); - variC[5] = SQR(noiseccr); - variC[6] = SQR(noiseccr); + variC[5] = SQR(1.2f * noiseccr); + variC[6] = SQR(1.5f * 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); + variCb[5] = SQR(1.2f * noiseccb); + variCb[6] = SQR(1.5f * noiseccb); - } else if (levred == 4) { - edge = 3; - variC[0] = SQR(lp.noisecf / 10.f); - variC[1] = SQR(lp.noisecf / 10.f); - variC[2] = SQR(lp.noisecf / 10.f); - variC[3] = SQR(lp.noisecf / 10.f); - - variCb[0] = SQR(lp.noisecf / 10.f); - variCb[1] = SQR(lp.noisecf / 10.f); - variCb[2] = SQR(lp.noisecf / 10.f); - variCb[3] = SQR(lp.noisecf / 10.f); - - - } - } else if (aut == 1 || aut == 2) { - edge = 2; - variC[0] = SQR(slida[0]); - variC[1] = SQR(slida[1]); - variC[2] = SQR(slida[2]); - variC[3] = SQR(slida[3]); - variC[4] = SQR(slida[4]); - variC[5] = SQR(slida[5]); - variC[6] = SQR(slida[6]); - float maxc01 = rtengine::max(slida[0], slida[1]); - float maxc23 = rtengine::max(slida[2], slida[3]); - float max03 = rtengine::max(maxc01, maxc23); - float maxrf = rtengine::max(max03, slida[4]); - float maxrc = rtengine::max(slida[5], slida[6]); - - variCb[0] = SQR(slidb[0]); - variCb[1] = SQR(slidb[1]); - variCb[2] = SQR(slidb[2]); - variCb[3] = SQR(slidb[3]); - variCb[4] = SQR(slidb[4]); - variCb[5] = SQR(slidb[5]); - variCb[6] = SQR(slidb[6]); - float maxb01 = rtengine::max(slidb[0], slidb[1]); - float maxb23 = rtengine::max(slidb[2], slidb[3]); - float maxb03 = rtengine::max(maxb01, maxb23); - float maxbf = rtengine::max(maxb03, slidb[4]); - maxcfine = rtengine::max(maxrf, maxbf); - - float maxbc = rtengine::max(slidb[5], slidb[6]); - maxccoarse = rtengine::max(maxrc, maxbc); - - } + } { float minic = 0.000001f; @@ -12013,52 +11917,51 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float k2 = 0.f; float k3 = 0.f; - if (aut == 0 || aut == 1) { - if ((lp.noisecf < 0.2f && aut == 0) || (maxcfine < 0.2f && aut == 1)) { + if (lp.noisecf < 0.2f) { k1 = 0.05f; k2 = 0.f; k3 = 0.f; - } else if ((lp.noisecf < 0.3f && aut == 0) || (maxcfine < 0.3f && aut == 1)) { + } else if (lp.noisecf < 0.3f) { k1 = 0.1f; k2 = 0.0f; k3 = 0.f; - } else if ((lp.noisecf < 0.5f && aut == 0) || (maxcfine < 0.5f && aut == 1)) { + } else if (lp.noisecf < 0.5f) { k1 = 0.2f; k2 = 0.1f; k3 = 0.f; - } else if ((lp.noisecf < 0.8f && aut == 0) || (maxcfine < 0.8f && aut == 1)) { + } else if (lp.noisecf < 0.8f) { k1 = 0.3f; k2 = 0.25f; k3 = 0.f; - } else if ((lp.noisecf < 1.f && aut == 0) || (maxcfine < 1.f && aut == 1)) { + } else if (lp.noisecf < 1.f) { k1 = 0.4f; k2 = 0.25f; k3 = 0.1f; - } else if ((lp.noisecf < 2.f && aut == 0) || (maxcfine < 2.f && aut == 1)) { + } else if (lp.noisecf < 2.f) { k1 = 0.5f; k2 = 0.3f; k3 = 0.15f; - } else if ((lp.noisecf < 3.f && aut == 0) || (maxcfine < 3.f && aut == 1)) { + } else if (lp.noisecf < 3.f) { k1 = 0.6f; k2 = 0.45f; k3 = 0.3f; - } else if ((lp.noisecf < 4.f && aut == 0) || (maxcfine < 4.f && aut == 1)) { + } else if (lp.noisecf < 4.f) { k1 = 0.7f; k2 = 0.5f; k3 = 0.4f; - } else if ((lp.noisecf < 5.f && aut == 0) || (maxcfine < 5.f && aut == 1)) { + } else if (lp.noisecf < 5.f) { k1 = 0.8f; k2 = 0.6f; k3 = 0.5f; - } else if ((lp.noisecf < 6.f && aut == 0) || (maxcfine < 10.f && aut == 1)) { + } else if (lp.noisecf < 6.f) { k1 = 0.85f; k2 = 0.7f; k3 = 0.6f; - } else if ((lp.noisecf < 8.f && aut == 0) || (maxcfine < 20.f && aut == 1)) { + } else if (lp.noisecf < 8.f) { k1 = 0.9f; k2 = 0.8f; k3 = 0.7f; - } else if ((lp.noisecf < 10.f && aut == 0) || (maxcfine < 50.f && aut == 1)) { + } else if (lp.noisecf < 10.f) { k1 = 1.f; k2 = 1.f; k3 = 0.9f; @@ -12066,13 +11969,8 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } else { k1 = 1.f; k2 = 1.f; - k3 = 1.f; + k3 = 1.5f; } - } else if (aut == 2) { - k1 = 1.f; - k2 = 1.f; - k3 = 1.f; - } variC[0] = rtengine::max(minic, variC[0]); variC[1] = rtengine::max(minic, k1 * variC[1]); @@ -12084,27 +11982,27 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[2] = rtengine::max(minic, k2 * variCb[2]); variCb[3] = rtengine::max(minic, k3 * variCb[3]); - if (levred == 7) { + { float k4 = 0.f; float k5 = 0.f; float k6 = 0.f; - if ((lp.noisecc < 0.2f && aut == 0) || (maxccoarse < 0.2f && aut == 1)) { + if (lp.noisecc < 0.2f) { k4 = 0.1f; k5 = 0.02f; - } else if ((lp.noisecc < 0.5f && aut == 0) || (maxccoarse < 0.5f && aut == 1)) { + } else if (lp.noisecc < 0.5f) { k4 = 0.15f; k5 = 0.05f; - } else if ((lp.noisecc < 1.f && aut == 0) || (maxccoarse < 1.f && aut == 1)) { + } else if (lp.noisecc < 1.f) { k4 = 0.15f; k5 = 0.1f; - } else if ((lp.noisecc < 3.f && aut == 0) || (maxccoarse < 3.f && aut == 1)) { + } else if (lp.noisecc < 3.f) { k4 = 0.3f; k5 = 0.15f; - } else if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 4.f) { k4 = 0.6f; k5 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k4 = 0.8f; k5 = 0.6f; } else { @@ -12118,11 +12016,11 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl variCb[4] = rtengine::max(0.000001f, k4 * variCb[4]); variCb[5] = rtengine::max(0.000001f, k5 * variCb[5]); - if ((lp.noisecc < 4.f && aut == 0) || (maxccoarse < 4.f && aut == 1)) { + if (lp.noisecc < 4.f) { k6 = 0.f; - } else if ((lp.noisecc < 5.f && aut == 0) || (maxccoarse < 5.f && aut == 1)) { + } else if (lp.noisecc < 5.f) { k6 = 0.4f; - } else if ((lp.noisecc < 6.f && aut == 0) || (maxccoarse < 6.f && aut == 1)) { + } else if (lp.noisecc < 6.f) { k6 = 0.7f; } else { k6 = 1.f; @@ -12137,7 +12035,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl float nvch = 0.6f;//high value float nvcl = 0.1f;//low value - if ((lp.noisecf > 30.f && aut == 0) || (maxcfine > 100.f && (aut == 1 || aut == 2))) { + if (lp.noisecf > 30.f) { nvch = 0.8f; nvcl = 0.4f; } @@ -12377,6 +12275,7 @@ void ImProcFunctions::DeNoise(int call, float * slidL, float * slida, float * sl } } } + } } @@ -13363,7 +13262,9 @@ void ImProcFunctions::Lab_Local( double& huerefblur, double& chromarefblur, double& lumarefblur, double& hueref, double& chromaref, double& lumaref, double& sobelref, int &lastsav, bool prevDeltaE, int llColorMask, int llColorMaskinv, int llExpMask, int llExpMaskinv, int llSHMask, int llSHMaskinv, int llvibMask, int lllcMask, int llsharMask, int llcbMask, int llretiMask, int llsoftMask, int lltmMask, int llblMask, int lllogMask, int ll_Mask, int llcieMask, float& minCD, float& maxCD, float& mini, float& maxi, float& Tmean, float& Tsigma, float& Tmin, float& Tmax, - float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab + float& meantm, float& stdtm, float& meanreti, float& stdreti, float &fab, + float& highresi, float& nresi, float& highresi46, float& nresi46, float& Lhighresi, float& Lnresi, float& Lhighresi46, float& Lnresi46 + ) { //general call of others functions : important return hueref, chromaref, lumaref @@ -14410,12 +14311,9 @@ void ImProcFunctions::Lab_Local( //local denoise if (lp.activspot && lp.denoiena && (lp.noiself > 0.f || lp.noiself0 > 0.f || lp.noiself2 > 0.f || lp.wavcurvedenoi ||lp.nlstr > 0 || lp.noiselc > 0.f || lp.noisecf > 0.f || lp.noisecc > 0.f )) {//disable denoise if not used - float slidL[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float slida[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; - float slidb[8] = {0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f, 0.f}; constexpr int aut = 0; - DeNoise(call, slidL, slida, slidb, aut, noiscfactiv, lp, originalmaskbl.get(), bufmaskblurbl.get(), levred, huerefblur, lumarefblur, chromarefblur, original, transformed, cx, cy, sk, locwavCurvehue, locwavhueutili); - + DeNoise(call, aut, noiscfactiv, lp, originalmaskbl.get(), bufmaskblurbl.get(), levred, huerefblur, lumarefblur, chromarefblur, original, transformed, cx, cy, sk, locwavCurvehue, locwavhueutili, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46); if (lp.recur) { original->CopyFrom(transformed, multiThread); float avge; @@ -19275,6 +19173,7 @@ void ImProcFunctions::Lab_Local( calc_ref(sp, original, transformed, 0, 0, original->W, original->H, sk, huerefblur, chromarefblur, lumarefblur, hueref, chromaref, lumaref, sobelref, avge, locwavCurveden, locwavdenutili); } } + } diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h index f86950457..1d7994ace 100644 --- a/rtengine/rtengine.h +++ b/rtengine/rtengine.h @@ -438,9 +438,21 @@ public: double Tmax; }; + struct locallabDenoiseLC { + double highres; + double nres; + double highres46; + double nres46; + double Lhighres; + double Lnres; + double Lhighres46; + double Lnres46; + }; + virtual ~LocallabListener() = default; // virtual void refChanged(const std::vector &ref, int selspot) = 0; virtual void minmaxChanged(const std::vector &minmax, int selspot) = 0; + virtual void denChanged(const std::vector &denlc, int selspot) = 0; virtual void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) = 0; virtual void refChanged2(float *huerefp, float *chromarefp, float *lumarefp, float *fabrefp, int selspot) = 0; }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index 78dd84042..96cd68d43 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1175,6 +1175,14 @@ private: float Tsigma; float Tmin; float Tmax; + float highresi = 0.f; + float nresi = 0.f; + float highresi46 =0.f; + float nresi46 = 0.f; + float Lhighresi = 0.f; + float Lnresi = 0.f; + float Lhighresi46 = 0.f; + float Lnresi46 = 0.f; // No Locallab mask is shown in exported picture ipf.Lab_Local(2, sp, shbuffer, labView, labView, reservView.get(), savenormtmView.get(), savenormretiView.get(), lastorigView.get(), fw, fh, 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, @@ -1229,7 +1237,8 @@ private: LHutili, HHutili, CHutili, HHutilijz, CHutilijz, LHutilijz, cclocalcurve, localcutili, rgblocalcurve, localrgbutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, lastsav, false, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, - meantme, stdtme, meanretie, stdretie, fab + meantme, stdtme, meanretie, stdretie, fab, + highresi, nresi, highresi46, nresi46, Lhighresi, Lnresi, Lhighresi46, Lnresi46 ); if (sp + 1u < params.locallab.spots.size()) { diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 8e8e999d3..e7725a005 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -703,6 +703,19 @@ void Locallab::write(rtengine::procparams::ProcParams* pp, ParamsEdited* pedited expreti.updateMinMax(cdma, cdmin, mini, maxi, Tmean, Tsigma, Tmin, Tmax); } + // Update Locallab Denoise tool lum/chro + if (pp->locallab.selspot < (int) denoiselc.size()) { + const double highres = denoiselc.at(pp->locallab.selspot).highres; + const double nres = denoiselc.at(pp->locallab.selspot).nres; + const double highres46 = denoiselc.at(pp->locallab.selspot).highres46; + const double nres46 = denoiselc.at(pp->locallab.selspot).nres46; + const double Lhighres = denoiselc.at(pp->locallab.selspot).Lhighres; + const double Lnres = denoiselc.at(pp->locallab.selspot).Lnres; + const double Lhighres46 = denoiselc.at(pp->locallab.selspot).Lhighres46; + const double Lnres46 = denoiselc.at(pp->locallab.selspot).Lnres46; + + expblur.updatedenlc(highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46); + } // Update default values according to selected spot setDefaults(pp, pedited); @@ -1094,6 +1107,28 @@ void Locallab::minmaxChanged(const std::vector &minmax, int } } +void Locallab::denChanged(const std::vector &denlc, int selspot) +{ + // Saving transmitted min/max data + denoiselc = denlc; + + //Update Locallab Denoise tool lum chro + if (selspot < (int) denoiselc.size()) { + const double highres = denoiselc.at(selspot).highres; + const double nres = denoiselc.at(selspot).nres; + const double highres46 = denoiselc.at(selspot).highres46; + const double nres46 = denoiselc.at(selspot).nres46; + const double Lhighres = denoiselc.at(selspot).Lhighres; + const double Lnres = denoiselc.at(selspot).Lnres; + const double Lhighres46 = denoiselc.at(selspot).Lhighres46; + const double Lnres46 = denoiselc.at(selspot).Lnres46; + + expblur.updatedenlc(highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46); + } + +} + + void Locallab::logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) { // Update Locallab Log Encoding and Ciecam accordingly diff --git a/rtgui/locallab.h b/rtgui/locallab.h index b0030bbe6..e39f213cc 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -123,6 +123,9 @@ private: // Locallab tools mask background management data std::vector retiMinMax; + // Locallab tools mask background management data + std::vector denoiselc; + // Locallab tools mask background management data std::vector maskBackRef; @@ -145,6 +148,10 @@ public: // Locallab Retinex tool min/man management function void minmaxChanged(const std::vector &minmax, int selspot) override; + //Locallab denoise + // Locallab Retinex tool min/man management function + void denChanged(const std::vector &denlc, int selspot) override; + // Locallab Log Encoding autocompute function void logencodChanged(const float blackev, const float whiteev, const float sourceg, const float sourceab, const float targetg, const bool autocomput, const bool autocie, const float jz1) override; diff --git a/rtgui/locallabtools.cc b/rtgui/locallabtools.cc index c59dd233a..2ebac1630 100644 --- a/rtgui/locallabtools.cc +++ b/rtgui/locallabtools.cc @@ -6477,8 +6477,17 @@ LocallabBlur::LocallabBlur(): activlum(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_ACTIV")))), expdenoise(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI_EXP")))), quamethod(Gtk::manage(new MyComboBoxText())), + expdenoisenl(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_NLFRA")))), + expdenoiselum(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOIWAVLUM")))), + expdenoisech(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOIWAVCH")))), LocalcurveEditorwavden(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_WAVDEN"))), wavshapeden(static_cast(LocalcurveEditorwavden->addCurve(CT_Flat, "", nullptr, false, false))), + // lCLabels(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_LCLABELS")))), + lCLabels(Gtk::manage(new Gtk::Label("-----------------"))), + lumLabels(Gtk::manage(new Gtk::Label("---"))), + lum46Labels(Gtk::manage(new Gtk::Label("---"))), + chroLabels(Gtk::manage(new Gtk::Label("---"))), + chro46Labels(Gtk::manage(new Gtk::Label("---"))), expdenoise1(Gtk::manage(new MyExpander(false, M("TP_LOCALLAB_DENOI1_EXP")))), maskusable(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUSABLE")))), maskunusable(Gtk::manage(new Gtk::Label(M("TP_LOCALLAB_MASKUNUSABLE")))), @@ -6514,7 +6523,7 @@ LocallabBlur::LocallabBlur(): decayd(Gtk::manage(new Adjuster(M("TP_LOCALLAB_MASKDDECAY"), 0.5, 4., 0.1, 2.))), invmaskd(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVMASK")))), invmask(Gtk::manage(new Gtk::CheckButton(M("TP_LOCALLAB_INVMASK")))), - nlFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_NLFRA")))), + prevFrame(Gtk::manage(new Gtk::Frame(M("TP_LOCALLAB_LCLABELS")))), nlstr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLLUM"), 0, 100, 1, 0))), nldet(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLDET"), 0, 100, 1, 50))), nlpat(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NLPAT"), 1, 5, 1, 2))), @@ -6640,12 +6649,23 @@ LocallabBlur::LocallabBlur(): Gtk::Label* const quaLabel = Gtk::manage(new Gtk::Label(M("TP_WAVELET_DENQUA") + ":")); quaHBox->pack_start(*quaLabel, Gtk::PACK_SHRINK, 4); quaHBox->pack_start(*quamethod); + setExpandAlignProperties(expdenoisenl, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + setExpandAlignProperties(expdenoiselum, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); + setExpandAlignProperties(expdenoisech, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); LocalcurveEditorwavden->setCurveListener(this); wavshapeden->setIdentityValue(0.); wavshapeden->setResetCurve(FlatCurveType(defSpot.locwavcurveden.at(0)), defSpot.locwavcurveden); + setExpandAlignProperties(lCLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(lumLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(lum46Labels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + + setExpandAlignProperties(chroLabels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + setExpandAlignProperties(chro46Labels, true, false, Gtk::ALIGN_CENTER, Gtk::ALIGN_START); + + LocalcurveEditorwavden->curveListComplete(); setExpandAlignProperties(expdenoise1, true, false, Gtk::ALIGN_FILL, Gtk::ALIGN_START); @@ -6701,7 +6721,7 @@ LocallabBlur::LocallabBlur(): decayd->setAdjusterListener(this); bilateral->setAdjusterListener(this); - nlFrame->set_label_align(0.025, 0.5); + prevFrame->set_label_align(0.025, 0.5); nlstr->setAdjusterListener(this); nldet->setAdjusterListener(this); @@ -6838,15 +6858,39 @@ LocallabBlur::LocallabBlur(): Gtk::Frame* const wavFrame = Gtk::manage(new Gtk::Frame()); ToolParamBlock* const wavBox = Gtk::manage(new ToolParamBlock()); wavBox->pack_start(*quaHBox); - wavBox->pack_start(*LocalcurveEditorwavden, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + wavBox->pack_start(*sensiden); + wavBox->pack_start(*reparden); + ToolParamBlock* const prevBox = Gtk::manage(new ToolParamBlock()); + prevBox->pack_start(*lumLabels); + prevBox->pack_start(*lum46Labels); + prevBox->pack_start(*lCLabels); + prevBox->pack_start(*chroLabels); + prevBox->pack_start(*chro46Labels); + prevFrame->add(*prevBox); + wavBox->pack_start(*prevFrame); + + ToolParamBlock* const nlbox = Gtk::manage(new ToolParamBlock()); + nlbox->pack_start(*nlstr); + nlbox->pack_start(*nldet); + nlbox->pack_start(*nlgam); + nlbox->pack_start(*nlpat); + nlbox->pack_start(*nlrad); + expdenoisenl->add(*nlbox); + + wavBox->pack_start(*expdenoisenl); + + // wavBox->pack_start(*noiselumf0); // wavBox->pack_start(*noiselumf); // wavBox->pack_start(*noiselumf2); // wavBox->pack_start(*noiselumc);//unused here, but used for normalize_mean_dt - wavBox->pack_start(*noiselumdetail); - wavBox->pack_start(*noiselequal); - wavBox->pack_start(*noisegam); - wavBox->pack_start(*LocalcurveEditorwavhue, Gtk::PACK_SHRINK, 4); + ToolParamBlock* const wchBox = Gtk::manage(new ToolParamBlock()); + + wchBox->pack_start(*LocalcurveEditorwavden, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor + wchBox->pack_start(*noiselumdetail); + wchBox->pack_start(*noiselequal); + wchBox->pack_start(*noisegam); + wchBox->pack_start(*LocalcurveEditorwavhue, Gtk::PACK_SHRINK, 4); ToolParamBlock* const wavBox1 = Gtk::manage(new ToolParamBlock()); wavBox1->pack_start(*maskusable, Gtk::PACK_SHRINK, 0); wavBox1->pack_start(*maskunusable, Gtk::PACK_SHRINK, 0); @@ -6854,28 +6898,24 @@ LocallabBlur::LocallabBlur(): wavBox1->pack_start(*levelthrlow, Gtk::PACK_SHRINK, 0); wavBox1->pack_start(*levelthr, Gtk::PACK_SHRINK, 0); expdenoise1->add(*wavBox1, false); - wavBox->pack_start(*expdenoise1); + wchBox->pack_start(*expdenoise1); + expdenoiselum->add(*wchBox); + wavBox->pack_start(*expdenoiselum); + ToolParamBlock* const chBox = Gtk::manage(new ToolParamBlock()); + + chBox->pack_start(*noisechrof); + chBox->pack_start(*noisechroc); + chBox->pack_start(*noisechrodetail); + chBox->pack_start(*adjblur); + expdenoisech->add(*chBox); + wavBox->pack_start(*expdenoisech); + ToolParamBlock* const detailBox = Gtk::manage(new ToolParamBlock()); detailBox->pack_start(*detailthr); detailBox->pack_start(*usemask, Gtk::PACK_SHRINK, 0); detailFrame->add(*detailBox); wavBox->pack_start(*detailFrame); - denoisebox->pack_start(*sensiden); - denoisebox->pack_start(*reparden); - - ToolParamBlock* const nlbox = Gtk::manage(new ToolParamBlock()); - nlbox->pack_start(*nlstr); - nlbox->pack_start(*nldet); - nlbox->pack_start(*nlgam); - nlbox->pack_start(*nlpat); - nlbox->pack_start(*nlrad); - nlFrame->add(*nlbox); - wavBox->pack_start(*nlFrame); - - wavBox->pack_start(*noisechrof); - wavBox->pack_start(*noisechroc); - wavBox->pack_start(*noisechrodetail); - wavBox->pack_start(*adjblur); + wavFrame->add(*wavBox); denoisebox->pack_start(*wavFrame); @@ -6978,6 +7018,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) expdenoise1->set_tooltip_markup(M("TP_LOCALLAB_MASKLC_TOOLTIP")); expdenoise2->set_tooltip_markup(M("TP_LOCALLAB_MASKGF_TOOLTIP")); expdenoise3->set_tooltip_markup(M("TP_LOCALLAB_MASKDE_TOOLTIP")); + expdenoisenl->set_tooltip_markup(M("TP_LOCALLAB_NLFRAME_TOOLTIP")); invmask->set_tooltip_text(M("TP_LOCALLAB_MASKDEINV_TOOLTIP")); invmaskd->set_tooltip_text(M("TP_LOCALLAB_MASKDEINV_TOOLTIP")); LocalcurveEditorwavden->setTooltip(M("TP_LOCALLAB_WASDEN_TOOLTIP")); @@ -6990,7 +7031,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) detailthr->set_tooltip_text(M("TP_LOCALLAB_DENOITHR_TOOLTIP")); adjblur->set_tooltip_text(M("TP_LOCALLAB_DENOIEQUALCHRO_TOOLTIP")); bilateral->set_tooltip_text(M("TP_LOCALLAB_DENOIBILAT_TOOLTIP")); - nlFrame->set_tooltip_text(M("TP_LOCALLAB_NLFRAME_TOOLTIP")); + prevFrame->set_tooltip_text(M("TP_LOCALLAB_LCLABELS_TOOLTIP")); nlstr->set_tooltip_text(M("TP_LOCALLAB_NLDENOISE_TOOLTIP")); nldet->set_tooltip_text(M("TP_LOCALLAB_NLDENOISE_TOOLTIP")); nlpat->set_tooltip_text(M("TP_LOCALLAB_NLDENOISENLPAT_TOOLTIP")); @@ -7025,6 +7066,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) higthresd->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRESD_TOOLTIP")); higthres->set_tooltip_text(M("TP_LOCALLAB_MASKHIGTHRES_TOOLTIP")); decayd->set_tooltip_text(M("TP_LOCALLAB_MASKDECAY_TOOLTIP")); + lCLabels->set_tooltip_text(M("TP_LOCALLAB_LCLABELS_TOOLTIP")); } else { expblnoise->set_tooltip_markup(""); @@ -7057,7 +7099,7 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) detailthr->set_tooltip_text(""); adjblur->set_tooltip_text(""); bilateral->set_tooltip_text(""); - nlFrame->set_tooltip_text(""); + prevFrame->set_tooltip_text(""); nlstr->set_tooltip_text(""); nldet->set_tooltip_text(""); nlpat->set_tooltip_text(""); @@ -7094,6 +7136,8 @@ void LocallabBlur::updateAdviceTooltips(const bool showTooltips) higthres->set_tooltip_text(""); // midthresd->set_tooltip_text(""); decayd->set_tooltip_text(""); + lCLabels->set_tooltip_text(""); + expdenoisenl->set_tooltip_markup(""); } } @@ -7138,7 +7182,36 @@ void LocallabBlur::neutral_pressed () } +void LocallabBlur::updatedenlc(const double highres, const double nres, const double highres46, const double nres46, const double Lhighres, const double Lnres, const double Lhighres46, const double Lnres46) +{ + idle_register.add( + [this, highres, nres, highres46, nres46, Lhighres, Lnres, Lhighres46, Lnres46]() -> bool { + GThreadLock lock; // All GUI access from idle_add callbacks or separate thread HAVE to be protected + lumLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_LUMLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), Lnres), + Glib::ustring::format(std::fixed, std::setprecision(0), Lhighres)) + ); + lum46Labels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_LUM46LABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), Lnres46 ), + Glib::ustring::format(std::fixed, std::setprecision(0), Lhighres46)) + ); + chroLabels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_CHROLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nres), + Glib::ustring::format(std::fixed, std::setprecision(0), highres)) + ); + chro46Labels->set_text( + Glib::ustring::compose(M("TP_LOCALLAB_CHRO46LABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nres46), + Glib::ustring::format(std::fixed, std::setprecision(0), highres46)) + ); + return false; + } + ); +} void LocallabBlur::setDefaultExpanderVisibility() { expblnoise->set_expanded(false); @@ -7147,6 +7220,9 @@ void LocallabBlur::setDefaultExpanderVisibility() expdenoise2->set_expanded(false); expdenoise3->set_expanded(false); expmaskbl->set_expanded(false); + expdenoisenl->set_expanded(false); + expdenoiselum->set_expanded(false); + expdenoisech->set_expanded(false); } void LocallabBlur::disableListener() diff --git a/rtgui/locallabtools.h b/rtgui/locallabtools.h index c4e54ca61..ced248ae1 100644 --- a/rtgui/locallabtools.h +++ b/rtgui/locallabtools.h @@ -707,8 +707,17 @@ private: Gtk::CheckButton* const activlum; MyExpander* const expdenoise; MyComboBoxText* const quamethod; + MyExpander* const expdenoisenl; + MyExpander* const expdenoiselum; + MyExpander* const expdenoisech; CurveEditorGroup* const LocalcurveEditorwavden; FlatCurveEditor* const wavshapeden; + Gtk::Label* const lCLabels; + Gtk::Label* const lumLabels; + Gtk::Label* const lum46Labels; + Gtk::Label* const chroLabels; + Gtk::Label* const chro46Labels; + MyExpander* const expdenoise1; Gtk::Label* const maskusable; Gtk::Label* const maskunusable; @@ -746,7 +755,7 @@ private: Gtk::CheckButton* const invmaskd; Gtk::CheckButton* const invmask; - Gtk::Frame* const nlFrame; + Gtk::Frame* const prevFrame; Adjuster* const nlstr; Adjuster* const nldet; Adjuster* const nlpat; @@ -788,6 +797,8 @@ private: public: LocallabBlur(); ~LocallabBlur(); + void updatedenlc(const double highres, const double nres, const double highres46, const double nres46, const double Lhighres, const double Lnres, const double Lhighres46, const double Lnres46); + bool isMaskViewActive() override; void resetMaskView() override;