diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 1ed3e4ed0..0153f819c 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -254,7 +254,7 @@ public: bool showSharpMask = false); void chromiLuminanceCurve(PipetteBuffer *pipetteBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve, LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histLurve); void vibrance(LabImage* lab, const procparams::VibranceParams &vibranceParams, bool highlight, const Glib::ustring &workingProfile); //Jacques' vibrance - void softprocess(const LabImage* bufcolorig, array2D &buflight, /* float ** bufchro, float ** buf_a, float ** buf_b, */ float rad, int bfh, int bfw, int sk, bool multiThread); + void softprocess(const LabImage* bufcolorig, array2D &buflight, /* float ** bufchro, float ** buf_a, float ** buf_b, */ float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread); void softproc(const LabImage* bufcolorig, const LabImage* bufcolfin, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread); // void colorCurve (LabImage* lold, LabImage* lnew); void sharpening(LabImage* lab, const procparams::SharpeningParams &sharpenParam, bool showMask = false); diff --git a/rtengine/iplocallab.cc b/rtengine/iplocallab.cc index 6fc5c5e1e..f9db9cce0 100644 --- a/rtengine/iplocallab.cc +++ b/rtengine/iplocallab.cc @@ -1150,7 +1150,7 @@ void ImProcFunctions::softproc(const LabImage* bufcolorig, const LabImage* bufco } -void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &buflight, float rad, int bfh, int bfw, int sk, bool multiThread) +void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &buflight, float rad, int bfh, int bfw, double epsilmax, double epsilmin, float thres, int sk, bool multiThread) { float minlig = buflight[0][0]; @@ -1176,8 +1176,13 @@ void ImProcFunctions::softprocess(const LabImage* bufcolorig, array2D &bu guidsoft[ir][jr] = bufcolorig->L[ir][jr] / 32768.f; } } + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * rad + bepsil; + float blur = 1.f / sk * (thres + 0.8f * rad); + guidedFilter(guidsoft, buflight, buflight, blur, epsil, multiThread, 4); - guidedFilter(guidsoft, buflight, buflight, rad * 5.f / sk, 0.001, multiThread, 4); + // guidedFilter(guidsoft, buflight, buflight, rad * 100.f / sk, 0.001, multiThread, 4); #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) @@ -5962,8 +5967,9 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o } } - if (lp.softradiusret > 0.f) { - // softprocess(bufreti, buflight, lp.softradiusret, Hd, Wd, sk, multiThread); + if (lp.softradiusret > 0.f && lp.scalereti != 1) { + // softprocess(bufreti, buflight, lp.softradiusret, Hd, Wd, sk, 0.01, 0.001, 0.0001f, multiThread); + //softproc(bufreti, tmpl, lp.softradiusret, bfh, bfw, 0.0001, 0.00001, 0.0001f, sk, multiThread); } transit_shapedetect_retinex(4, bufreti, bufmask, buforigmas, buflight, bufchro, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk); @@ -6329,6 +6335,7 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o if (lp.softradiusexp > 0.f) { softproc(bufexporig.get(), bufexpfin.get(), lp.softradiusexp, bfh, bfw, 0.0001, 0.00001, 0.0001f, sk, multiThread); + // softprocess(bufexporig.get(), buflight, lp.softradiusexp, bfh, bfw, sk, multiThread); } #ifdef _OPENMP #pragma omp parallel for schedule(dynamic,16) diff --git a/rtengine/ipretinex.cc b/rtengine/ipretinex.cc index d23c4a351..1e283eed4 100644 --- a/rtengine/ipretinex.cc +++ b/rtengine/ipretinex.cc @@ -944,15 +944,17 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b float *buffer = new float[W_L * H_L]; for (int scale = scal - 1; scale >= 0; scale--) { - printf("retscale=%f scale=%i \n", RetinexScales[scale], scale); + // printf("retscale=%f scale=%i \n", RetinexScales[scale], scale); #ifdef _OPENMP #pragma omp parallel #endif { - if (scale == scal - 1) { + if (scale == scal - 1) + { gaussianBlur(src, out, W_L, H_L, RetinexScales[scale], buffer); - } else { // reuse result of last iteration + } else // reuse result of last iteration + { // out was modified in last iteration => restore it gaussianBlur(out, out, W_L, H_L, sqrtf(SQR(RetinexScales[scale]) - SQR(RetinexScales[scale + 1])), buffer); @@ -1163,6 +1165,8 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } } + + #ifdef __SSE2__ vfloat pondv = F2V(pond); vfloat limMinv = F2V(ilimD); @@ -1202,6 +1206,62 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } } + if (scal != 1) { + float mintran = luminance[0][0]; + float maxtran = mintran; + +#ifdef _OPENMP + #pragma omp parallel for reduction(min:mintran) reduction(max:maxtran) schedule(dynamic,16) +#endif + + for (int ir = 0; ir < H_L; ir++) { + for (int jr = 0; jr < W_L; jr++) { + mintran = rtengine::min(luminance[ir][jr], mintran); + maxtran = rtengine::max(luminance[ir][jr], maxtran); + } + } + + float deltatran = maxtran - mintran; + +// printf("minT=%f maxT=%f delt=%f \n", mintran, maxtran, deltatran); +//here add GuidFilter for transmission map + array2D ble(W_L, H_L); + array2D guid(W_L, H_L); +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i ++) + for (int j = 0; j < W_L; j++) { + guid[i][j] = src[i][j] / 32768.f; + ble[i][j] = (luminance[i][j] + mintran) / deltatran; + } + + double epsilmax = 1e-5; + double epsilmin = 1e-6; + float radi = loc.spots.at(sp).softradiusret; + + if (loc.spots.at(sp).softradiusret > 0.f) { + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * radi + bepsil; + + float blur = 10.f / skip * (0.00001f + 0.8f * radi); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); + + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i ++) + for (int j = 0; j < W_L; j++) { + luminance[i][j] = ble[i][j] * deltatran + mintran; + } + } + + if (scal == 1) { //use only local contrast float kval = 1.f; #ifdef _OPENMP @@ -1211,6 +1271,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b for (int y = 0; y < H_L; ++y) { for (int x = 0; x < W_L; ++x) { float threslow = threslum * 163.f; + if (src[y][x] < threslow) { kval = src[y][x] / threslow; } @@ -1269,44 +1330,62 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b } } -//here add GuidFilter for transmission map - array2D ble(W_L, H_L); - array2D guid(W_L, H_L); -#ifdef _OPENMP - #pragma omp parallel for -#endif - - for (int i = 0; i < H_L; i ++) - for (int j = 0; j < W_L; j++) { - guid[i][j] = src[i][j] / 32768.f; - ble[i][j] = luminance[i][j] / 32768.f; - } - - double epsilon = 4. * 1e-5 / (double) scal; - float radi = loc.spots.at(sp).softradiusret > 0.f; - if (scal == 1) { - epsilon = 1e-6; - radi /= 10.f; - } - - if (loc.spots.at(sp).softradiusret > 0.f) { - guidedFilter(guid, ble, ble, radi * 10.f / skip, epsilon, multiThread, 4); - } + float mintran = luminance[0][0]; + float maxtran = mintran; #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for reduction(min:mintran) reduction(max:maxtran) schedule(dynamic,16) #endif - for (int i = 0; i < H_L; i ++) - for (int j = 0; j < W_L; j++) { - luminance[i][j] = ble[i][j] * 32768.f; + for (int ir = 0; ir < H_L; ir++) { + for (int jr = 0; jr < W_L; jr++) { + mintran = rtengine::min(luminance[ir][jr], mintran); + maxtran = rtengine::max(luminance[ir][jr], maxtran); + } } + float deltatran = maxtran - mintran; + array2D ble(W_L, H_L); + array2D guid(W_L, H_L); +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i ++) + for (int j = 0; j < W_L; j++) { + guid[i][j] = src[i][j] / 32768.f; + ble[i][j] = (luminance[i][j] + mintran) / deltatran; + } + + double epsilmax = 1e-3; + double epsilmin = 1e-4; + float radi = loc.spots.at(sp).softradiusret; + + if (loc.spots.at(sp).softradiusret > 0.f) { + double aepsil = (epsilmax - epsilmin) / 90.f; + double bepsil = epsilmax - 100.f * aepsil; + double epsil = aepsil * radi + bepsil; + + float blur = 10.f / skip * (0.001f + 0.1f * radi); + rtengine::guidedFilter(guid, ble, ble, blur, epsil, multiThread, 4); + + } + +#ifdef _OPENMP + #pragma omp parallel for +#endif + + for (int i = 0; i < H_L; i ++) + for (int j = 0; j < W_L; j++) { + luminance[i][j] = ble[i][j] * deltatran + mintran; + } + } + delete [] buffer; delete [] outBuffer; outBuffer = nullptr; - delete [] srcBuffer; +// delete [] srcBuffer; float str = strength * (chrome == 0 ? 1.f : chrT); if (scal != 1) { @@ -1423,6 +1502,8 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b minCD = minCD < cdmin ? minCD : cdmin; } } + + } else { #ifdef _OPENMP #pragma omp for schedule(dynamic,16) @@ -1430,7 +1511,7 @@ void ImProcFunctions::MSRLocal(int sp, int lum, LabImage * bufreti, LabImage * b for (int i = 0; i < H_L; i ++) for (int j = 0; j < W_L; j++) { - luminance[i][j] = luminance[i][j] * str + (1.f - str) * originalLuminance[i][j]; + luminance[i][j] = CLIPLOC(luminance[i][j]) * str + (1.f - str) * originalLuminance[i][j]; }