From 9b62f92095d1b4bb574f939625296d1c350a34ff Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 23 Aug 2016 19:35:15 +0200 Subject: [PATCH 1/4] About 7x speedup for Automatic Saturation Protection in Colourtoning --- rtengine/color.h | 13 +++++++++++ rtengine/improcfun.cc | 54 +++++++++++-------------------------------- 2 files changed, 27 insertions(+), 40 deletions(-) diff --git a/rtengine/color.h b/rtengine/color.h index bf42140c5..1ae721e5a 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -231,6 +231,19 @@ public: */ static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); + static inline float rgb2s(float r, float g, float b) // fast version if only saturation is needed + { + float var_Min = min(r, g, b); + float var_Max = max(r, g, b); + float del_Max = var_Max - var_Min; + + if (del_Max < 0.00001f) { + return 0.f; + } else { + return del_Max / var_Max; + } + } + static inline bool rgb2hsvdcp(float r, float g, float b, float &h, float &s, float &v) { diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 67103d521..f70341334 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -40,7 +40,7 @@ #include "improccoordinator.h" #include "clutstore.h" #include "ciecam02.h" -//#define BENCHMARK +#define BENCHMARK #include "StopWatch.h" #include "../rtgui/ppversion.h" #include "../rtgui/guiutils.h" @@ -2861,54 +2861,28 @@ void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) { -// MyTime t1e,t2e; -// t1e.set(); + BENCHFUN int tHh = working->height; int tWw = working->width; - float moy = 0.f; - float eqt = 0.f; - #pragma omp parallel - { - float mo = 0.f; + double moy = 0.0; + double sqrs = 0.0; #ifndef _DEBUG - #pragma omp for reduction(+:moy) + #pragma omp parallel for reduction(+:moy,sqrs) schedule(dynamic,16) #endif - for (int i = 0; i < tHh; i++) { - for (int j = 0; j < tWw; j++) { - float r = CLIP(working->r(i, j)); - float g = CLIP(working->g(i, j)); - float b = CLIP(working->b(i, j)); - float h, s, v; - Color::rgb2hsv(r, g, b, h, s, v); - moy += s; - } - } - - mo = moy / (tHh * tWw); - moyS = mo; -#ifndef _DEBUG - #pragma omp for reduction(+:eqt) -#endif - - for (int i = 0; i < tHh; i++) { - for (int j = 0; j < tWw; j++) { - float r = CLIP(working->r(i, j)); - float g = CLIP(working->g(i, j)); - float b = CLIP(working->b(i, j)); - float h, s, v; - Color::rgb2hsv(r, g, b, h, s, v); - eqt += SQR(s - mo); - } + for (int i = 0; i < tHh; i++) { + for (int j = 0; j < tWw; j++) { + float s = Color::rgb2s(CLIP(working->r(i, j)), CLIP(working->g(i, j)), CLIP(working->b(i, j))); + moy += s; + sqrs += SQR(s); } } - eqt = eqt / (tHh * tWw); - eqty = (sqrt(eqt)); - - // t2e.set(); - // printf("Moyeqt:%d\n", t2e.etime(t1e)); + double mo = moy / (tHh * tWw); + moyS = mo; + double eqt = (sqrs - 2.0 * mo * moy + tHh * tWw * SQR(mo)) / (tHh * tWw); + eqty = sqrt(eqt); } static inline void From 7a4cf9aba827be535b3860b64dad658f8baccf6d Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 23 Aug 2016 19:59:49 +0200 Subject: [PATCH 2/4] Colourtoning: Always calculate saturation for 'Automatic Saturation Protection' from full image --- rtengine/dcrop.cc | 23 +---------------------- rtengine/improccoordinator.cc | 14 +++++++------- rtengine/improccoordinator.h | 2 ++ 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index 577a3f4a6..93aca0f6d 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -749,27 +749,6 @@ void Crop::update (int todo) baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256, parent->imgsrc->getGamma()); }*/ - float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; - float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); - - if(params.colorToning.enabled && params.colorToning.autosat) { //for colortoning evaluation of saturation settings - float moyS = 0.f; - float eqty = 0.f; - parent->ipf.moyeqt (baseCrop, moyS, eqty);//return image : mean saturation and standard dev of saturation - //printf("moy=%f ET=%f\n", moyS,eqty); - float satp = ((moyS + 1.5f * eqty) - 0.3f) / 0.7f; //1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale - - if(satp >= 0.92f) { - satp = 0.92f; //avoid values too high (out of gamut) - } - - if(satp <= 0.15f) { - satp = 0.15f; //avoid too low values - } - - satLimit = 100.f * satp; - satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation - } if (todo & M_RGBCURVE) { double rrm, ggm, bbm; @@ -777,7 +756,7 @@ void Crop::update (int todo) DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, parent->currWB, as); parent->ipf.rgbProc (baseCrop, laboCrop, this, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, - params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, satLimit , satLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve, parent->cl2Toningcurve, + params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, parent->colourToningSatLimit , parent->colourToningSatLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve, parent->cl2Toningcurve, parent->customToneCurve1, parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW, rrm, ggm, bbm, parent->bwAutoR, parent->bwAutoG, parent->bwAutoB, dcpProf, as); } diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index a0dd47960..a6354bd56 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -473,8 +473,8 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW, scale == 1 ? 1 : 1); } - float satLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; - float satLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); + colourToningSatLimit = float(params.colorToning.satProtectionThreshold) / 100.f * 0.7f + 0.3f; + colourToningSatLimitOpacity = 1.f - (float(params.colorToning.saturatedOpacity) / 100.f); int satTH = 80; int satPR = 30; @@ -497,10 +497,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) //satTH=(int) 100.f*satp; //satPR=(int) 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation - satLimit = 100.f * satp; + colourToningSatLimit = 100.f * satp; satTH = (int) 100.f * satp; - satLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation + colourToningSatLimitOpacity = 100.f * (moyS - 0.85f * eqty); //-0.85 sigma==>20% pixels with low saturation satPR = (int) 100.f * (moyS - 0.85f * eqty); } @@ -539,7 +539,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB, as); ipf.rgbProc (oprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, - rCurve, gCurve, bCurve, satLimit , satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf, as); + rCurve, gCurve, bCurve, colourToningSatLimit , colourToningSatLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, beforeToneCurveBW, afterToneCurveBW, rrm, ggm, bbm, bwAutoR, bwAutoG, bwAutoB, params.toneCurve.expcomp, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, dcpProf, as); if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) { if (settings->verbose) { @@ -551,10 +551,10 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) if(params.colorToning.autosat && actListener) { if (settings->verbose) { - printf("ImProcCoordinator / Auto CT: indi=%d satH=%d satPR=%d\n", indi, (int)satLimit , (int) satLimitOpacity); + printf("ImProcCoordinator / Auto CT: indi=%d satH=%d satPR=%d\n", indi, (int)colourToningSatLimit , (int) colourToningSatLimitOpacity); } - actListener->autoColorTonChanged(indi, (int) satLimit, (int)satLimitOpacity);//change sliders autosat + actListener->autoColorTonChanged(indi, (int) colourToningSatLimit, (int)colourToningSatLimitOpacity);//change sliders autosat } // correct GUI black and white with value diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h index 4f1a6a691..5cc03cb72 100644 --- a/rtengine/improccoordinator.h +++ b/rtengine/improccoordinator.h @@ -197,6 +197,8 @@ protected: bool wavcontlutili; void startProcessing (); void process (); + float colourToningSatLimit; + float colourToningSatLimitOpacity; public: From 281e3979d5a68ba0420dce49aa9572b52d892abd Mon Sep 17 00:00:00 2001 From: heckflosse Date: Tue, 23 Aug 2016 21:32:30 +0200 Subject: [PATCH 3/4] ImProcFunctions::moyeqt, simplified calculation --- rtengine/improcfun.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index f70341334..34e2eeb34 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -2867,7 +2867,8 @@ void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) int tWw = working->width; double moy = 0.0; double sqrs = 0.0; -#ifndef _DEBUG + +#ifdef _OPENMP #pragma omp parallel for reduction(+:moy,sqrs) schedule(dynamic,16) #endif @@ -2879,10 +2880,10 @@ void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) } } - double mo = moy / (tHh * tWw); - moyS = mo; - double eqt = (sqrs - 2.0 * mo * moy + tHh * tWw * SQR(mo)) / (tHh * tWw); - eqty = sqrt(eqt); + moy /= (tHh * tWw); + sqrs /= (tHh * tWw); + eqty = sqrt(sqrs - SQR(moy)); + moyS = moy; } static inline void From 39a57cbb3b6ea1b4c2c0b78daee333ba2addc38f Mon Sep 17 00:00:00 2001 From: heckflosse Date: Wed, 24 Aug 2016 21:28:01 +0200 Subject: [PATCH 4/4] Disabled StopWatch --- rtengine/improcfun.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 34e2eeb34..9bbdb022f 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -40,7 +40,7 @@ #include "improccoordinator.h" #include "clutstore.h" #include "ciecam02.h" -#define BENCHMARK +//#define BENCHMARK #include "StopWatch.h" #include "../rtgui/ppversion.h" #include "../rtgui/guiutils.h"