From c1560f32c56c287868da804b32c859cd7808e447 Mon Sep 17 00:00:00 2001 From: Desmis Date: Fri, 27 Sep 2019 11:16:02 +0200 Subject: [PATCH] Add Transmission map to Retinex --- rtdata/languages/default | 2 ++ rtengine/curves.cc | 41 +++++++++++++++++++++++++++++++++ rtengine/curves.h | 28 +++++++++++++++++++++++ rtengine/dcrop.cc | 7 ++++-- rtengine/improccoordinator.cc | 6 +++-- rtengine/improccoordinator.h | 1 + rtengine/improcfun.h | 4 ++-- rtengine/iplocallab.cc | 10 ++++---- rtengine/ipretinex.cc | 43 ++++++++++++++++++++++++++++++++++- rtengine/procevents.h | 1 + rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtengine/refreshmap.cc | 3 ++- rtengine/simpleprocess.cc | 4 +++- rtgui/locallab.cc | 28 +++++++++++++++++++++++ rtgui/locallab.h | 2 ++ rtgui/paramsedited.cc | 7 ++++++ rtgui/paramsedited.h | 1 + 18 files changed, 179 insertions(+), 14 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index 62a9ccbdc..e5c4ef483 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -990,6 +990,7 @@ HISTORY_MSG_749;Local - Reti Depth HISTORY_MSG_750;Local - Reti Mode log - lin HISTORY_MSG_751;Local - Reti Dehaze luminance HISTORY_MSG_752;Local - Reti Offset +HISTORY_MSG_753;Local - Transmission map HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction @@ -2209,6 +2210,7 @@ TP_LOCALLAB_RETI_NEIGH_VART_TOOLTIP;Adapt these values according to images - if TP_LOCALLAB_LC_FFTW_TOOLTIP;FFT improve quality and allow big radius, but increases the treatment time.\nThe treatment time depends on the surface to be treated.\nTo be used preferably for large radius.\n\nDimensions can be reduced by a few pixels to optimize FFTW.\nThis optimization can reduce the treatment time by a factor of 1.5 to 10.\n TP_LOCALLAB_RETI_FFTW_TOOLTIP;FFT improve quality and allow big radius, but increases the treatment time.\nThe treatment time depends on the surface to be treated\nThe treatment time depends on the value of scale (be carefull to high values).\nTo be used preferably for large radius.\n\nDimensions can be reduced by a few pixels to optimize FFTW.\nThis optimization can reduce the treatment time by a factor of 1.5 to 10.\nNot used in Preview TP_LOCALLAB_TRANSMISSIONGAIN;Transmission gain +TP_LOCALLAB_TRANSMISSIONMAP;Transmission map TP_LOCALLAB_STREN;Compression Strength TP_LOCALLAB_STRGRID;Strength TP_LOCALLAB_SHADEX;Shadows diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 6a6b744b5..6b5ee40c6 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -2778,6 +2778,47 @@ void LocwavCurve::Set(const std::vector &curvePoints, bool & lcwavutili) } } +LocretitransCurve::LocretitransCurve() : sum(0.f) {}; + +void LocretitransCurve::Reset() +{ + lutLocretitransCurve.reset(); + sum = 0.f; +} + +void LocretitransCurve::Set(const Curve &pCurve) +{ + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + + lutLocretitransCurve(501); // raise this value if the quality suffers from this number of samples + sum = 0.f; + + for (int i = 0; i < 501; i++) { + lutLocretitransCurve[i] = pCurve.getVal(double (i) / 500.); + + if (lutLocretitransCurve[i] < 0.02f) { + lutLocretitransCurve[i] = 0.02f; //avoid 0.f for wavelet : under 0.01f quasi no action for each value + } + + sum += lutLocretitransCurve[i]; + } + + //lutLocCurve.dump("wav"); +} +void LocretitransCurve::Set(const std::vector &curvePoints) +{ + + if (!curvePoints.empty() && curvePoints[0] > FCT_Linear && curvePoints[0] < FCT_Unchanged) { + FlatCurve tcurve(curvePoints, false, CURVES_MIN_POLY_POINTS / 2); + tcurve.setIdentityValue(0.); + Set(tcurve); + } else { + Reset(); + } +} LocretigainCurve::LocretigainCurve() : sum(0.f) {}; diff --git a/rtengine/curves.h b/rtengine/curves.h index a6634ab86..de30ef045 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -1316,6 +1316,34 @@ public: } }; +class LocretitransCurve +{ +private: + LUTf lutLocretitransCurve; // 0xffff range + void Set(const Curve &pCurve); + +public: + float sum; + + virtual ~LocretitransCurve() {}; + LocretitransCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + float getSum() const + { + return sum; + } + + float operator[](float index) const + { + return lutLocretitransCurve[index]; + } + operator bool (void) const + { + return lutLocretitransCurve; + } +}; + class LocwavCurve { diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 3d6c11b05..ac4231c99 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -919,6 +919,7 @@ void Crop::update(int todo) LUTu dummy; bool needslocal = params.locallab.enabled; LocretigainCurve locRETgainCurve; + LocretitransCurve locRETtransCurve; LocLHCurve loclhCurve; LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; @@ -954,6 +955,7 @@ void Crop::update(int todo) if (needslocal) { for (int sp = 0; sp < params.locallab.nbspot && sp < (int)params.locallab.spots.size(); sp++) { locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); + locRETtransCurve.Set(params.locallab.spots.at(sp).localTtranscurve); loclhCurve.Set(params.locallab.spots.at(sp).LHcurve, LHutili); lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve, lcmasutili); @@ -1011,7 +1013,7 @@ void Crop::update(int todo) sca); // Locallab mask are only shown for selected spot if (sp == params.locallab.selspot) { - parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2,locallutili, + parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, lllocalcurve2,locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, @@ -1022,7 +1024,7 @@ void Crop::update(int todo) LHutili, HHutili, cclocalcurve2, localcutili, localexutili, exlocalcurve2, hltonecurveloc2, shtonecurveloc2, tonecurveloc2, lightCurveloc2, huerefblu, chromarefblu, lumarefblu, huere, chromare, lumare, sobelre, parent->locallColorMask, parent->locallColorMaskinv, parent->locallExpMask, parent->locallExpMaskinv, parent->locallSHMask, parent->locallSHMaskinv, parent->locallcbMask, parent->locallretiMask, parent->locallsoftMask, parent->localltmMask, parent->locallblMask); } else { - parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, lllocalcurve2,locallutili, + parent->ipf.Lab_Local(1, sp, (float**)shbuffer, labnCrop, labnCrop, reservCrop, cropx / skip, cropy / skip, skips(parent->fw, skip), skips(parent->fh, skip), skip, locRETgainCurve, locRETtransCurve, lllocalcurve2,locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, @@ -1040,6 +1042,7 @@ void Crop::update(int todo) shtonecurveloc2.clear(); tonecurveloc2.clear(); locRETgainCurve.Reset(); + locRETtransCurve.Reset(); loclhCurve.Reset(); lochhCurve.Reset(); locccmasCurve.Reset(); diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 8c2d57d1f..ac12d4830 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -934,6 +934,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) lcmasutili = false; locwavutili = false; locRETgainCurve.Set(params->locallab.spots.at(sp).localTgaincurve); + locRETtransCurve.Set(params->locallab.spots.at(sp).localTtranscurve); loclhCurve.Set(params->locallab.spots.at(sp).LHcurve, LHutili); lochhCurve.Set(params->locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params->locallab.spots.at(sp).CCmaskcurve, lcmasutili); @@ -1004,7 +1005,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) */ // Locallab mask are only shown for selected spot if (sp == params->locallab.selspot) { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, @@ -1014,7 +1015,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) LHutili, HHutili, cclocalcurve, localcutili, localexutili, exlocalcurve, hltonecurveloc, shtonecurveloc, tonecurveloc, lightCurveloc, huerblu, chromarblu, lumarblu, huer, chromar, lumar, sobeler, locallColorMask, locallColorMaskinv, locallExpMask, locallExpMaskinv, locallSHMask, locallSHMaskinv, locallcbMask, locallretiMask, locallsoftMask, localltmMask, locallblMask); } else { - ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + ipf.Lab_Local(3, sp, (float**)shbuffer, nprevl, nprevl, reserv, 0, 0, pW, pH, scale, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, @@ -1038,6 +1039,7 @@ void ImProcCoordinator::updatePreviewImage(int todo, bool panningRelatedChange) shtonecurveloc.clear(); tonecurveloc.clear(); locRETgainCurve.Reset(); + locRETtransCurve.Reset(); loclhCurve.Reset(); lochhCurve.Reset(); locccmasCurve.Reset(); diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 50029d6b0..c40340d1c 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -235,6 +235,7 @@ protected: LUTf lightCurveloc; // LUTu lhist16loc; LocretigainCurve locRETgainCurve; + LocretitransCurve locRETtransCurve; LocretigainCurverab locRETgainCurverab; LocLHCurve loclhCurve; LocHHCurve lochhCurve; diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index bb958ab07..9aaa92751 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -194,12 +194,12 @@ public: void fftw_convol_blur2(float **input2, float **output2, int bfw, int bfh, float radius, int fftkern, int algo); void fftw_tile_blur(int GW, int GH, int tilssize , int max_numblox_W, int min_numblox_W, float **tmp1, int numThreads, double radius); - void MSRLocal(int sp, bool fftw, int lum, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, + void MSRLocal(int sp, bool fftw, int lum, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const procparams::LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, LabImage * transformed, bool retiMasktmap, bool retiMask); void calc_ref(int sp, LabImage* original, LabImage* transformed, int cx, int cy, int oW, int oH, int sk, double &huerefblur, double &chromarefblur, double &lumarefblur, double &hueref, double &chromaref, double &lumaref, double &sobelref, float &avg); void copy_ref(LabImage* spotbuffer, LabImage* original, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp, double &huerefspot, double &chromarefspot, double &lumarefspot); void paste_ref(LabImage* spotbuffer, LabImage* transformed, int cx, int cy, int sk, const struct local_params & lp); - void Lab_Local(int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool & lhmasutili, + void Lab_Local(int call, int sp, float** shbuffer, LabImage* original, LabImage* transformed, LabImage* reserved, int cx, int cy, int oW, int oH, int sk, const LocretigainCurve & locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool & lhmasutili, const LocCCmaskCurve & locccmasexpCurve, bool &lcmasexputili, const LocLLmaskCurve & locllmasexpCurve, bool &llmasexputili, const LocHHmaskCurve & lochhmasexpCurve, bool & lhmasexputili, const LocCCmaskCurve & locccmasSHCurve, bool &lcmasSHutili, const LocLLmaskCurve & locllmasSHCurve, bool &llmasSHutili, const LocHHmaskCurve & lochhmasSHCurve, bool & lhmasSHutili, const LocCCmaskCurve & locccmascbCurve, bool &lcmascbutili, const LocLLmaskCurve & locllmascbCurve, bool &llmascbutili, const LocHHmaskCurve & lochhmascbCurve, bool & lhmascbutili, diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 1ba528224..b2f59ef88 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -6591,7 +6591,7 @@ void ImProcFunctions::DeNoise(int call, int del, float * slidL, float * slida, f void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * original, LabImage * transformed, LabImage * reserved, int cx, int cy, int oW, int oH, int sk, - const LocretigainCurve & locRETgainCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool & lhmasutili, + const LocretigainCurve & locRETgainCcurve, const LocretitransCurve & locRETtransCcurve, LUTf & lllocalcurve, bool & locallutili, const LocLHCurve & loclhCurve, const LocHHCurve & lochhCurve, const LocCCmaskCurve & locccmasCurve, bool & lcmasutili, const LocLLmaskCurve & locllmasCurve, bool & llmasutili, const LocHHmaskCurve & lochhmasCurve, bool & lhmasutili, const LocCCmaskCurve & locccmasexpCurve, bool & lcmasexputili, const LocLLmaskCurve & locllmasexpCurve, bool & llmasexputili, const LocHHmaskCurve & lochhmasexpCurve, bool & lhmasexputili, const LocCCmaskCurve & locccmasSHCurve, bool & lcmasSHutili, const LocLLmaskCurve & locllmasSHCurve, bool & llmasSHutili, const LocHHmaskCurve & lochhmasSHCurve, bool & lhmasSHutili, const LocCCmaskCurve & locccmascbCurve, bool & lcmascbutili, const LocLLmaskCurve & locllmascbCurve, bool & llmascbutili, const LocHHmaskCurve & lochhmascbCurve, bool & lhmascbutili, @@ -8882,7 +8882,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o float minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax; bool fftw = lp.ftwreti; //for Retinex Mask are incorporated in MSR - ImProcFunctions::MSRLocal(sp, fftw, 1, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, + ImProcFunctions::MSRLocal(sp, fftw, 1, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, transformed, lp.enaretiMasktmap, lp.enaretiMask); #ifdef _OPENMP @@ -9011,7 +9011,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bool fftw = false; if (params->locallab.spots.at(sp).chrrt > 40.f) { //second step active Retinex Chroma - ImProcFunctions::MSRLocal(sp, fftw, 0, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, + ImProcFunctions::MSRLocal(sp, fftw, 0, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, transformed, lp.enaretiMasktmap, lp.enaretiMask); } @@ -9347,7 +9347,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bool fftw = lp.ftwreti; //for Retinex Mask are incorporated in MSR - ImProcFunctions::MSRLocal(sp, fftw, 1, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, bfwr, bfhr, params->locallab, sk, locRETgainCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, + ImProcFunctions::MSRLocal(sp, fftw, 1, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, bfwr, bfhr, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 0, 4, 1.f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, transformed, lp.enaretiMasktmap, lp.enaretiMask); #ifdef _OPENMP @@ -9485,7 +9485,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o bool fftw = false; if (params->locallab.spots.at(sp).chrrt > 40.f) { //second step active Retinex Chroma - ImProcFunctions::MSRLocal(sp, fftw, 0, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, + ImProcFunctions::MSRLocal(sp, fftw, 0, bufreti, bufmask, buforig, buforigmas, orig, tmpl->L, orig1, Wd, Hd, Wd, Hd, params->locallab, sk, locRETgainCcurve, locRETtransCcurve, 1, 4, 0.8f, minCD, maxCD, mini, maxi, Tmean, Tsigma, Tmin, Tmax, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, llretiMask, transformed, lp.enaretiMasktmap, lp.enaretiMask); } diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index a9648bf44..d54316260 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -850,7 +850,7 @@ void RawImageSource::MSR(float** luminance, float** originalLuminance, float **e } } -void ImProcFunctions::MSRLocal(int sp, bool fftw, int lum, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, +void ImProcFunctions::MSRLocal(int sp, bool fftw, int lum, LabImage * bufreti, LabImage * bufmask, LabImage * buforig, LabImage * buforigmas, float** luminance, float** templ, const float* const *originalLuminance, const int width, const int height, int bfwr, int bfhr, const LocallabParams &loc, const int skip, const LocretigainCurve &locRETgainCcurve, const LocretitransCurve &locRETtransCcurve, const int chrome, const int scall, const float krad, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, const LocCCmaskCurve & locccmasretiCurve, bool &lcmasretiutili, const LocLLmaskCurve & locllmasretiCurve, bool &llmasretiutili, const LocHHmaskCurve & lochhmasretiCurve, bool & lhmasretiutili, int llretiMask, LabImage * transformed, bool retiMasktmap, bool retiMask) { BENCHFUN @@ -1479,6 +1479,47 @@ void ImProcFunctions::MSRLocal(int sp, bool fftw, int lum, LabImage * bufreti, L mean_stddv2(luminance, mean, stddv, W_L, H_L, maxtr, mintr); // printf("mean=%f std=%f delta=%f maxtr=%f mintr=%f\n", mean, stddv, delta, maxtr, mintr); + if (locRETtransCcurve && mean != 0.f && stddv != 0.f) { //if curve + float asig = 0.166666f / stddv; + float bsig = 0.5f - asig * mean; + float amax = 0.333333f / (maxtr - mean - stddv); + float bmax = 1.f - amax * maxtr; + float amin = 0.333333f / (mean - stddv - mintr); + float bmin = -amin * mintr; + + asig *= 500.f; + bsig *= 500.f; + amax *= 500.f; + bmax *= 500.f; + amin *= 500.f; + bmin *= 500.f; + +#ifdef _OPENMP + #pragma omp parallel +#endif + { + float absciss; +#ifdef _OPENMP + #pragma omp for schedule(dynamic,16) +#endif + + for (int i = 0; i < H_L; i++) + for (int j = 0; j < W_L; j++) { //for mintr to maxtr evalate absciss in function of original transmission + if (LIKELY(fabsf(luminance[i][j] - mean) < stddv)) { + absciss = asig * luminance[i][j] + bsig; + } else if (luminance[i][j] >= mean) { + absciss = amax * luminance[i][j] + bmax; + } else { /*if(luminance[i][j] <= mean - stddv)*/ + absciss = amin * luminance[i][j] + bmin; + } + + //TODO : move multiplication by 4.f and subtraction of 1.f inside the curve + luminance[i][j] *= (-1.f + 4.f * locRETtransCcurve[absciss]); //new transmission + + } + } + } + float epsil = 0.1f; mini = mean - vart * stddv; diff --git a/rtengine/procevents.h b/rtengine/procevents.h index a0455717d..16ce4656e 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -779,6 +779,7 @@ enum ProcEventCode { Evlocallabloglin = 749, Evlocallablumonly = 750, Evlocallaboffs = 751, + EvlocallabCTtransCurve = 752, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index e6aaaf137..764b458a8 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2587,6 +2587,7 @@ LocallabParams::LocallabSpot::LocallabSpot() : depth(25), sensih(30), localTgaincurve{(double)FCT_MinMaxCPoints, 0.0, 0.12, 0.35, 0.35, 0.70, 0.50, 0.35, 0.35, 1.00, 0.12, 0.35, 0.35}, + localTtranscurve{(double)FCT_MinMaxCPoints, 0.0, 0.50, 0.35, 0.35, 0.60, 0.75, 0.35, 0.35, 1.00, 0.50, 0.35, 0.35}, inversret(false), equilret(true), loglin(false), @@ -2852,6 +2853,7 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const && depth == other.depth && sensih == other.sensih && localTgaincurve == other.localTgaincurve + && localTtranscurve == other.localTtranscurve && inversret == other.inversret && equilret == other.equilret && loglin == other.loglin @@ -4103,6 +4105,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->locallab.spots.at(i).depth, "Locallab", "Depth_" + std::to_string(i), spot.depth, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensih, "Locallab", "Sensih_" + std::to_string(i), spot.sensih, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).localTgaincurve, "Locallab", "TgainCurve_" + std::to_string(i), spot.localTgaincurve, keyFile); + saveToKeyfile(!pedited || pedited->locallab.spots.at(i).localTtranscurve, "Locallab", "TtransCurve_" + std::to_string(i), spot.localTtranscurve, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).inversret, "Locallab", "Inversret_" + std::to_string(i), spot.inversret, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).equilret, "Locallab", "Equilret_" + std::to_string(i), spot.equilret, keyFile); saveToKeyfile(!pedited || pedited->locallab.spots.at(i).loglin, "Locallab", "Loglin_" + std::to_string(i), spot.loglin, keyFile); @@ -5481,6 +5484,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) assignFromKeyfile(keyFile, "Locallab", "Depth_" + std::to_string(i), pedited, spot.depth, spotEdited.depth); assignFromKeyfile(keyFile, "Locallab", "Sensih_" + std::to_string(i), pedited, spot.sensih, spotEdited.sensih); assignFromKeyfile(keyFile, "Locallab", "TgainCurve_" + std::to_string(i), pedited, spot.localTgaincurve, spotEdited.localTgaincurve); + assignFromKeyfile(keyFile, "Locallab", "TtransCurve_" + std::to_string(i), pedited, spot.localTtranscurve, spotEdited.localTtranscurve); assignFromKeyfile(keyFile, "Locallab", "Inversret_" + std::to_string(i), pedited, spot.inversret, spotEdited.inversret); assignFromKeyfile(keyFile, "Locallab", "Equilret_" + std::to_string(i), pedited, spot.equilret, spotEdited.equilret); assignFromKeyfile(keyFile, "Locallab", "Loglin_" + std::to_string(i), pedited, spot.loglin, spotEdited.loglin); diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 84f937566..7679a9cf5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1136,6 +1136,7 @@ struct LocallabParams { int depth; int sensih; std::vector localTgaincurve; + std::vector localTtranscurve; bool inversret; bool equilret; bool loglin; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 85badd440..0ca159986 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -778,7 +778,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // Evlocallabdepth LUMINANCECURVE, // Evlocallabloglin LUMINANCECURVE, // Evlocallablumonly - LUMINANCECURVE // Evlocallaboffs + LUMINANCECURVE, // Evlocallaboffs + LUMINANCECURVE //EvlocallabCTtransCurve }; diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index eecbb0c5c..4f6d97d59 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -1092,6 +1092,7 @@ private: LUTi centerx(500, -10000); LUTi centery(500, -10000); LocretigainCurve locRETgainCurve; + LocretitransCurve locRETtransCurve; LocLHCurve loclhCurve; LocHHCurve lochhCurve; LocCCmaskCurve locccmasCurve; @@ -1165,6 +1166,7 @@ private: bool lcmasutili = false; bool lhmasutili = false; locRETgainCurve.Set(params.locallab.spots.at(sp).localTgaincurve); + locRETtransCurve.Set(params.locallab.spots.at(sp).localTtranscurve); loclhCurve.Set(params.locallab.spots.at(sp).LHcurve, LHutili); lochhCurve.Set(params.locallab.spots.at(sp).HHcurve, HHutili); locccmasCurve.Set(params.locallab.spots.at(sp).CCmaskcurve, lcmasutili); @@ -1217,7 +1219,7 @@ private: 1); // No Locallab mask is shown in exported picture - ipf.Lab_Local(2, sp, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, + ipf.Lab_Local(2, sp, (float**)shbuffer, labView, labView, reservView, 0, 0, fw, fh, 1, locRETgainCurve, locRETtransCurve, lllocalcurve, locallutili, loclhCurve, lochhCurve, locccmasCurve, lcmasutili, locllmasCurve, llmasutili, lochhmasCurve, lhmasutili, locccmasexpCurve, lcmasexputili, locllmasexpCurve, llmasexputili, lochhmasexpCurve, lhmasexputili, locccmasSHCurve, lcmasSHutili, locllmasSHCurve, llmasSHutili, lochhmasSHCurve, lhmasSHutili, locccmascbCurve, lcmascbutili, locllmascbCurve, llmascbutili, lochhmascbCurve, lhmascbutili, locccmasretiCurve, lcmasretiutili, locllmasretiCurve, llmasretiutili, lochhmasretiCurve, lhmasretiutili, diff --git a/rtgui/locallab.cc b/rtgui/locallab.cc index 822235ec6..da9c34c6e 100644 --- a/rtgui/locallab.cc +++ b/rtgui/locallab.cc @@ -167,6 +167,7 @@ Locallab::Locallab(): //TM masktmCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), // Retinex + LocalcurveEditortransT(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_TRANSMISSIONMAP"))), LocalcurveEditorgainT(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_TRANSMISSIONGAIN"))), maskretiCurveEditorG(new CurveEditorGroup(options.lastlocalCurvesDir, M("TP_LOCALLAB_MASK"))), //Local contrast @@ -1363,6 +1364,16 @@ Locallab::Locallab(): softradiusret->set_tooltip_text(M("TP_LOCALLAB_GUIDFILTER_TOOLTIP")); } + LocalcurveEditortransT->setCurveListener(this); + cTtransshape = static_cast(LocalcurveEditortransT->addCurve(CT_Flat, "", nullptr, false, false)); + cTtransshape->setIdentityValue(0.); + cTtransshape->setResetCurve(FlatCurveType(defSpot.localTtranscurve.at(0)), defSpot.localTtranscurve); + + if (showtooltip) { + cTtransshape->setTooltip(M("TP_RETINEX_TRANSMISSION_TOOLTIP")); + } + LocalcurveEditortransT->curveListComplete(); + LocalcurveEditorgainT->setCurveListener(this); cTgainshape = static_cast(LocalcurveEditorgainT->addCurve(CT_Flat, "", nullptr, false, false)); @@ -1490,6 +1501,7 @@ Locallab::Locallab(): retiBox->pack_start(*darkness); retiBox->pack_start(*lightnessreti); // retiBox->pack_start(*softradiusret); + retiBox->pack_start(*LocalcurveEditortransT, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor retiBox->pack_start(*LocalcurveEditorgainT, Gtk::PACK_SHRINK, 4); // Padding is mandatory to correct behavior of curve editor retiBox->pack_start(*expmaskreti); retiBox->pack_start(*inversret); @@ -2049,6 +2061,7 @@ Locallab::~Locallab() delete maskexpCurveEditorG; delete maskSHCurveEditorG; delete curveEditorGG; + delete LocalcurveEditortransT; delete LocalcurveEditorgainT; delete LocalcurveEditorwav; delete masktmCurveEditorG; @@ -3067,6 +3080,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pp->locallab.spots.at(pp->locallab.selspot).depth = depth->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).sensih = sensih->getIntValue(); pp->locallab.spots.at(pp->locallab.selspot).localTgaincurve = cTgainshape->getCurve(); + pp->locallab.spots.at(pp->locallab.selspot).localTtranscurve = cTtransshape->getCurve(); pp->locallab.spots.at(pp->locallab.selspot).inversret = inversret->get_active(); pp->locallab.spots.at(pp->locallab.selspot).softradiusret = softradiusret->getValue(); pp->locallab.spots.at(pp->locallab.selspot).equilret = equilret->get_active(); @@ -3340,6 +3354,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pe->locallab.spots.at(pp->locallab.selspot).depth = pe->locallab.spots.at(pp->locallab.selspot).depth || depth->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).sensih = pe->locallab.spots.at(pp->locallab.selspot).sensih || sensih->getEditedState(); pe->locallab.spots.at(pp->locallab.selspot).localTgaincurve = pe->locallab.spots.at(pp->locallab.selspot).localTgaincurve || !cTgainshape->isUnChanged(); + pe->locallab.spots.at(pp->locallab.selspot).localTtranscurve = pe->locallab.spots.at(pp->locallab.selspot).localTtranscurve || !cTtransshape->isUnChanged(); pe->locallab.spots.at(pp->locallab.selspot).inversret = pe->locallab.spots.at(pp->locallab.selspot).inversret || !inversret->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).equilret = pe->locallab.spots.at(pp->locallab.selspot).equilret || !equilret->get_inconsistent(); pe->locallab.spots.at(pp->locallab.selspot).loglin = pe->locallab.spots.at(pp->locallab.selspot).loglin || !loglin->get_inconsistent(); @@ -3611,6 +3626,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited) pedited->locallab.spots.at(pp->locallab.selspot).depth = pedited->locallab.spots.at(pp->locallab.selspot).depth || depth->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).sensih = pedited->locallab.spots.at(pp->locallab.selspot).sensih || sensih->getEditedState(); pedited->locallab.spots.at(pp->locallab.selspot).localTgaincurve = pedited->locallab.spots.at(pp->locallab.selspot).localTgaincurve || !cTgainshape->isUnChanged(); + pedited->locallab.spots.at(pp->locallab.selspot).localTtranscurve = pedited->locallab.spots.at(pp->locallab.selspot).localTtranscurve || !cTtransshape->isUnChanged(); pedited->locallab.spots.at(pp->locallab.selspot).inversret = pedited->locallab.spots.at(pp->locallab.selspot).inversret || !inversret->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).equilret = pedited->locallab.spots.at(pp->locallab.selspot).equilret || !equilret->get_inconsistent(); pedited->locallab.spots.at(pp->locallab.selspot).loglin = pedited->locallab.spots.at(pp->locallab.selspot).loglin || !loglin->get_inconsistent(); @@ -3977,6 +3993,12 @@ void Locallab::curveChanged(CurveEditor* ce) } } + if (ce == cTtransshape) { + if (listener) { + listener->panelChanged(EvlocallabCTtransCurve, M("HISTORY_CUSTOMCURVE")); + } + } + if (ce == CCmaskretishape) { if (listener) { listener->panelChanged(EvlocallabCCmaskretishape, M("HISTORY_CUSTOMCURVE")); @@ -6436,9 +6458,11 @@ void Locallab::adjusterChanged(Adjuster * a, double newval) if (a == scalereti) { if (scalereti->getValue() == 1) { LocalcurveEditorgainT->hide(); + LocalcurveEditortransT->hide(); retinexMethod->hide(); } else { LocalcurveEditorgainT->show(); + LocalcurveEditortransT->show(); retinexMethod->show(); } @@ -7281,9 +7305,11 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con if (pp->locallab.spots.at(index).scalereti == 1) { LocalcurveEditorgainT->hide(); + LocalcurveEditortransT->hide(); retinexMethod->hide(); } else { LocalcurveEditorgainT->show(); + LocalcurveEditortransT->show(); retinexMethod->show(); } @@ -7494,6 +7520,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con depth->setValue(pp->locallab.spots.at(index).depth); sensih->setValue(pp->locallab.spots.at(index).sensih); cTgainshape->setCurve(pp->locallab.spots.at(index).localTgaincurve); + cTtransshape->setCurve(pp->locallab.spots.at(index).localTtranscurve); inversret->set_active(pp->locallab.spots.at(index).inversret); equilret->set_active(pp->locallab.spots.at(index).equilret); loglin->set_active(pp->locallab.spots.at(index).loglin); @@ -7817,6 +7844,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con depth->setEditedState(spotState->depth ? Edited : UnEdited); sensih->setEditedState(spotState->sensih ? Edited : UnEdited); cTgainshape->setUnChanged(!spotState->localTgaincurve); + cTtransshape->setUnChanged(!spotState->localTtranscurve); inversret->set_inconsistent(multiImage && !spotState->inversret); equilret->set_inconsistent(multiImage && !spotState->equilret); loglin->set_inconsistent(multiImage && !spotState->loglin); diff --git a/rtgui/locallab.h b/rtgui/locallab.h index bd4641923..a5d83306f 100644 --- a/rtgui/locallab.h +++ b/rtgui/locallab.h @@ -107,8 +107,10 @@ private: FlatCurveEditor* LLmasktmshape; FlatCurveEditor* HHmasktmshape; // Retinex + CurveEditorGroup* const LocalcurveEditortransT; CurveEditorGroup* const LocalcurveEditorgainT; CurveEditorGroup* const maskretiCurveEditorG; + FlatCurveEditor* cTtransshape; FlatCurveEditor* cTgainshape; FlatCurveEditor* CCmaskretishape; FlatCurveEditor* LLmaskretishape; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 5fab4eff0..fa9104569 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -1128,6 +1128,7 @@ void ParamsEdited::initFrom(const std::vector& locallab.spots.at(j).depth = locallab.spots.at(j).depth && pSpot.depth == otherSpot.depth; locallab.spots.at(j).sensih = locallab.spots.at(j).sensih && pSpot.sensih == otherSpot.sensih; locallab.spots.at(j).localTgaincurve = locallab.spots.at(j).localTgaincurve && pSpot.localTgaincurve == otherSpot.localTgaincurve; + locallab.spots.at(j).localTtranscurve = locallab.spots.at(j).localTtranscurve && pSpot.localTtranscurve == otherSpot.localTtranscurve; locallab.spots.at(j).inversret = locallab.spots.at(j).inversret && pSpot.inversret == otherSpot.inversret; locallab.spots.at(j).equilret = locallab.spots.at(j).equilret && pSpot.equilret == otherSpot.equilret; locallab.spots.at(j).loglin = locallab.spots.at(j).loglin && pSpot.loglin == otherSpot.loglin; @@ -3363,6 +3364,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.locallab.spots.at(i).localTgaincurve = mods.locallab.spots.at(i).localTgaincurve; } + if (locallab.spots.at(i).localTtranscurve) { + toEdit.locallab.spots.at(i).localTtranscurve = mods.locallab.spots.at(i).localTtranscurve; + } + if (locallab.spots.at(i).inversret) { toEdit.locallab.spots.at(i).inversret = mods.locallab.spots.at(i).inversret; } @@ -4811,6 +4816,7 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) : depth(v), sensih(v), localTgaincurve(v), + localTtranscurve(v), inversret(v), equilret(v), loglin(v), @@ -5073,6 +5079,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v) depth = v; sensih = v; localTgaincurve = v; + localTtranscurve = v; inversret = v; equilret = v; loglin = v; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 16d73bcf4..db47226ca 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -546,6 +546,7 @@ public: bool depth; bool sensih; bool localTgaincurve; + bool localTtranscurve; bool inversret; bool equilret; bool loglin;